diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-02-02 20:08:49 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-02-02 20:08:49 +0000 |
| commit | 1d3b98e5f5311479cd87f20e3656b0133bff73bd (patch) | |
| tree | 95eea2fcac18f236b31053e4d1493aa644760df0 /src | |
| parent | update to trunk (diff) | |
| parent | Translations. Arabic translation update. (diff) | |
| download | inkscape-1d3b98e5f5311479cd87f20e3656b0133bff73bd.tar.gz inkscape-1d3b98e5f5311479cd87f20e3656b0133bff73bd.zip | |
update to trunk
(bzr r13645.1.4)
Diffstat (limited to 'src')
339 files changed, 7239 insertions, 5235 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1455b762e..617e9dce1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -187,7 +187,6 @@ set(inkscape_SRC console-output-undo-observer.cpp context-fns.cpp desktop-events.cpp - desktop-handles.cpp desktop-style.cpp desktop.cpp device-manager.cpp @@ -299,7 +298,6 @@ set(inkscape_SRC context-fns.h decimal-round.h desktop-events.h - desktop-handles.h desktop-style.h desktop.h device-manager.h @@ -336,7 +334,6 @@ set(inkscape_SRC icon-size.h id-clash.h # ige-mac-menu.h - inkscape-private.h inkscape-version.h inkscape.h interface.h @@ -365,6 +362,7 @@ set(inkscape_SRC number-opt-number.h object-hierarchy.h object-snapper.h + object-test.h path-chemistry.h path-prefix.h persp3d-reference.h @@ -517,10 +515,19 @@ set(inkscape_SRC # make executable for INKSCAPE add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC}) +if(UNIX) +# message after building. +add_custom_command( + TARGET inkscape + POST_BUILD MAIN_DEPENDENCY inkscape + COMMAND ${CMAKE_COMMAND} -E echo 'now run: \"make install\" to copy runtime files & scripts to ${CMAKE_INSTALL_PREFIX}' +) +endif() + add_dependencies(inkscape inkscape_version) target_link_libraries(inkscape - # order from automake + # order from automake #sp_LIB nrtype_LIB diff --git a/src/Makefile_insert b/src/Makefile_insert index 2fff44cb8..b07541109 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -29,7 +29,6 @@ ink_common_sources += \ decimal-round.h \ desktop.cpp desktop.h \ desktop-events.cpp desktop-events.h \ - desktop-handles.cpp desktop-handles.h \ desktop-style.cpp desktop-style.h \ device-manager.cpp device-manager.h \ dir-util.cpp dir-util.h \ @@ -63,7 +62,7 @@ ink_common_sources += \ helper/pixbuf-ops.h \ icon-size.h \ id-clash.cpp id-clash.h \ - inkscape.cpp inkscape.h inkscape-private.h \ + inkscape.cpp inkscape.h \ isinf.h \ knot.cpp knot.h \ knot-enums.h \ @@ -247,6 +246,7 @@ CXXTEST_TESTSUITES += \ $(srcdir)/extract-uri-test.h \ $(srcdir)/marker-test.h \ $(srcdir)/mod360-test.h \ + $(srcdir)/object-test.h \ $(srcdir)/preferences-test.h \ $(srcdir)/round-test.h \ $(srcdir)/sp-gradient-test.h \ diff --git a/src/attribute-rel-css.cpp b/src/attribute-rel-css.cpp index 89678edb5..b904cd5f4 100644 --- a/src/attribute-rel-css.cpp +++ b/src/attribute-rel-css.cpp @@ -60,6 +60,7 @@ bool SPAttributeRelCSS::findIfValid(Glib::ustring property, Glib::ustring elemen || property.substr(0,4) == "rdf:" || property.substr(0,3) == "cc:" || property.substr(0,4) == "ns1:" // JessyInk + || property.substr(0,4) == "osb:" // Open Swatch Book || (SPAttributeRelCSS::instance->propertiesOfElements[temp].find(property) != SPAttributeRelCSS::instance->propertiesOfElements[temp].end()) ) { return true; diff --git a/src/attribute-rel-svg.cpp b/src/attribute-rel-svg.cpp index 49c97ae64..0064f4c62 100644 --- a/src/attribute-rel-svg.cpp +++ b/src/attribute-rel-svg.cpp @@ -56,6 +56,7 @@ bool SPAttributeRelSVG::findIfValid(Glib::ustring attribute, Glib::ustring eleme || attribute.substr(0,4) == "rdf:" || attribute.substr(0,3) == "cc:" || attribute.substr(0,4) == "ns1:" // JessyInk + || attribute.substr(0,4) == "osb:" // Open Swatch Book || (SPAttributeRelSVG::instance->attributesOfElements[temp].find(attribute) != SPAttributeRelSVG::instance->attributesOfElements[temp].end()) ) { return true; diff --git a/src/attributes.cpp b/src/attributes.cpp index d142d1a06..0b18b80cf 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -115,7 +115,7 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_SNAP_BBOX_CORNER, "inkscape:bbox-nodes"}, {SP_ATTR_INKSCAPE_SNAP_PAGE_BORDER, "inkscape:snap-page"}, {SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"}, - {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, + {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, // This setting sets the Display units, *not* the units used in SVG {SP_ATTR_UNITS, "units"}, {SP_ATTR_INKSCAPE_CONNECTOR_SPACING, "inkscape:connector-spacing"}, /* SPColorProfile */ @@ -195,6 +195,8 @@ static SPStyleProp const props[] = { {SP_ATTR_DX, "dx"}, {SP_ATTR_DY, "dy"}, {SP_ATTR_ROTATE, "rotate"}, + {SP_ATTR_TEXTLENGTH, "textLength"}, + {SP_ATTR_LENGTHADJUST, "lengthAdjust"}, {SP_ATTR_SODIPODI_ROLE, "sodipodi:role"}, /* SPText */ {SP_ATTR_SODIPODI_LINESPACING, "sodipodi:linespacing"}, @@ -289,6 +291,7 @@ static SPStyleProp const props[] = { {SP_ATTR_FY, "fy"}, /* SPMeshPatch */ {SP_ATTR_TENSOR, "tensor"}, + {SP_ATTR_SMOOTH, "smooth"}, /* SPPattern */ {SP_ATTR_PATTERNUNITS, "patternUnits"}, {SP_ATTR_PATTERNCONTENTUNITS, "patternContentUnits"}, @@ -436,6 +439,11 @@ static SPStyleProp const props[] = { {SP_PROP_KERNING, "kerning"}, {SP_PROP_TEXT_ANCHOR, "text-anchor"}, {SP_PROP_WHITE_SPACE, "white-space"}, + /* SVG 2 Text Wrapping */ + {SP_PROP_SHAPE_INSIDE, "shape-inside"}, + {SP_PROP_SHAPE_OUTSIDE, "shape-outside"}, + {SP_PROP_SHAPE_PADDING, "shape-padding"}, + {SP_PROP_SHAPE_MARGIN, "shape-margin"}, /* Text Decoration */ {SP_PROP_TEXT_DECORATION, "text-decoration"}, {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, diff --git a/src/attributes.h b/src/attributes.h index 8e091df71..645aad00b 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -196,6 +196,8 @@ enum SPAttributeEnum { SP_ATTR_DX, SP_ATTR_DY, SP_ATTR_ROTATE, + SP_ATTR_TEXTLENGTH, + SP_ATTR_LENGTHADJUST, SP_ATTR_SODIPODI_ROLE, /* SPText */ SP_ATTR_SODIPODI_LINESPACING, @@ -291,6 +293,7 @@ enum SPAttributeEnum { SP_ATTR_FY, /* SPMeshPatch */ SP_ATTR_TENSOR, + SP_ATTR_SMOOTH, /* SPPattern */ SP_ATTR_PATTERNUNITS, SP_ATTR_PATTERNCONTENTUNITS, @@ -443,6 +446,11 @@ enum SPAttributeEnum { SP_PROP_TEXT_ANCHOR, SP_PROP_WHITE_SPACE, + SP_PROP_SHAPE_INSIDE, + SP_PROP_SHAPE_OUTSIDE, + SP_PROP_SHAPE_PADDING, + SP_PROP_SHAPE_MARGIN, + /* Text Decoration */ SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ diff --git a/src/box3d.cpp b/src/box3d.cpp index 3c0cbb675..86f99049b 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -37,7 +37,7 @@ #include "preferences.h" #include "desktop.h" -#include "desktop-handles.h" + #include "macros.h" static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box); @@ -47,16 +47,16 @@ static gint counter = 0; #include "sp-factory.h" namespace { - SPObject* createBox3D() { - return new SPBox3D(); - } + SPObject* createBox3D() { + return new SPBox3D(); + } - bool box3DRegistered = SPFactory::instance().registerObject("inkscape:box3d", createBox3D); + bool box3DRegistered = SPFactory::instance().registerObject("inkscape:box3d", createBox3D); } SPBox3D::SPBox3D() : SPGroup() { - this->my_counter = 0; - this->swapped = Box3D::NONE; + this->my_counter = 0; + this->swapped = Box3D::NONE; this->persp_href = NULL; this->persp_ref = new Persp3DReference(this); @@ -87,7 +87,7 @@ void SPBox3D::build(SPDocument *document, Inkscape::XML::Node *repr) { } void SPBox3D::release() { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; if (box->persp_href) { @@ -125,7 +125,7 @@ void SPBox3D::release() { } void SPBox3D::set(unsigned int key, const gchar* value) { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; switch (key) { @@ -210,7 +210,7 @@ void SPBox3D::update(SPCtx *ctx, guint flags) { } Inkscape::XML::Node* SPBox3D::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { @@ -401,7 +401,7 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta snap_pts[3] = diag2.closest_to (pt); } - gdouble const zoom = inkscape_active_desktop()->current_zoom(); + gdouble const zoom = SP_ACTIVE_DESKTOP->current_zoom(); // determine the distances to all potential snapping points double snap_dists[MAX_POINT_COUNT]; @@ -912,9 +912,11 @@ box3d_swap_sides(int z_orders[6], Box3D::Axis axis) { } } - int tmp = z_orders[pos1]; - z_orders[pos1] = z_orders[pos2]; - z_orders[pos2] = tmp; + if (pos1 != -1){ + int tmp = z_orders[pos1]; + z_orders[pos1] = z_orders[pos2]; + z_orders[pos2] = tmp; + } } diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index cb72f65dc..c13b9a5d3 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -32,7 +32,7 @@ #include "xml/node.h" #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document-undo.h" #include "sp-namedview.h" #include "sp-item-group.h" @@ -87,11 +87,11 @@ void SPAvoidRef::setAvoid(char const *value) void SPAvoidRef::handleSettingChange(void) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) { return; } - if (sp_desktop_document(desktop) != item->document) { + if (desktop->getDocument() != item->document) { // We don't want to go any further if the active desktop's document // isn't the same as the document that this item is part of. This // case can happen if a new document is loaded from the file chooser @@ -277,7 +277,7 @@ static std::vector<Geom::Point> approxItemWithPoints(SPItem const *item, const G } static Avoid::Polygon avoid_item_poly(SPItem const *item) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); double spacing = desktop->namedview->connector_spacing; @@ -370,7 +370,7 @@ void init_avoided_shape_geometry(SPDesktop *desktop) { // Don't count this as changes to the document, // it is basically just late initialisation. - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); bool saved = DocumentUndo::getUndoSensitive(document); DocumentUndo::setUndoSensitive(document, false); diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 5d8ea8b9f..5dbe0f8dc 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -24,7 +24,7 @@ #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "display/canvas-axonomgrid.h" #include "display/canvas-grid.h" @@ -40,6 +40,7 @@ #include "display/sp-canvas.h" #include "sp-guide.h" #include "sp-namedview.h" +#include "sp-root.h" #include "ui/tools-switch.h" #include "verbs.h" #include "widgets/desktop-widget.h" @@ -217,11 +218,21 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge if ((horiz ? wy : wx) >= 0) { Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("sodipodi:guide"); + + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = event_dt.x(); + double newy = event_dt.y(); + + SPRoot *root = desktop->doc()->getRoot(); + if( root->viewBox_set ) { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + sp_repr_set_point(repr, "position", Geom::Point( newx, newy )); sp_repr_set_point(repr, "orientation", normal); - sp_repr_set_point(repr, "position", event_dt); desktop->namedview->appendChild(repr); Inkscape::GC::release(repr); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create guide")); } desktop->set_coordinate_status(event_dt); @@ -229,7 +240,7 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge if (!dragged) { // Ruler click (without drag) toggle the guide visibility on and off Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - sp_namedview_toggle_guides(sp_desktop_document(desktop), repr); + sp_namedview_toggle_guides(desktop->getDocument(), repr); } @@ -477,14 +488,14 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) assert(false); break; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Move guide")); } else { /* Undo movement of any attached shapes. */ guide->moveto(guide->getPoint(), false); guide->set_normal(guide->getNormal(), false); sp_guide_remove(guide); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Delete guide")); } moved = false; @@ -505,7 +516,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if ((event->crossing.state & GDK_SHIFT_MASK) && (drag_type != SP_DRAG_MOVE_ORIGIN)) { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -514,7 +525,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) } else { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_HAND1); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -531,7 +542,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) sp_guideline_set_color(SP_GUIDELINE(item), guide->getColor()); // restore event context's cursor - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), desktop->event_context->cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), desktop->event_context->cursor); desktop->guidesMessageContext()->clear(); break; @@ -553,7 +564,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if (drag_type != SP_DRAG_MOVE_ORIGIN) { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -574,7 +585,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) case GDK_KEY_Shift_R: GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else diff --git a/src/desktop-handles.cpp b/src/desktop-handles.cpp deleted file mode 100644 index 8fa7ad986..000000000 --- a/src/desktop-handles.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Frontends - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "display/sp-canvas.h" -#include "display/sp-canvas-item.h" -#include "desktop.h" -#include "desktop-handles.h" - -Inkscape::Selection * -sp_desktop_selection (SPDesktop const * desktop) -{ - g_assert(desktop != NULL); - - return desktop->selection; -} - -SPDocument * -sp_desktop_document (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->doc(); -} - -SPCanvas * -sp_desktop_canvas (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return (SP_CANVAS_ITEM(desktop->main))->canvas; -} - -SPCanvasItem * -sp_desktop_acetate (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->acetate; -} - -SPCanvasGroup * -sp_desktop_main (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->main; -} - -SPCanvasGroup * -sp_desktop_gridgroup (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->gridgroup; -} - -SPCanvasGroup * -sp_desktop_guides (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->guides; -} - -SPCanvasItem * -sp_desktop_drawing (SPDesktop const *desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->drawing; -} - -SPCanvasGroup * -sp_desktop_sketch (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->sketch; -} - -SPCanvasGroup * -sp_desktop_controls (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->controls; -} - -SPCanvasGroup * -sp_desktop_tempgroup (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->tempgroup; -} - -Inkscape::MessageStack * -sp_desktop_message_stack (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->messageStack(); -} - -SPNamedView * -sp_desktop_namedview (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->namedview; -} - - diff --git a/src/desktop-handles.h b/src/desktop-handles.h deleted file mode 100644 index 70a8c8b5f..000000000 --- a/src/desktop-handles.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef SEEN_SP_DESKTOP_HANDLES_H -#define SEEN_SP_DESKTOP_HANDLES_H - -/* - * Frontends - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -class SPDesktop; -class SPDocument; - -namespace Inkscape { -namespace UI { -namespace Tools { - -class ToolBase; - -} -} -} - -class SPNamedView; -struct SPCanvas; -struct SPCanvasGroup; -struct SPCanvasItem; - -namespace Inkscape { - class MessageStack; - class Selection; -} - -#define SP_DESKTOP_ZOOM_MAX 256.0 -#define SP_DESKTOP_ZOOM_MIN 0.01 - -#define SP_COORDINATES_UNDERLINE_NONE (0) -#define SP_COORDINATES_UNDERLINE_X (1 << Geom::X) -#define SP_COORDINATES_UNDERLINE_Y (1 << Geom::Y) - -//ToolBase * sp_desktop_event_context (SPDesktop const * desktop); -Inkscape::Selection * sp_desktop_selection (SPDesktop const * desktop); -SPDocument * sp_desktop_document (SPDesktop const * desktop); -SPCanvas * sp_desktop_canvas (SPDesktop const * desktop); -SPCanvasItem * sp_desktop_acetate (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_main (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_gridgroup (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_guides (SPDesktop const * desktop); -SPCanvasItem *sp_desktop_drawing (SPDesktop const *desktop); -SPCanvasGroup * sp_desktop_sketch (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_controls (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_tempgroup (SPDesktop const * desktop); -Inkscape::MessageStack * sp_desktop_message_stack (SPDesktop const * desktop); -SPNamedView * sp_desktop_namedview (SPDesktop const * desktop); - -#endif // SEEN_SP_DESKTOP_HANDLES_H - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 15dc339cf..ee9fa39ec 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -49,6 +49,24 @@ #include "box3d-side.h" #include <2geom/math-utils.h> +namespace { + +bool isTextualItem(SPObject const *obj) +{ + bool isTextual = dynamic_cast<SPText const *>(obj) // + || dynamic_cast<SPFlowtext const *>(obj) // + || dynamic_cast<SPTSpan const *>(obj) // + || dynamic_cast<SPTRef const *>(obj) // + || dynamic_cast<SPTextPath const *>(obj) // + || dynamic_cast<SPFlowdiv const *>(obj) // + || dynamic_cast<SPFlowpara const *>(obj) // + || dynamic_cast<SPFlowtspan const *>(obj); + + return isTextual; +} + +} // namespace + /** * Set color on selection on desktop. */ @@ -89,8 +107,10 @@ void sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) { // non-items should not have style - if (!SP_IS_ITEM(o)) + SPItem *item = dynamic_cast<SPItem *>(o); + if (!item) { return; + } // 1. tspans with role=line are not regular objects in that they are not supposed to have style of their own, // but must always inherit from the parent text. Same for textPath. @@ -100,22 +120,24 @@ sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) // it, be it clone or not; it's just styleless shape (because that's how Inkscape does // flowtext). + SPTSpan *tspan = dynamic_cast<SPTSpan *>(o); + if (!(skip_lines - && ((SP_IS_TSPAN(o) && SP_TSPAN(o)->role == SP_TSPAN_ROLE_LINE) - || SP_IS_FLOWDIV(o) - || SP_IS_FLOWPARA(o) - || SP_IS_TEXTPATH(o)) + && ((tspan && tspan->role == SP_TSPAN_ROLE_LINE) + || dynamic_cast<SPFlowdiv *>(o) + || dynamic_cast<SPFlowpara *>(o) + || dynamic_cast<SPTextPath *>(o)) && !o->getAttribute("style")) && - !(SP_IS_FLOWREGION(o) || - SP_IS_FLOWREGIONEXCLUDE(o) || - (SP_IS_USE(o) && + !(dynamic_cast<SPFlowregionbreak *>(o) || + dynamic_cast<SPFlowregionExclude *>(o) || + (dynamic_cast<SPUse *>(o) && o->parent && - (SP_IS_FLOWREGION(o->parent) || - SP_IS_FLOWREGIONEXCLUDE(o->parent) - ) - ) - ) + (dynamic_cast<SPFlowregion *>(o->parent) || + dynamic_cast<SPFlowregionExclude *>(o->parent) + ) + ) + ) ) { SPCSSAttr *css_set = sp_repr_css_attr_new(); @@ -123,7 +145,7 @@ sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) // Scale the style by the inverse of the accumulated parent transform in the paste context. { - Geom::Affine const local(SP_ITEM(o)->i2doc_affine()); + Geom::Affine const local(item->i2doc_affine()); double const ex(local.descrim()); if ( ( ex != 0. ) && ( ex != 1. ) ) { @@ -137,8 +159,9 @@ sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) } // setting style on child of clone spills into the clone original (via shared repr), don't do it! - if (SP_IS_USE(o)) + if (dynamic_cast<SPUse *>(o)) { return; + } for ( SPObject *child = o->firstChild() ; child ; child = child->getNext() ) { if (sp_repr_css_property(css, "opacity", NULL) != NULL) { @@ -212,11 +235,10 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write css_no_text = sp_css_attr_unset_text(css_no_text); for (GSList const *i = desktop->selection->itemList(); i != NULL; i = i->next) { + SPItem *item = reinterpret_cast<SPItem *>(i->data); // If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME) - if ( SP_IS_TEXT(i->data) || SP_IS_FLOWTEXT(i->data) - || SP_IS_TSPAN(i->data) || SP_IS_TREF(i->data) || SP_IS_TEXTPATH(i->data) - || SP_IS_FLOWDIV(i->data) || SP_IS_FLOWPARA(i->data) || SP_IS_FLOWTSPAN(i->data)) { + if (isTextualItem(item)) { // If any font property has changed, then we have written out the font // properties in longhand and we need to remove the 'font' shorthand. @@ -224,11 +246,11 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write sp_repr_css_unset_property(css, "font"); } - sp_desktop_apply_css_recursive(SP_OBJECT(i->data), css, true); + sp_desktop_apply_css_recursive(item, css, true); } else { - sp_desktop_apply_css_recursive(SP_OBJECT(i->data), css_no_text, true); + sp_desktop_apply_css_recursive(item, css_no_text, true); } } @@ -406,10 +428,9 @@ sp_desktop_get_font_size_tool(SPDesktop *desktop) double ret = 12; if (!style_str.empty()) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str.data()); - ret = style->font_size.computed; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str.data()); + ret = style.font_size.computed; } return ret; } @@ -427,16 +448,17 @@ stroke_average_width (GSList const *objects) int n_notstroked = 0; for (GSList const *l = objects; l != NULL; l = l->next) { - if (!SP_IS_ITEM (l->data)) + SPObject *obj = reinterpret_cast<SPObject *>(l->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + if (!item) { continue; + } - Geom::Affine i2dt = SP_ITEM(l->data)->i2dt_affine(); - - SPObject *object = SP_OBJECT(l->data); + Geom::Affine i2dt = item->i2dt_affine(); - double width = object->style->stroke_width.computed * i2dt.descrim(); + double width = item->style->stroke_width.computed * i2dt.descrim(); - if ( object->style->stroke.isNone() || IS_NAN(width)) { + if ( item->style->stroke.isNone() || IS_NAN(width)) { ++n_notstroked; // do not count nonstroked objects continue; } else { @@ -493,7 +515,10 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill bool same_color = true; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!obj) { + continue; + } SPStyle *style = obj->style; if (!style) { continue; @@ -504,9 +529,9 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill // We consider paint "effectively set" for anything within text hierarchy SPObject *parent = obj->parent; bool paint_effectively_set = - paint->set || (SP_IS_TEXT(parent) || SP_IS_TEXTPATH(parent) || SP_IS_TSPAN(parent) - || SP_IS_FLOWTEXT(parent) || SP_IS_FLOWDIV(parent) || SP_IS_FLOWPARA(parent) - || SP_IS_FLOWTSPAN(parent) || SP_IS_FLOWLINE(parent)); + paint->set || (dynamic_cast<SPText *>(parent) || dynamic_cast<SPTextPath *>(parent) || dynamic_cast<SPTSpan *>(parent) + || dynamic_cast<SPFlowtext *>(parent) || dynamic_cast<SPFlowdiv *>(parent) || dynamic_cast<SPFlowpara *>(parent) + || dynamic_cast<SPFlowtspan *>(parent) || dynamic_cast<SPFlowline*>(parent)); // 1. Bail out with QUERY_STYLE_MULTIPLE_DIFFERENT if necessary @@ -518,38 +543,45 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill if (paint_res->set && paint->set && paint_res->isPaintserver()) { // both previous paint and this paint were a server, see if the servers are compatible - SPPaintServer *server_res = isfill? SP_STYLE_FILL_SERVER (style_res) : SP_STYLE_STROKE_SERVER (style_res); - SPPaintServer *server = isfill? SP_STYLE_FILL_SERVER (style) : SP_STYLE_STROKE_SERVER (style); + SPPaintServer *server_res = isfill ? style_res->getFillPaintServer() : style_res->getStrokePaintServer(); + SPPaintServer *server = isfill ? style->getFillPaintServer() : style->getStrokePaintServer(); - if (SP_IS_LINEARGRADIENT (server_res)) { - - if (!SP_IS_LINEARGRADIENT(server)) + SPLinearGradient *linear_res = dynamic_cast<SPLinearGradient *>(server_res); + SPRadialGradient *radial_res = linear_res ? NULL : dynamic_cast<SPRadialGradient *>(server_res); + SPPattern *pattern_res = (linear_res || radial_res) ? NULL : dynamic_cast<SPPattern *>(server_res); + if (linear_res) { + SPLinearGradient *linear = dynamic_cast<SPLinearGradient *>(server); + if (!linear) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + } - SPGradient *vector = SP_GRADIENT(server)->getVector(); - SPGradient *vector_res = SP_GRADIENT(server_res)->getVector(); - if (vector_res != vector) + SPGradient *vector = linear->getVector(); + SPGradient *vector_res = linear_res->getVector(); + if (vector_res != vector) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different gradient vectors - - } else if (SP_IS_RADIALGRADIENT (server_res)) { - - if (!SP_IS_RADIALGRADIENT(server)) + } + } else if (radial_res) { + SPRadialGradient *radial = dynamic_cast<SPRadialGradient *>(server); + if (!radial) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + } - SPGradient *vector = SP_GRADIENT(server)->getVector(); - SPGradient *vector_res = SP_GRADIENT(server_res)->getVector(); - if (vector_res != vector) + SPGradient *vector = radial->getVector(); + SPGradient *vector_res = radial_res->getVector(); + if (vector_res != vector) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different gradient vectors - - } else if (SP_IS_PATTERN (server_res)) { - - if (!SP_IS_PATTERN(server)) + } + } else if (pattern_res) { + SPPattern *pattern = dynamic_cast<SPPattern *>(server); + if (!pattern) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + } - SPPattern *pat = pattern_getroot (SP_PATTERN (server)); - SPPattern *pat_res = pattern_getroot (SP_PATTERN (server_res)); - if (pat_res != pat) + SPPattern *pat = pattern_getroot (pattern); + SPPattern *pat_res = pattern_getroot (pattern_res); + if (pat_res != pat) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots + } } } @@ -593,7 +625,7 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill paintImpossible = false; paint_res->colorSet = paint->colorSet; - paint_res->currentcolor = paint->currentcolor; + paint_res->paintOrigin = paint->paintOrigin; if (paint_res->set && paint_effectively_set && paint->isPaintserver()) { // copy the server gchar const *string = NULL; // memory leak results if style->get* called inside sp_style_set_to_uri_string. if (isfill) { @@ -667,7 +699,10 @@ objects_query_opacity (GSList *objects, SPStyle *style_res) for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!obj) { + continue; + } SPStyle *style = obj->style; if (!style) { continue; @@ -720,8 +755,12 @@ objects_query_strokewidth (GSList *objects, SPStyle *style_res) int n_stroked = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); - if (!SP_IS_ITEM(obj)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!obj) { + continue; + } + SPItem *item = dynamic_cast<SPItem *>(obj); + if (!item) { continue; } SPStyle *style = obj->style; @@ -740,7 +779,7 @@ objects_query_strokewidth (GSList *objects, SPStyle *style_res) noneSet &= style->stroke.isNone(); - Geom::Affine i2d = SP_ITEM(obj)->i2dt_affine(); + Geom::Affine i2d = item->i2dt_affine(); double sw = style->stroke_width.computed * i2d.descrim(); if (!IS_NAN(sw)) { @@ -790,8 +829,8 @@ objects_query_miterlimit (GSList *objects, SPStyle *style_res) bool same_ml = true; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); - if (!SP_IS_ITEM(obj)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!dynamic_cast<SPItem *>(obj)) { continue; } SPStyle *style = obj->style; @@ -849,8 +888,8 @@ objects_query_strokecap (GSList *objects, SPStyle *style_res) int n_stroked = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); - if (!SP_IS_ITEM(obj)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!dynamic_cast<SPItem *>(obj)) { continue; } SPStyle *style = obj->style; @@ -903,8 +942,8 @@ objects_query_strokejoin (GSList *objects, SPStyle *style_res) int n_stroked = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); - if (!SP_IS_ITEM(obj)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!dynamic_cast<SPItem *>(obj)) { continue; } SPStyle *style = obj->style; @@ -966,11 +1005,9 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res) int no_size = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); - if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) - && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj) - && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) { + if (!isTextualItem(obj)) { continue; } @@ -980,7 +1017,9 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res) } texts ++; - double dummy = style->font_size.computed * Geom::Affine(SP_ITEM(obj)->i2dt_affine()).descrim(); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + double dummy = style->font_size.computed * Geom::Affine(item->i2dt_affine()).descrim(); if (!IS_NAN(dummy)) { size += dummy; /// \todo FIXME: we assume non-% units here } else { @@ -1085,12 +1124,11 @@ objects_query_fontstyle (GSList *objects, SPStyle *style_res) int texts = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); - if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) - && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj) - && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) + if (!isTextualItem(obj)) { continue; + } SPStyle *style = obj->style; if (!style) { @@ -1155,11 +1193,9 @@ objects_query_baselines (GSList *objects, SPStyle *style_res) int texts = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); - if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) - && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj) - && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) { + if (!isTextualItem(obj)) { continue; } @@ -1245,12 +1281,10 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res) style_res->font_family.set = FALSE; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); // std::cout << " " << reinterpret_cast<SPObject*>(i->data)->getId() << std::endl; - if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) - && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj) - && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) { + if (!isTextualItem(obj)) { continue; } @@ -1303,12 +1337,10 @@ objects_query_fontspecification (GSList *objects, SPStyle *style_res) style_res->font_specification.set = FALSE; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); // std::cout << " " << reinterpret_cast<SPObject*>(i->data)->getId() << std::endl; - if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) - && !SP_IS_TSPAN(obj) && !SP_IS_TREF(obj) && !SP_IS_TEXTPATH(obj) - && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) { + if (!isTextualItem(obj)) { continue; } @@ -1363,9 +1395,12 @@ objects_query_blend (GSList *objects, SPStyle *style_res) guint items = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!obj) { + continue; + } SPStyle *style = obj->style; - if (!style || !SP_IS_ITEM(obj)) { + if (!style || !dynamic_cast<SPItem *>(obj)) { continue; } @@ -1378,14 +1413,14 @@ objects_query_blend (GSList *objects, SPStyle *style_res) // determine whether filter is simple (blend and/or blur) or complex for(SPObject *primitive_obj = style->getFilter()->children; - primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); + primitive_obj && dynamic_cast<SPFilterPrimitive *>(primitive_obj); primitive_obj = primitive_obj->next) { - SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); - if(SP_IS_FEBLEND(primitive)) + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + if (dynamic_cast<SPFeBlend *>(primitive)) { ++blendcount; - else if(SP_IS_GAUSSIANBLUR(primitive)) + } else if (dynamic_cast<SPGaussianBlur *>(primitive)) { ++blurcount; - else { + } else { blurcount = complex_filter; break; } @@ -1394,10 +1429,10 @@ objects_query_blend (GSList *objects, SPStyle *style_res) // simple filter if(blurcount == 1 || blendcount == 1) { for(SPObject *primitive_obj = style->getFilter()->children; - primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); + primitive_obj && dynamic_cast<SPFilterPrimitive *>(primitive_obj); primitive_obj = primitive_obj->next) { - if(SP_IS_FEBLEND(primitive_obj)) { - SPFeBlend *spblend = SP_FEBLEND(primitive_obj); + SPFeBlend *spblend = dynamic_cast<SPFeBlend *>(primitive_obj); + if (spblend) { blend = spblend->blend_mode; } } @@ -1450,16 +1485,20 @@ objects_query_blur (GSList *objects, SPStyle *style_res) guint items = 0; for (GSList const *i = objects; i != NULL; i = i->next) { - SPObject *obj = SP_OBJECT (i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + if (!obj) { + continue; + } SPStyle *style = obj->style; if (!style) { continue; } - if (!SP_IS_ITEM(obj)) { + SPItem *item = dynamic_cast<SPItem *>(obj); + if (!item) { continue; } - Geom::Affine i2d = SP_ITEM(obj)->i2dt_affine(); + Geom::Affine i2d = item->i2dt_affine(); items ++; @@ -1468,12 +1507,12 @@ objects_query_blur (GSList *objects, SPStyle *style_res) //cycle through filter primitives SPObject *primitive_obj = style->getFilter()->children; while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { - SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + if (primitive) { //if primitive is gaussianblur - if(SP_IS_GAUSSIANBLUR(primitive)) { - SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive); + SPGaussianBlur * spblur = dynamic_cast<SPGaussianBlur *>(primitive); + if (spblur) { float num = spblur->stdDeviation.getNumber(); float dummy = num * i2d.descrim(); if (!IS_NAN(dummy)) { diff --git a/src/desktop.cpp b/src/desktop.cpp index 74dea3ca1..cdf8f276c 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -37,7 +37,7 @@ #include "color.h" #include "desktop-events.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "device-manager.h" #include "display/canvas-arena.h" @@ -56,7 +56,6 @@ #include "event-log.h" #include "helper/action-context.h" #include "ui/interface.h" -#include "inkscape-private.h" #include "layer-fns.h" #include "layer-manager.h" #include "layer-model.h" @@ -94,28 +93,28 @@ static void _reconstruction_finish(SPDesktop * desktop); static void _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop); SPDesktop::SPDesktop() : - _dlg_mgr( 0 ), - namedview( 0 ), - canvas( 0 ), - layers( 0 ), - selection( 0 ), - event_context( 0 ), - layer_manager( 0 ), - event_log( 0 ), - temporary_item_list( 0 ), - snapindicator( 0 ), - acetate( 0 ), - main( 0 ), - gridgroup( 0 ), - guides( 0 ), - drawing( 0 ), - sketch( 0 ), - controls( 0 ), - tempgroup ( 0 ), - table( 0 ), - page( 0 ), - page_border( 0 ), - current( 0 ), + _dlg_mgr( NULL ), + namedview( NULL ), + canvas( NULL ), + layers( NULL ), + selection( NULL ), + event_context( NULL ), + layer_manager( NULL ), + event_log( NULL ), + temporary_item_list( NULL ), + snapindicator( NULL ), + acetate( NULL ), + main( NULL ), + gridgroup( NULL ), + guides( NULL ), + drawing( NULL ), + sketch( NULL ), + controls( NULL ), + tempgroup ( NULL ), + table( NULL ), + page( NULL ), + page_border( NULL ), + current( NULL ), _focusMode(false), dkey( 0 ), number( 0 ), @@ -124,16 +123,15 @@ SPDesktop::SPDesktop() : waiting_cursor( false ), showing_dialogs ( false ), guides_active( false ), - gr_item( 0 ), + gr_item( NULL ), gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), gr_fill_or_stroke( Inkscape::FOR_FILL ), _reconstruction_old_layer_id(), // an id attribute is not allowed to be the empty string _display_mode(Inkscape::RENDERMODE_NORMAL), _display_color_mode(Inkscape::COLORMODE_NORMAL), - _widget( 0 ), - _inkscape( 0 ), - _guides_message_context( 0 ), + _widget( NULL ), + _guides_message_context( NULL ), _active( false ), _w2d(), _d2w(), @@ -299,7 +297,6 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid // ? // sp_active_desktop_set (desktop); - _inkscape = INKSCAPE; _activate_connection = _activate_signal.connect( sigc::bind( @@ -385,10 +382,6 @@ void SPDesktop::destroy() layer_manager = NULL; } - if (_inkscape) { - _inkscape = NULL; - } - if (drawing) { doc()->getRoot()->invoke_hide(dkey); g_object_unref(drawing); @@ -509,7 +502,7 @@ void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) { canvas->rendermode = mode; _display_mode = mode; redrawDesktop(); - _widget->setTitle( sp_desktop_document(this)->getName() ); + _widget->setTitle( this->getDocument()->getName() ); } void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { // reload grayscale matrix from prefs @@ -530,7 +523,7 @@ void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { canvas->colorrendermode = mode; _display_color_mode = mode; redrawDesktop(); - _widget->setTitle( sp_desktop_document(this)->getName() ); + _widget->setTitle( this->getDocument()->getName() ); } void SPDesktop::displayModeToggle() { @@ -1431,7 +1424,7 @@ void SPDesktop::emitToolSubselectionChanged(gpointer data) { _tool_subselection_changed.emit(data); - inkscape_subselection_changed (this); + INKSCAPE.subselection_changed (this); } void SPDesktop::updateNow() @@ -1453,7 +1446,7 @@ void SPDesktop::disableInteraction() void SPDesktop::setWaitingCursor() { GdkCursor *waiting = gdk_cursor_new(GDK_WATCH); - gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(this))), waiting); + gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(getCanvas())), waiting); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(waiting); #else @@ -1488,7 +1481,7 @@ void SPDesktop::toggleGrids() } } else { //there is no grid present at the moment. add a rectangular grid and make it visible - namedview->writeNewGrid(sp_desktop_document(this), Inkscape::GRID_RECTANGULAR); + namedview->writeNewGrid(this->getDocument(), Inkscape::GRID_RECTANGULAR); showGrids(true); } } diff --git a/src/desktop.h b/src/desktop.h index 509f8a396..a0b9592d0 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -103,6 +103,9 @@ namespace Inkscape { } } +#define SP_DESKTOP_ZOOM_MAX 256.0 +#define SP_DESKTOP_ZOOM_MIN 0.01 + /** * SPDesktop is a subclass of View, implementing an editable document * canvas. It is extensively used by many UI controls that need certain @@ -424,7 +427,6 @@ public: private: Inkscape::UI::View::EditWidgetInterface *_widget; - InkscapeApplication *_inkscape; Inkscape::MessageContext *_guides_message_context; bool _active; Geom::Affine _w2d; diff --git a/src/dir-util-test.h b/src/dir-util-test.h index cc3bc20b8..735f0174e 100644 --- a/src/dir-util-test.h +++ b/src/dir-util-test.h @@ -12,11 +12,19 @@ public: void testBase() { char const* cases[][3] = { +#if defined(WIN32) || defined(__WIN32__) + {"\\foo\\bar", "\\foo", "bar"}, + {"\\foo\\barney", "\\foo\\bar", "\\foo\\barney"}, + {"\\foo\\bar\\baz", "\\foo\\", "bar\\baz"}, + {"\\foo\\bar\\baz", "\\", "foo\\bar\\baz"}, + {"\\foo\\bar\\baz", "\\foo\\qux", "\\foo\\bar\\baz"}, +#else {"/foo/bar", "/foo", "bar"}, {"/foo/barney", "/foo/bar", "/foo/barney"}, {"/foo/bar/baz", "/foo/", "bar/baz"}, {"/foo/bar/baz", "/", "foo/bar/baz"}, {"/foo/bar/baz", "/foo/qux", "/foo/bar/baz"}, +#endif }; for ( size_t i = 0; i < G_N_ELEMENTS(cases); i++ ) diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 592c962a6..ac93f5c88 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -36,7 +36,7 @@ #include "ui/widget/registered-widget.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/cairo-utils.h" #include "display/canvas-grid.h" #include "display/sp-canvas-util.h" @@ -46,6 +46,7 @@ #include "preferences.h" #include "sp-namedview.h" #include "sp-object.h" +#include "sp-root.h" #include "svg/svg-color.h" #include "2geom/line.h" #include "2geom/angle.h" @@ -213,22 +214,58 @@ static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color) void CanvasAxonomGrid::readRepr() { + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) { + // scaling is uniform, try to reduce numerical error + scale_x = (scale_x + scale_y)/2.0; + scale_y = scale_x; + } + } + gchar const *value; + if ( (value = repr->attribute("originx")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::X] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::X] = q.quantity * scale_x; + } } + if ( (value = repr->attribute("originy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::Y] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::Y] = q.quantity * scale_y; + } } if ( (value = repr->attribute("spacingy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - lengthy = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + lengthy = q.value("px"); + } else { + // Grid in 'user units' + lengthy = q.quantity * scale_y; // We do not handle scale_x != scale_y + } if (lengthy < 0.0500) lengthy = 0.0500; } @@ -281,6 +318,10 @@ CanvasAxonomGrid::readRepr() snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); } + if ( (value = repr->attribute("units")) ) { + gridunit = unit_table.getUnit(value); // Display unit identifier in grid menu + } + for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); } @@ -316,11 +357,14 @@ _wr.setUpdating (true); Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu( _("Grid _units:"), "units", _wr, repr, doc) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) ); + _("_Origin X:"), _("X coordinate of grid origin"), "originx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) ); + _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _Y:"), _("Base length of z-axis"), "spacingy", *_rumg, _wr, repr, doc) ); + _("Spacing _Y:"), _("Base length of z-axis"), "spacingy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalar *_rsu_ax = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( _("Angle X:"), _("Angle of x-axis"), "gridanglex", _wr, repr, doc ) ); Inkscape::UI::Widget::RegisteredScalar *_rsu_az = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 2eeaa7006..0a43ed8b7 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -36,7 +36,7 @@ #include "desktop.h" #include "sp-canvas-util.h" #include "util/mathfns.h" -#include "desktop-handles.h" + #include "display/cairo-utils.h" #include "display/canvas-axonomgrid.h" #include "display/canvas-grid.h" @@ -47,6 +47,7 @@ #include "preferences.h" #include "sp-namedview.h" #include "sp-object.h" +#include "sp-root.h" #include "svg/svg-color.h" #include "svg/stringstream.h" #include "util/mathfns.h" @@ -284,12 +285,12 @@ CanvasGrid::createCanvasItem(SPDesktop * desktop) // check if there is already a canvasitem on this desktop linking to this grid for (GSList *l = canvasitems; l != NULL; l = l->next) { - if ( sp_desktop_gridgroup(desktop) == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) { + if ( desktop->getGridGroup() == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) { return NULL; } } - GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) ); + GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(desktop->getGridGroup(), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) ); item->grid = this; sp_canvas_item_show(SP_CANVAS_ITEM(item)); @@ -367,17 +368,21 @@ bool CanvasGrid::isEnabled() const return snapper->getEnabled(); } +// Used to shift origin when page size changed to fit drawing. void CanvasGrid::setOrigin(Geom::Point const &origin_px) { - Inkscape::SVGOStringStream os_x, os_y; - gdouble val; + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->viewBox.width() / root->width.computed; + scale_y = root->viewBox.height() / root->height.computed; + } - val = origin_px[Geom::X]; - val = Inkscape::Util::Quantity::convert(val, "px", gridunit); - os_x << val << gridunit->abbr; - val = origin_px[Geom::Y]; - val = Inkscape::Util::Quantity::convert(val, "px", gridunit); - os_y << val << gridunit->abbr; + // Write out in 'user-units' + Inkscape::SVGOStringStream os_x, os_y; + os_x << origin_px[Geom::X] * scale_x; + os_y << origin_px[Geom::Y] * scale_y; repr->setAttribute("originx", os_x.str().c_str()); repr->setAttribute("originy", os_y.str().c_str()); } @@ -504,33 +509,6 @@ static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color) return TRUE; } -/** If the passed scalar is invalid (<=0), then set the widget and the scalar - to use the given old value. - - @param oldVal Old value to use if the new one is invalid. - @param pTarget The scalar to validate. - @param widget Widget associated with the scalar. -*/ -static void validateScalar(double oldVal, - double* pTarget) -{ - // Avoid nullness. - if ( pTarget == NULL ) - return; - - // Invalid new value? - if ( *pTarget <= 0 ) { - // If the old value is somehow invalid as well, then default to 1. - if ( oldVal <= 0 ) - oldVal = 1; - - // Reset the scalar and associated widget to the old value. - *pTarget = oldVal; - } //if - -} //validateScalar - - /** If the passed int is invalid (<=0), then set the widget and the int to use the given old value. @@ -560,34 +538,83 @@ static void validateInt(gint oldVal, void CanvasXYGrid::readRepr() { + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) { + // scaling is uniform, try to reduce numerical error + scale_x = (scale_x + scale_y)/2.0; + scale_y = scale_x; + } + } + gchar const *value; + if ( (value = repr->attribute("originx")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::X] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::X] = q.quantity * scale_x; + } } if ( (value = repr->attribute("originy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::Y] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::Y] = q.quantity * scale_y; + } } if ( (value = repr->attribute("spacingx")) ) { - double oldVal = spacing[Geom::X]; + + // Ensure a valid default value + if( spacing[Geom::X] <= 0.0 ) + spacing[Geom::X] = 1.0; + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - spacing[Geom::X] = q.quantity; - validateScalar(oldVal, &spacing[Geom::X]); - spacing[Geom::X] = Inkscape::Util::Quantity::convert(spacing[Geom::X], gridunit, "px"); + // Ensure a valid new value + if( q.quantity > 0 ) { + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + spacing[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + spacing[Geom::X] = q.quantity * scale_x; + } + } } + if ( (value = repr->attribute("spacingy")) ) { - double oldVal = spacing[Geom::Y]; + + // Ensure a valid default value + if( spacing[Geom::Y] <= 0.0 ) + spacing[Geom::Y] = 1.0; + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - spacing[Geom::Y] = q.quantity; - validateScalar(oldVal, &spacing[Geom::Y]); - spacing[Geom::Y] = Inkscape::Util::Quantity::convert(spacing[Geom::Y], gridunit, "px"); + // Ensure a valid new value + if( q.quantity > 0 ) { + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + spacing[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + spacing[Geom::Y] = q.quantity * scale_y; + } + } } if ( (value = repr->attribute("color")) ) { @@ -629,6 +656,10 @@ CanvasXYGrid::readRepr() snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); } + if ( (value = repr->attribute("units")) ) { + gridunit = unit_table.getUnit(value); // Display unit identifier in grid menu + } + for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); } @@ -666,13 +697,17 @@ CanvasXYGrid::newSpecificWidget() Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu( _("Grid _units:"), "units", _wr, repr, doc) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) ); + _("_Origin X:"), _("X coordinate of grid origin"), "originx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) ); + _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sx = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _X:"), _("Distance between vertical grid lines"), "spacingx", *_rumg, _wr, repr, doc) ); + _("Spacing _X:"), _("Distance between vertical grid lines"), "spacingx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _Y:"), _("Distance between horizontal grid lines"), "spacingy", *_rumg, _wr, repr, doc) ); + _("Spacing _Y:"), _("Distance between horizontal grid lines"), "spacingy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gcol = Gtk::manage( new Inkscape::UI::Widget::RegisteredColorPicker( diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index bce89d70e..1a9cbfdcc 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -21,14 +21,11 @@ namespace Inkscape { DrawingGroup::DrawingGroup(Drawing &drawing) : DrawingItem(drawing) - , _style(NULL) , _child_transform(NULL) {} DrawingGroup::~DrawingGroup() { - if (_style) - sp_style_unref(_style); delete _child_transform; // delete NULL; is safe } @@ -42,12 +39,6 @@ DrawingGroup::setPickChildren(bool p) _pick_children = p; } -void -DrawingGroup::setStyle(SPStyle *style) -{ - _setStyleCommon(_style, style); -} - /** * Set additional transform for the group. * This is applied after the normal transform and mainly useful for diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h index ab1f9895d..0c985b43f 100644 --- a/src/display/drawing-group.h +++ b/src/display/drawing-group.h @@ -14,8 +14,6 @@ #include "display/drawing-item.h" -class SPStyle; - namespace Inkscape { class DrawingGroup @@ -28,7 +26,6 @@ public: bool pickChildren() { return _pick_children; } void setPickChildren(bool p); - void setStyle(SPStyle *style); void setChildTransform(Geom::Affine const &new_trans); protected: @@ -40,7 +37,6 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); - SPStyle *_style; Geom::Affine *_child_transform; }; diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index e56f3e58b..8fe337959 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -24,15 +24,10 @@ namespace Inkscape { DrawingImage::DrawingImage(Drawing &drawing) : DrawingItem(drawing) , _pixbuf(NULL) - , _style(NULL) {} DrawingImage::~DrawingImage() { - if (_style) { - sp_style_unref(_style); - } - // _pixbuf is owned by SPImage - do not delete it } @@ -45,12 +40,6 @@ DrawingImage::setPixbuf(Inkscape::Pixbuf *pb) } void -DrawingImage::setStyle(SPStyle *style) -{ - _setStyleCommon(_style, style); -} - -void DrawingImage::setScale(double sx, double sy) { _scale = Geom::Scale(sx, sy); diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h index 64e4517b0..7511768c9 100644 --- a/src/display/drawing-image.h +++ b/src/display/drawing-image.h @@ -29,7 +29,6 @@ public: ~DrawingImage(); void setPixbuf(Inkscape::Pixbuf *pb); - void setStyle(SPStyle *style); void setScale(double sx, double sy); void setOrigin(Geom::Point const &o); void setClipbox(Geom::Rect const &box); @@ -43,7 +42,6 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); Inkscape::Pixbuf *_pixbuf; - SPStyle *_style; // TODO: the following three should probably be merged into a new Geom::Viewbox object Geom::Rect _clipbox; ///< for preserveAspectRatio diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 8ed74b550..89ca66dc4 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -109,6 +109,8 @@ DrawingItem::DrawingItem(Drawing &drawing) : _drawing(drawing) , _parent(NULL) , _key(0) + , _style(NULL) + , _context_style(NULL) , _opacity(1.0) , _transform(NULL) , _clip(NULL) @@ -188,6 +190,8 @@ DrawingItem::~DrawingItem() delete _clip; delete _mask; delete _filter; + if(_style) + sp_style_unref(_style); } DrawingItem * @@ -351,6 +355,72 @@ DrawingItem::setCached(bool cached, bool persistent) } } +/** + * Process information related to the new style. + * + * Note: _style is not used by DrawingGlyphs which uses its parent style. + */ +void +DrawingItem::setStyle(SPStyle *style, SPStyle *context_style) +{ + // std::cout << "DrawingItem::setStyle: " << name() << " " << style + // << " " << context_style << std::endl; + + if( style != _style ) { + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; + } + + if (style && style->filter.set && style->getFilter()) { + if (!_filter) { + int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); + _filter = new Inkscape::Filters::Filter(primitives); + } + sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); + } else { + // no filter set for this group + delete _filter; + _filter = NULL; + } + + if (style && style->enable_background.set) { + if (style->enable_background.value == SP_CSS_BACKGROUND_NEW && !_background_new) { + _background_new = true; + _markForUpdate(STATE_BACKGROUND, true); + } else if (style->enable_background.value == SP_CSS_BACKGROUND_ACCUMULATE && _background_new) { + _background_new = false; + _markForUpdate(STATE_BACKGROUND, true); + } + } + + if (context_style != NULL) { + _context_style = context_style; + } else if (_parent != NULL) { + _context_style = _parent->_context_style; + } + + _markForUpdate(STATE_ALL, false); +} + + +/** + * Recursively update children style. + * The purpose of this call is to update fill and stroke for markers that have elements with + * fill/stroke property values of 'context-fill' or 'context-stroke'. Marker styling is not + * updated like other 'clones' as marker instances are not included the SP object tree. + * Note: this is a virtual function. + */ +void +DrawingItem::setChildrenStyle(SPStyle* context_style) +{ + _context_style = context_style; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->setChildrenStyle( context_style ); + } +} + + void DrawingItem::setClip(DrawingItem *item) { @@ -908,6 +978,39 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) return NULL; } +// For debugging +Glib::ustring +DrawingItem::name() +{ + SPObject *object = static_cast<SPObject *>(_user_data); + if (object) { + if(object->getId()) + return object->getId(); + else + return "No object id"; + } else { + return "No associated object"; + } +} + +// For debugging: Print drawing tree structure. +void +DrawingItem::recursivePrintTree( unsigned level ) +{ + if (level == 0) { + std::cout << "Display Item Tree" << std::endl; + } + std::cout << "DI: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + std::cout << name() << std::endl; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->recursivePrintTree( level+1 ); + } +} + + /** * Marks the current visual bounding box of the item for redrawing. * This is called whenever the object changes its visible appearance. @@ -998,48 +1101,6 @@ DrawingItem::_markForUpdate(unsigned flags, bool propagate) } /** - * Process information related to the new style. - * - * This function is something of a hack to avoid creating an extra class in the hierarchy - * which would differ from DrawingItem only by having a _style member. - * This is mainly to the benefit of DrawingGlyphs, which use the style of their parent. - * This should probably be refactored some day, possibly by creating the relevant class - * or creating a more complex data model in DrawingText and removing DrawingGlyphs, - * which would cause every item to have a style. - */ -void -DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) -{ - if (style) sp_style_ref(style); - if (_style) sp_style_unref(_style); - _style = style; - - if (style && style->filter.set && style->getFilter()) { - if (!_filter) { - int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - _filter = new Inkscape::Filters::Filter(primitives); - } - sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); - } else { - // no filter set for this group - delete _filter; - _filter = NULL; - } - - if (style && style->enable_background.set) { - if (style->enable_background.value == SP_CSS_BACKGROUND_NEW && !_background_new) { - _background_new = true; - _markForUpdate(STATE_BACKGROUND, true); - } else if (style->enable_background.value == SP_CSS_BACKGROUND_ACCUMULATE && _background_new) { - _background_new = false; - _markForUpdate(STATE_BACKGROUND, true); - } - } - - _markForUpdate(STATE_ALL, false); -} - -/** * Compute the caching score. * * Higher scores mean the item is more aggresively prioritized for automatic diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 9b399e6e3..3c593ceaa 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -20,6 +20,10 @@ #include <exception> #include <list> +namespace Glib { +class ustring; +} + class SPStyle; namespace Inkscape { @@ -108,6 +112,8 @@ public: bool cached() const { return _cached; } void setCached(bool c, bool persistent = false); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); void setOpacity(float opacity); void setAntialiasing(bool a); void setIsolation(unsigned isolation); // CSS Compositing and Blending @@ -131,6 +137,9 @@ public: void clip(DrawingContext &dc, Geom::IntRect const &area); DrawingItem *pick(Geom::Point const &p, double delta, unsigned flags = 0); + virtual Glib::ustring name(); // For debugging + void recursivePrintTree(unsigned level = 0); // For debugging + protected: enum ChildType { CHILD_ORPHAN = 0, // no parent - implies _parent == NULL @@ -149,7 +158,6 @@ protected: void _markForUpdate(unsigned state, bool propagate); void _markForRendering(); void _invalidateFilterBackground(Geom::IntRect const &area); - void _setStyleCommon(SPStyle *&_style, SPStyle *style); double _cacheScore(); Geom::OptIntRect _cacheRect(); virtual unsigned _updateItem(Geom::IntRect const &/*area*/, UpdateContext const &/*ctx*/, @@ -176,6 +184,9 @@ protected: unsigned _key; ///< Some SPItems can have more than one DrawingItem; /// this value is a hack used to distinguish between them + SPStyle *_style; // Not used by DrawingGlyphs + SPStyle *_context_style; // Used for 'context-fill', 'context-stroke' + float _opacity; Geom::Affine *_transform; ///< Incremental transform from parent to this item's coords diff --git a/src/display/drawing-pattern.cpp b/src/display/drawing-pattern.cpp index cf6358278..d0bf5de58 100644 --- a/src/display/drawing-pattern.cpp +++ b/src/display/drawing-pattern.cpp @@ -149,8 +149,8 @@ DrawingPattern::renderPattern(float opacity) { return cp; } -unsigned -DrawingPattern::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +// TODO investigate if area should be used. +unsigned DrawingPattern::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) { UpdateContext pattern_ctx; diff --git a/src/display/drawing-pattern.h b/src/display/drawing-pattern.h index 7483ba067..dc1f93ed1 100644 --- a/src/display/drawing-pattern.h +++ b/src/display/drawing-pattern.h @@ -15,7 +15,6 @@ #include "display/drawing-group.h" typedef struct _cairo_pattern cairo_pattern_t; -class SPStyle; namespace Inkscape { diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 66160638f..63efb3c0d 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -34,15 +34,12 @@ namespace Inkscape { DrawingShape::DrawingShape(Drawing &drawing) : DrawingItem(drawing) , _curve(NULL) - , _style(NULL) , _last_pick(NULL) , _repick_after(0) {} DrawingShape::~DrawingShape() { - if (_style) - sp_style_unref(_style); if (_curve) _curve->unref(); } @@ -65,10 +62,17 @@ DrawingShape::setPath(SPCurve *curve) } void -DrawingShape::setStyle(SPStyle *style) +DrawingShape::setStyle(SPStyle *style, SPStyle *context_style) { - _setStyleCommon(_style, style); - _nrstyle.set(style); + DrawingItem::setStyle(style, context_style); // Must be first + _nrstyle.set(_style, _context_style); +} + +void +DrawingShape::setChildrenStyle(SPStyle* context_style) +{ + DrawingItem::setChildrenStyle( context_style ); + _nrstyle.set(_style, _context_style); } unsigned @@ -145,7 +149,6 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u _bbox.unionWith(i->geometricBounds()); } } - return STATE_ALL; } diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index 9d93a642f..1cdbc636e 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -28,7 +28,8 @@ public: ~DrawingShape(); void setPath(SPCurve *curve); - void setStyle(SPStyle *style); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); protected: virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, @@ -45,7 +46,6 @@ protected: DrawingItem *stop_at); SPCurve *_curve; - SPStyle *_style; NRStyle _nrstyle; DrawingItem *_last_pick; diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index afe661b2e..e20a7ff2a 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -55,6 +55,13 @@ DrawingGlyphs::setGlyph(font_instance *font, int glyph, Geom::Affine const &tran _markForUpdate(STATE_ALL, false); } +void +DrawingGlyphs::setStyle(SPStyle * /*style*/, SPStyle * /*context_style*/) +{ + std::cerr << "DrawingGlyphs: Use parent style" << std::endl; +} + + unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext const &ctx, unsigned /*flags*/, unsigned /*reset*/) { DrawingText *ggroup = dynamic_cast<DrawingText *>(_parent); @@ -216,10 +223,17 @@ DrawingText::addComponent(font_instance *font, int glyph, Geom::Affine const &tr } void -DrawingText::setStyle(SPStyle *style) +DrawingText::setStyle(SPStyle *style, SPStyle *context_style) +{ + DrawingGroup::setStyle(style, context_style); // Must be first + _nrstyle.set(_style, _context_style); +} + +void +DrawingText::setChildrenStyle(SPStyle* context_style) { - _nrstyle.set(style); - DrawingGroup::setStyle(style); + DrawingGroup::setChildrenStyle( context_style ); + _nrstyle.set(_style, _context_style); } unsigned diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index 4453a3db4..3d248df9b 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -28,6 +28,7 @@ public: ~DrawingGlyphs(); void setGlyph(font_instance *font, int glyph, Geom::Affine const &trans); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); // Not to be used protected: unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, @@ -56,8 +57,8 @@ public: void clear(); bool addComponent(font_instance *font, int glyph, Geom::Affine const &trans, float width, float ascent, float descent, float phase_length); - void setStyle(SPStyle *style); - + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); protected: virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index b065ac445..c8b569036 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -17,7 +17,7 @@ #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "sp-root.h" #include "style.h" @@ -171,9 +171,11 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) void FilterPrimitive::setStyle(SPStyle *style) { - if (style) sp_style_ref(style); - if (_style) sp_style_unref(_style); - _style = style; + if( style != _style ) { + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; + } } diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index a2a8c5756..19dedb67c 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -64,8 +64,10 @@ public: for (i = 0; i < BSize; ++i) { _latticeSelector[i] = i; - _gradient[i][k][0] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; - _gradient[i][k][1] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + do { + _gradient[i][k][0] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + _gradient[i][k][1] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + } while(_gradient[i][k][0] == 0 && _gradient[i][k][1] == 0); // normalize gradient double s = hypot(_gradient[i][k][0], _gradient[i][k][1]); diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 96d16bf06..1740785e2 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -93,24 +93,47 @@ NRStyle::~NRStyle() text_decoration_stroke.clear(); } -void NRStyle::set(SPStyle *style) +void NRStyle::set(SPStyle *style, SPStyle *context_style) { - if ( style->fill.isPaintserver() ) { + // Handle 'context-fill' and 'context-stroke': Work in progress + const SPIPaint *style_fill = &(style->fill); + if( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if( context_style != NULL ) { + style_fill = &(context_style->fill); + } else { + // A marker in the defs section will result in ending up here. + //std::cerr << "NRStyle::set: 'context-fill': 'context_style' is NULL" << std::endl; + } + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if( context_style != NULL ) { + style_fill = &(context_style->stroke); + } else { + //std::cerr << "NRStyle::set: 'context-stroke': 'context_style' is NULL" << std::endl; + } + } + + if ( style_fill->isPaintserver() ) { SPPaintServer* server = style->getFillPaintServer(); if ( server && server->isValid() ) { fill.set(server); - } else if ( style->fill.colorSet ) { - fill.set(style->fill.value.color); + } else if ( style_fill->colorSet ) { + fill.set(style_fill->value.color); } else { fill.clear(); } - } else if ( style->fill.isColor() ) { - fill.set(style->fill.value.color); - } else if ( style->fill.isNone() ) { + } else if ( style_fill->isColor() ) { + fill.set(style_fill->value.color); + } else if ( style_fill->isNone() ) { fill.clear(); + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + // A marker in the defs section will result in ending up here. + //std::cerr << "NRStyle::set: fill: context-fill: Double" << std::endl; + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + //std::cerr << "NRStyle::set: fill: context-stroke: Double" << std::endl; } else { g_assert_not_reached(); } + fill.opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value); switch (style->fill_rule.computed) { @@ -124,22 +147,42 @@ void NRStyle::set(SPStyle *style) g_assert_not_reached(); } - if ( style->stroke.isPaintserver() ) { + const SPIPaint *style_stroke = &(style->stroke); + if( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if( context_style != NULL ) { + style_stroke = &(context_style->fill); + } else { + //std::cerr << "NRStyle::set: 'context-fill': 'context_style' is NULL" << std::endl; + } + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if( context_style != NULL ) { + style_stroke = &(context_style->stroke); + } else { + //std::cerr << "NRStyle::set: 'context-stroke': 'context_style' is NULL" << std::endl; + } + } + + if ( style_stroke->isPaintserver() ) { SPPaintServer* server = style->getStrokePaintServer(); if ( server && server->isValid() ) { stroke.set(server); - } else if ( style->stroke.isColor() ) { - stroke.set(style->stroke.colorSet); + } else if ( style_stroke->isColor() ) { + stroke.set(style_stroke->colorSet); } else { stroke.clear(); } - } else if ( style->stroke.isColor() ) { - stroke.set(style->stroke.value.color); - } else if ( style->stroke.isNone() ) { + } else if ( style_stroke->isColor() ) { + stroke.set(style_stroke->value.color); + } else if ( style_stroke->isNone() ) { stroke.clear(); + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + //std::cerr << "NRStyle::set: stroke: context-fill: Double" << std::endl; + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + //std::cerr << "NRStyle::set: stroke: context-stroke: Double" << std::endl; } else { g_assert_not_reached(); } + stroke.opacity = SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); stroke_width = style->stroke_width.computed; switch (style->stroke_linecap.computed) { @@ -266,7 +309,7 @@ void NRStyle::set(SPStyle *style) } else if ( style_td->fill.isNone() ) { text_decoration_fill.clear(); } else { - g_assert_not_reached(); + //g_assert_not_reached(); } if ( style_td->stroke.isPaintserver() ) { @@ -276,7 +319,7 @@ void NRStyle::set(SPStyle *style) } else if ( style_td->stroke.isNone() ) { text_decoration_stroke.clear(); } else { - g_assert_not_reached(); + //g_assert_not_reached(); } } @@ -310,13 +353,16 @@ bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &pai fill_pattern = pattern->renderPattern(fill.opacity); } else { fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); - } break; + } + break; case PAINT_COLOR: { SPColor const &c = fill.color; fill_pattern = cairo_pattern_create_rgba( c.v.c[0], c.v.c[1], c.v.c[2], fill.opacity); - } break; - default: break; + } + break; + default: + break; } } if (!fill_pattern) return false; diff --git a/src/display/nr-style.h b/src/display/nr-style.h index f324fdb56..5f78795d3 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -1,6 +1,7 @@ /** * @file * Style information for rendering. + * Only used by classes DrawingShape and DrawingText *//* * Authors: * Krzysztof Kosiński <tweenk.pl@gmail.com> @@ -28,7 +29,7 @@ struct NRStyle { NRStyle(); ~NRStyle(); - void set(SPStyle *); + void set(SPStyle *style, SPStyle *context_style = NULL); bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); bool prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 84b4bd080..011f51977 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -4,6 +4,7 @@ * * Authors: * Felipe C. da S. Sanches <juca@members.fsf.org> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * @@ -32,9 +33,9 @@ #include "sp-font.h" #include "sp-glyph-kerning.h" -//*************************// +// ************************// // UserFont Implementation // -//*************************// +// ************************// // I wrote this binding code because Cairomm does not yet support userfonts. I have moved this code to cairomm and sent them a patch. // Once Cairomm incorporate the UserFonts binding, this code should be removed from inkscape and Cairomm API should be used. @@ -111,16 +112,38 @@ unsigned int size_of_substring(const char* substring, gchar* str){ return 0; } -//TODO: in these macros, verify what happens when using unicode strings. -#define Match_VKerning_Rule ((SP_VKERN(node))->u1->contains(previous_unicode[0])\ - || (SP_VKERN(node))->g1->contains(previous_glyph_name)) &&\ - ((SP_VKERN(node))->u2->contains(this->glyphs[i]->unicode[0])\ - || (SP_VKERN(node))->g2->contains(this->glyphs[i]->glyph_name.c_str())) -#define Match_HKerning_Rule ((SP_HKERN(node))->u1->contains(previous_unicode[0])\ - || (SP_HKERN(node))->g1->contains(previous_glyph_name)) &&\ - ((SP_HKERN(node))->u2->contains(this->glyphs[i]->unicode[0])\ - || (SP_HKERN(node))->g2->contains(this->glyphs[i]->glyph_name.c_str())) +namespace { + +//TODO: in these functions, verify what happens when using unicode strings. + +bool MatchVKerningRule(SPVkern const *vkern, + SPGlyph *glyph, + char const *previous_unicode, + gchar const *previous_glyph_name) +{ + bool value = (vkern->u1->contains(previous_unicode[0]) + || vkern->g1->contains(previous_glyph_name)) + && (vkern->u2->contains(glyph->unicode[0]) + || vkern->g2->contains(glyph->glyph_name.c_str())); + + return value; +} + +bool MatchHKerningRule(SPHkern const *hkern, + SPGlyph *glyph, + char const *previous_unicode, + gchar const *previous_glyph_name) +{ + bool value = (hkern->u1->contains(previous_unicode[0]) + || hkern->g1->contains(previous_glyph_name)) + && (hkern->u2->contains(glyph->unicode[0]) + || hkern->g2->contains(glyph->glyph_name.c_str())); + + return value; +} + +} // namespace cairo_status_t SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/, @@ -182,11 +205,13 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/, if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){ for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ //apply glyph kerning if appropriate - if (SP_IS_HKERN(node) && is_horizontal_text && Match_HKerning_Rule ){ - x -= ((SP_HKERN(node))->k / 1000.0);//TODO: use here the height of the font + SPHkern *hkern = dynamic_cast<SPHkern *>(node); + if (hkern && is_horizontal_text && MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + x -= (hkern->k / 1000.0);//TODO: use here the height of the font } - if (SP_IS_VKERN(node) && !is_horizontal_text && Match_VKerning_Rule ){ - y -= ((SP_VKERN(node))->k / 1000.0);//TODO: use here the "height" of the font + SPVkern *vkern = dynamic_cast<SPVkern *>(node); + if (vkern && !is_horizontal_text && MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + y -= (vkern->k / 1000.0);//TODO: use here the "height" of the font } } previous_unicode = const_cast<char*>(this->glyphs[i]->unicode.c_str());//used for kerning checking @@ -246,9 +271,8 @@ SvgFont::glyph_modified(SPObject* /* blah */, unsigned int /* bleh */){ Geom::PathVector SvgFont::flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv){ double units_per_em = 1000; - SPObject* obj; - for (obj = (SP_OBJECT(spfont))->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ + for (SPObject *obj = spfont->children; obj; obj = obj->next){ + if (dynamic_cast<SPFontFace *>(obj)) { //XML Tree being directly used here while it shouldn't be. sp_repr_get_double(obj->getRepr(), "units_per_em", &units_per_em); } @@ -275,19 +299,21 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, if (glyph > this->glyphs.size()) return CAIRO_STATUS_SUCCESS;//TODO: this is an error! - SPObject* node; - if (glyph == this->glyphs.size()){ - if (!this->missingglyph) return CAIRO_STATUS_SUCCESS; - node = SP_OBJECT(this->missingglyph); + SPObject *node = NULL; + if (glyph == glyphs.size()){ + if (!missingglyph) { + return CAIRO_STATUS_SUCCESS; + } + node = missingglyph; } else { - node = SP_OBJECT(this->glyphs[glyph]); + node = glyphs[glyph]; } - if (!SP_IS_GLYPH(node) && !SP_IS_MISSING_GLYPH(node)) { + if (!dynamic_cast<SPGlyph *>(node) && !dynamic_cast<SPMissingGlyph *>(node)) { return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return? } - SPFont* spfont = SP_FONT(node->parent); + SPFont* spfont = dynamic_cast<SPFont *>(node->parent); if (!spfont) { return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return? } @@ -296,36 +322,48 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, // or using the d attribute of a glyph node. // pathv stores the path description from the d attribute: Geom::PathVector pathv; - if (SP_IS_GLYPH(node) && (SP_GLYPH(node))->d) { - pathv = sp_svg_read_pathv((SP_GLYPH(node))->d); - pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); - } else if (SP_IS_MISSING_GLYPH(node) && (SP_MISSING_GLYPH(node))->d) { - pathv = sp_svg_read_pathv((SP_MISSING_GLYPH(node))->d); + + SPGlyph *glyphNode = dynamic_cast<SPGlyph *>(node); + if (glyphNode && glyphNode->d) { + pathv = sp_svg_read_pathv(glyphNode->d); pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); + render_glyph_path(cr, &pathv); + } else { + SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(node); + if (missing && missing->d) { + pathv = sp_svg_read_pathv(missing->d); + pathv = flip_coordinate_system(spfont, pathv); + render_glyph_path(cr, &pathv); + } } if (node->hasChildren()){ //render the SVG described on this glyph's child nodes. for(node = node->children; node; node=node->next){ - if (SP_IS_PATH(node)){ - pathv = (SP_SHAPE(node))->_curve->get_pathvector(); - pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); + { + SPPath *path = dynamic_cast<SPPath *>(node); + if (path) { + pathv = path->_curve->get_pathvector(); + pathv = flip_coordinate_system(spfont, pathv); + render_glyph_path(cr, &pathv); + } } - if (SP_IS_OBJECTGROUP(node)){ + if (dynamic_cast<SPObjectGroup *>(node)) { g_warning("TODO: svgfonts: render OBJECTGROUP"); } - if (SP_IS_USE(node)){ - SPItem* item = SP_USE(node)->ref->getObject(); - if (SP_IS_PATH(item)){ - pathv = (SP_SHAPE(item))->_curve->get_pathvector(); + SPUse *use = dynamic_cast<SPUse *>(node); + if (use) { + SPItem* item = use->ref->getObject(); + SPPath *path = dynamic_cast<SPPath *>(item); + if (path) { + SPShape *shape = dynamic_cast<SPShape *>(item); + g_assert(shape != NULL); + pathv = shape->_curve->get_pathvector(); pathv = flip_coordinate_system(spfont, pathv); this->render_glyph_path(cr, &pathv); } - glyph_modified_connection = (SP_OBJECT(item))->connectModified(sigc::mem_fun(*this, &SvgFont::glyph_modified)); + glyph_modified_connection = item->connectModified(sigc::mem_fun(*this, &SvgFont::glyph_modified)); } } } @@ -337,11 +375,13 @@ cairo_font_face_t* SvgFont::get_font_face(){ if (!this->userfont) { for(SPObject* node = this->font->children;node;node=node->next){ - if (SP_IS_GLYPH(node)){ - this->glyphs.push_back(SP_GLYPH(node)); + SPGlyph *glyph = dynamic_cast<SPGlyph *>(node); + if (glyph) { + glyphs.push_back(glyph); } - if (SP_IS_MISSING_GLYPH(node)){ - this->missingglyph=SP_MISSING_GLYPH(node); + SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(node); + if (missing) { + missingglyph = missing; } } this->userfont = new UserFont(this); diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 2632d69db..bcce81f0b 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -14,7 +14,7 @@ #include "display/snap-indicator.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrl.h" #include "display/sodipodi-ctrlrect.h" #include "display/canvas-text.h" @@ -246,7 +246,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap // Display the snap indicator (i.e. the cross) SPCanvasItem * canvasitem = NULL; - canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + canvasitem = sp_canvas_item_new(_desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 10.0, @@ -280,7 +280,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap tooltip_pos += _desktop->w2d(Geom::Point(0, -2*fontsize)); } - SPCanvasItem *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(_desktop), _desktop, tooltip_pos, tooltip_str); + SPCanvasItem *canvas_tooltip = sp_canvastext_new(_desktop->getTempGroup(), _desktop, tooltip_pos, tooltip_str); sp_canvastext_set_fontsize(SP_CANVASTEXT(canvas_tooltip), fontsize); SP_CANVASTEXT(canvas_tooltip)->rgba = 0xffffffff; SP_CANVASTEXT(canvas_tooltip)->outline = false; @@ -299,7 +299,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap // Display the bounding box, if we snapped to one Geom::OptRect const bbox = p.getTargetBBox(); if (bbox) { - SPCanvasItem* box = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + SPCanvasItem* box = sp_canvas_item_new(_desktop->getTempGroup(), SP_TYPE_CTRLRECT, NULL); @@ -348,7 +348,7 @@ SnapIndicator::set_new_snapsource(Inkscape::SnapCandidatePoint const &p) bool value = prefs->getBool("/options/snapindicator/value", true); if (value) { - SPCanvasItem * canvasitem = sp_canvas_item_new( sp_desktop_tempgroup (_desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new( _desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 6.0, @@ -367,7 +367,7 @@ void SnapIndicator::set_new_debugging_point(Geom::Point const &p) { g_assert(_desktop != NULL); - SPCanvasItem * canvasitem = sp_canvas_item_new( sp_desktop_tempgroup (_desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new( _desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 10.0, diff --git a/src/document-private.h b/src/document-private.h index 8e28b288b..a5033b3c2 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -75,6 +75,8 @@ struct SPDocumentPrivate { Inkscape::ConsoleOutputUndoObserver console_output_undo_observer; bool seeking; + sigc::connection selChangeConnection; + sigc::connection desktopActivatedConnection; }; #endif // SEEN_SP_DOCUMENT_PRIVATE_H diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 15d5d2c70..d4015bafb 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -99,9 +99,8 @@ void Inkscape::DocumentUndo::done(SPDocument *doc, const unsigned int event_type maybeDone(doc, NULL, event_type, event_description); } -void Inkscape::DocumentUndo::resetKey( InkscapeApplication * /*inkscape*/, SPDesktop * /*desktop*/, GObject *base ) +void Inkscape::DocumentUndo::resetKey( SPDocument *doc ) { - SPDocument *doc = reinterpret_cast<SPDocument *>(base); doc->actionkey.clear(); } @@ -259,7 +258,7 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) doc->priv->seeking = false; if (ret) - inkscape_external_change(); + INKSCAPE.external_change(); return ret; } @@ -304,7 +303,7 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) doc->priv->seeking = false; if (ret) - inkscape_external_change(); + INKSCAPE.external_change(); return ret; } diff --git a/src/document-undo.h b/src/document-undo.h index 17b3de252..85b44d562 100644 --- a/src/document-undo.h +++ b/src/document-undo.h @@ -41,7 +41,7 @@ public: static void maybeDone(SPDocument *document, const gchar *keyconst, unsigned int event_type, Glib::ustring const &event_description); - static void resetKey(InkscapeApplication *inkscape, SPDesktop *desktop, GObject *base); + static void resetKey(SPDocument *doc); static void cancel(SPDocument *document); diff --git a/src/document.cpp b/src/document.cpp index e5b827937..2caefb4ed 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -50,7 +50,7 @@ #include "document-private.h" #include "document-undo.h" #include "id-clash.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "inkscape-version.h" #include "libavoid/router.h" #include "persp3d.h" @@ -154,6 +154,14 @@ SPDocument::~SPDocument() { router = NULL; } + if (oldSignalsConnected) { + priv->selChangeConnection.disconnect(); + priv->desktopActivatedConnection.disconnect(); + } else { + _selection_changed_connection.disconnect(); + _desktop_activated_connection.disconnect(); + } + if (priv) { if (priv->partial) { sp_repr_free_log(priv->partial); @@ -208,17 +216,8 @@ SPDocument::~SPDocument() { rerouting_handler_id = 0; } - if (oldSignalsConnected) { - g_signal_handlers_disconnect_by_func(G_OBJECT(INKSCAPE), - reinterpret_cast<gpointer>(DocumentUndo::resetKey), - static_cast<gpointer>(this)); - } else { - _selection_changed_connection.disconnect(); - _desktop_activated_connection.disconnect(); - } - if (keepalive) { - inkscape_unref(); + inkscape_unref(INKSCAPE); keepalive = FALSE; } @@ -447,7 +446,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, rdf_set_defaults( document ); if (keepalive) { - inkscape_ref(); + inkscape_ref(INKSCAPE); } // Check if the document already has a perspective (e.g., when opening an existing @@ -462,10 +461,14 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, DocumentUndo::setUndoSensitive(document, true); // reset undo key when selection changes, so that same-key actions on different objects are not coalesced - g_signal_connect(G_OBJECT(INKSCAPE), "change_selection", - G_CALLBACK(DocumentUndo::resetKey), document); - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", - G_CALLBACK(DocumentUndo::resetKey), document); + document->priv->selChangeConnection = INKSCAPE.signal_selection_changed.connect( + sigc::hide(sigc::bind( + sigc::ptr_fun(&DocumentUndo::resetKey), document) + )); + document->priv->desktopActivatedConnection = INKSCAPE.signal_activate_desktop.connect( + sigc::hide(sigc::bind( + sigc::ptr_fun(&DocumentUndo::resetKey), document) + )); document->oldSignalsConnected = true; return document; @@ -593,10 +596,67 @@ SPDocument *SPDocument::doUnref() } /// guaranteed not to return nullptr -Inkscape::Util::Unit const* SPDocument::getDefaultUnit() const +Inkscape::Util::Unit const* SPDocument::getDisplayUnit() const +{ + SPNamedView const* nv = sp_document_namedview(this, NULL); + return nv ? nv->getDisplayUnit() : unit_table.getUnit("px"); +} + +/// guaranteed not to return nullptr +// returns 'px' units as default, like legacy Inkscape +// THIS SHOULD NOT BE USED... INSTEAD USE DOCUMENT SCALE +Inkscape::Util::Unit const& SPDocument::getSVGUnit() const { SPNamedView const* nv = sp_document_namedview(this, NULL); - return nv ? nv->getDefaultUnit() : unit_table.getUnit("pt"); + return nv ? nv->getSVGUnit() : *unit_table.getUnit("px"); +} + +/// Returns document scale as defined by width/height and viewBox (real world to user-units). +Geom::Scale SPDocument::getDocumentScale() const +{ + Geom::Scale scale; + if( root->viewBox_set ) { + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox.width() > 0.0 ) { + scale_x = root->width.computed / root->viewBox.width(); + } + if( root->viewBox.height() > 0.0 ) { + scale_y = root->height.computed / root->viewBox.height(); + } + scale = Geom::Scale(scale_x, scale_y); + } + // std::cout << "SPDocument::getDocumentScale():\n" << scale << std::endl; + return scale; +} + +// Avoid calling root->updateRepr() twice by combining setting width and height. +// (As done on every delete as clipboard calls this via fitToRect(). Also called in page-sizer.cpp) +void SPDocument::setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize) +{ + Inkscape::Util::Unit const *old_width_units = unit_table.getUnit("px"); + if (root->width.unit) + old_width_units = unit_table.getUnit(root->width.unit); + gdouble old_width_converted = Inkscape::Util::Quantity::convert(root->width.value, old_width_units, width.unit); + + root->width.computed = width.value("px"); + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); + + Inkscape::Util::Unit const *old_height_units = unit_table.getUnit("px"); + if (root->height.unit) + old_height_units = unit_table.getUnit(root->height.unit); + gdouble old_height_converted = Inkscape::Util::Quantity::convert(root->height.value, old_height_units, height.unit); + + root->height.computed = height.value("px"); + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); + + if (root->viewBox_set && changeSize) + root->viewBox.setMax(Geom::Point( + root->viewBox.left() + (root->width.value / old_width_converted ) * root->viewBox.width(), + root->viewBox.top() + (root->height.value / old_height_converted) * root->viewBox.height())); + root->updateRepr(); } Inkscape::Util::Quantity SPDocument::getWidth() const @@ -616,24 +676,18 @@ Inkscape::Util::Quantity SPDocument::getWidth() const return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); } -void SPDocument::setWidth(const Inkscape::Util::Quantity &width) +void SPDocument::setWidth(const Inkscape::Util::Quantity &width, bool changeSize) { Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); if (root->width.unit) old_units = unit_table.getUnit(root->width.unit); gdouble old_converted = Inkscape::Util::Quantity::convert(root->width.value, old_units, width.unit); + root->width.computed = width.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*width.unit == *unit_table.getUnit("m")) { - root->width.value = width.value("cm"); - root->width.unit = SVGLength::CM; - } else { - root->width.value = width.quantity; - root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - } + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - if (root->viewBox_set) + if (root->viewBox_set && changeSize) root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_converted) * root->viewBox.width(), root->viewBox.bottom())); root->updateRepr(); @@ -657,24 +711,18 @@ Inkscape::Util::Quantity SPDocument::getHeight() const return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); } -void SPDocument::setHeight(const Inkscape::Util::Quantity &height) +void SPDocument::setHeight(const Inkscape::Util::Quantity &height, bool changeSize) { Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); if (root->height.unit) old_units = unit_table.getUnit(root->height.unit); gdouble old_converted = Inkscape::Util::Quantity::convert(root->height.value, old_units, height.unit); + root->height.computed = height.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*height.unit == *unit_table.getUnit("m")) { - root->height.value = height.value("cm"); - root->height.unit = SVGLength::CM; - } else { - root->height.value = height.quantity; - root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - } + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - if (root->viewBox_set) + if (root->viewBox_set && changeSize) root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_converted) * root->viewBox.height())); root->updateRepr(); @@ -713,11 +761,9 @@ void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins) double const old_height = getHeight().value("px"); Inkscape::Util::Unit const *nv_units = unit_table.getUnit("px"); + if (root->height.unit) + nv_units = unit_table.getUnit(root->height.unit); SPNamedView *nv = sp_document_namedview(this, NULL); - if (nv != NULL) { - if (nv->getAttribute("units")) - nv_units = unit_table.getUnit(nv->getAttribute("units")); - } /* in px */ double margin_top = 0.0; @@ -742,9 +788,10 @@ void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins) rect.min() - Geom::Point(margin_left, margin_bottom), rect.max() + Geom::Point(margin_right, margin_top)); - - setWidth(Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.width(), "px", nv_units), nv_units)); - setHeight(Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.height(), "px", nv_units), nv_units)); + setWidthAndHeight( + Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.width(), "px", nv_units), nv_units), + Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.height(), "px", nv_units), nv_units) + ); Geom::Translate const tr( Geom::Point(0, old_height - rect_with_margins.height()) diff --git a/src/document.h b/src/document.h index 4ace249ae..22c341eae 100644 --- a/src/document.h +++ b/src/document.h @@ -38,7 +38,6 @@ class SPGroup; class SPRoot; namespace Inkscape { - struct Application; class Selection; class UndoStackObserver; class EventLog; @@ -241,13 +240,16 @@ public: SPDocument *doRef(); SPDocument *doUnref(); - Inkscape::Util::Unit const* getDefaultUnit() const; + Inkscape::Util::Unit const* getDisplayUnit() const; + Inkscape::Util::Unit const& getSVGUnit() const; + Geom::Scale getDocumentScale() const; Inkscape::Util::Quantity getWidth() const; Inkscape::Util::Quantity getHeight() const; Geom::Point getDimensions() const; Geom::OptRect preferredBounds() const; - void setWidth(const Inkscape::Util::Quantity &width); - void setHeight(const Inkscape::Util::Quantity &height); + void setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize=true); + void setWidth(const Inkscape::Util::Quantity &width, bool changeSize=true); + void setHeight(const Inkscape::Util::Quantity &height, bool changeSize=true); void setViewBox(const Geom::Rect &viewBox); void requestModified(); int ensureUpToDate(); diff --git a/src/extension/dbus/application-interface.cpp b/src/extension/dbus/application-interface.cpp index c0bc19d90..afaf9aedf 100644 --- a/src/extension/dbus/application-interface.cpp +++ b/src/extension/dbus/application-interface.cpp @@ -49,7 +49,7 @@ application_interface_init (ApplicationInterface *app_interface) static bool ensure_desktop_valid(GError **error) { - if (!inkscape_use_gui()) { + if (!INKSCAPE.use_gui()) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires a GUI"); return false; } @@ -59,7 +59,7 @@ ensure_desktop_valid(GError **error) static bool ensure_desktop_not_present(GError **error) { - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires non-GUI (command line) mode"); return false; } @@ -196,7 +196,7 @@ application_interface_document_close_all (ApplicationInterface *app_interface, SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_assert(doc != NULL); Inkscape::XML::Node *repr = doc->getReprRoot(); diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index 19b48e10d..43830762c 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -153,23 +153,23 @@ gchar * init_document (void) { // This is for command-line use only - g_assert(!inkscape_use_gui()); + g_assert(!INKSCAPE.use_gui()); // Create a blank document and get its selection model etc in an ActionContext SPDocument *doc = SPDocument::createNewDoc(NULL, 1, TRUE); - inkscape_add_document(doc); - return dbus_register_document(inkscape_action_context_for_document(doc)); + INKSCAPE.add_document(doc); + return dbus_register_document(INKSCAPE.action_context_for_document(doc)); } gchar * init_active_document() { - SPDocument *doc = inkscape_active_document(); + SPDocument *doc = INKSCAPE.active_document(); if (!doc) { return NULL; } - return dbus_register_document(inkscape_active_action_context()); + return dbus_register_document(INKSCAPE.active_action_context()); } gchar * diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index e3452f4ce..4fde6885f 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -21,7 +21,7 @@ #include <string.h> #include <dbus/dbus-glib.h> #include "desktop.h" -#include "desktop-handles.h" //sp_desktop_document() + //sp_desktop_document() #include "desktop-style.h" //sp_desktop_get_style #include "display/canvas-text.h" //text #include "display/sp-canvas.h" //text @@ -156,7 +156,7 @@ get_name_from_object (SPObject * obj) void desktop_ensure_active (SPDesktop* desk) { if (desk != SP_ACTIVE_DESKTOP) - inkscape_activate_desktop (desk); + INKSCAPE.activate_desktop (desk); return; } diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 3c8ee5844..e7299ba51 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -9,10 +9,10 @@ */ #include "prefdialog.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "helper/action.h" #include "ui/view/view.h" -#include "desktop-handles.h" + #include "selection.h" #include "sp-namedview.h" #include "desktop.h" @@ -89,11 +89,13 @@ Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation * } // children of "inkscape-extension" } // if we have an XML file - if (INKSCAPE != NULL && inkscape_use_gui()) { + // \TODO this gets called from the Inkscape::Application constructor, where it initializes the menus. + // But in the constructor, our object isn't quite there yet! + if (Inkscape::Application::exists() && INKSCAPE.use_gui()) { if (_effects_list == NULL) - _effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST); + _effects_list = find_menu(INKSCAPE.get_menus(), EFFECTS_LIST); if (_filters_list == NULL) - _filters_list = find_menu(inkscape_get_menus(INKSCAPE), FILTERS_LIST); + _filters_list = find_menu(INKSCAPE.get_menus(), FILTERS_LIST); } if ((_effects_list != NULL || _filters_list != NULL)) { diff --git a/src/extension/error-file.cpp b/src/extension/error-file.cpp index f60af870f..db354c0ce 100644 --- a/src/extension/error-file.cpp +++ b/src/extension/error-file.cpp @@ -48,9 +48,10 @@ ErrorFileNotice::ErrorFileNotice (void) : ) { + // \FIXME change this /* This is some filler text, needs to change before relase */ Glib::ustring dialog_text(_("<span weight=\"bold\" size=\"larger\">One or more extensions failed to load</span>\n\nThe failed extensions have been skipped. Inkscape will continue to run normally but those extensions will be unavailable. For details to troubleshoot this problem, please refer to the error log located at: ")); - gchar * ext_error_file = profile_path(EXTENSION_ERROR_LOG_FILENAME); + gchar * ext_error_file = Inkscape::Application::profile_path(EXTENSION_ERROR_LOG_FILENAME); dialog_text += ext_error_file; g_free(ext_error_file); set_message(dialog_text, true); diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index d4b5fd187..13b8d60c4 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -31,7 +31,7 @@ #include "desktop.h" #include "ui/view/view.h" #include "sp-namedview.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "util/glib-list-iterators.h" @@ -65,7 +65,7 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp if (desktop != NULL) { Inkscape::Util::GSListConstIterator<SPItem *> selected = - sp_desktop_selection(desktop)->itemList(); + desktop->getSelection()->itemList(); while ( selected != NULL ) { Glib::ustring selected_id; selected_id = (*selected)->getId(); @@ -200,7 +200,7 @@ ExecutionEnv::reselect (void) { if (desktop == NULL) { return; } - Inkscape::Selection * selection = sp_desktop_selection(desktop); + Inkscape::Selection * selection = desktop->getSelection(); for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); ++i) { SPObject * obj = doc->getObjectById(i->c_str()); diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 6a22eb585..3d0f49a20 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -667,7 +667,7 @@ Extension::set_param_color (const gchar * name, guint32 color, SPDocument * doc, void Extension::error_file_open (void) { - gchar * ext_error_file = profile_path(EXTENSION_ERROR_LOG_FILENAME); + gchar * ext_error_file = Inkscape::Application::profile_path(EXTENSION_ERROR_LOG_FILENAME); gchar * filename = g_filename_from_utf8( ext_error_file, -1, NULL, NULL, NULL ); error_file.open(filename); if (!error_file.is_open()) { diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 6f6bddb93..52f63499a 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -21,7 +21,7 @@ #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "ui/view/view.h" #include "util/glib-list-iterators.h" @@ -48,8 +48,8 @@ Gtk::Widget *Implementation::prefs_effect(Inkscape::Extension::Effect *module, I SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = - sp_desktop_selection((SPDesktop *)view)->itemList(); + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node const* first_select = NULL; if (selected != NULL) { const SPItem * item = *selected; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 99c882a01..bbc567f75 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -24,7 +24,7 @@ #include <errno.h> #include <glib/gstdio.h> -#include "desktop-handles.h" + #include "desktop.h" #include "ui/dialog-events.h" #include "extension/effect.h" @@ -690,7 +690,7 @@ void Script::effect(Inkscape::Extension::Effect *module, } Inkscape::Util::GSListConstIterator<SPItem *> selected = - sp_desktop_selection(desktop)->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer + desktop->getSelection()->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer while ( selected != NULL ) { Glib::ustring selected_id; selected_id += "--id="; @@ -1051,7 +1051,7 @@ int Script::execute (const std::list<std::string> &in_command, Glib::ustring stderr_data = fileerr.string(); if (stderr_data.length() != 0 && - inkscape_use_gui() + INKSCAPE.use_gui() ) { checkStderr(stderr_data, Gtk::MESSAGE_INFO, _("Inkscape has received additional data from the script executed. " diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 912d58a13..c16a5a899 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -243,7 +243,7 @@ init() /* Load search path for extensions */ if (Inkscape::Extension::Extension::search_path.size() == 0) { - Inkscape::Extension::Extension::search_path.push_back(profile_path("extensions")); + Inkscape::Extension::Extension::search_path.push_back(Inkscape::Application::profile_path("extensions")); Inkscape::Extension::Extension::search_path.push_back(g_strdup(INKSCAPE_EXTENSIONDIR)); diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 0d47240d4..76f35415e 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -25,7 +25,7 @@ #include <glib/gstdio.h> #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "sp-object.h" #include "util/glib-list-iterators.h" @@ -242,7 +242,9 @@ ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::Vie SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); + + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node * first_select = NULL; if (selected != NULL) { first_select = (*selected)->getRepr(); diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 4defc2ab9..5dc412301 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -146,12 +146,12 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) {} bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -169,14 +169,14 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con bool new_areaPage = true; try { - new_areaPage = (strcmp(ext->get_param_optiongroup("area"), "page") == 0); + new_areaPage = (strcmp(mod->get_param_optiongroup("area"), "page") == 0); } catch(...) {} bool new_areaDrawing = !new_areaPage; float bleedmargin_px = 0.; try { - bleedmargin_px = ext->get_param_float("bleed"); + bleedmargin_px = mod->get_param_float("bleed"); } catch(...) {} const gchar *new_exportId = NULL; @@ -221,7 +221,7 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co Inkscape::Extension::Extension * ext; unsigned int ret; - ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS); + ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS); if (ext == NULL) return; @@ -235,12 +235,12 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) {} bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -258,14 +258,14 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co bool new_areaPage = true; try { - new_areaPage = (strcmp(ext->get_param_optiongroup("area"), "page") == 0); + new_areaPage = (strcmp(mod->get_param_optiongroup("area"), "page") == 0); } catch(...) {} bool new_areaDrawing = !new_areaPage; float bleedmargin_px = 0.; try { - bleedmargin_px = ext->get_param_float("bleed"); + bleedmargin_px = mod->get_param_float("bleed"); } catch(...) {} const gchar *new_exportId = NULL; @@ -330,10 +330,13 @@ CairoPsOutput::init (void) "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n" "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" - "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" + "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size") "\" type=\"optiongroup\" >\n" "<_option value=\"page\">" N_("Use document's page size") "</_option>" "<_option value=\"drawing\">" N_("Use exported object's size") "</_option>" @@ -369,10 +372,13 @@ CairoEpsOutput::init (void) "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n" "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" - "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" + "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size") "\" type=\"optiongroup\" >\n" "<_option value=\"page\">" N_("Use document's page size") "</_option>" "<_option value=\"drawing\">" N_("Use exported object's size") "</_option>" diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index cb414b3b2..d76c187a2 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -658,12 +658,12 @@ CairoRenderContext::popLayer(void) CairoRenderContext *mask_ctx = _renderer->createContext(); // Fix Me: This is a kludge. PDF and PS output is set to 72 dpi but the - // Cairo surface is expecting the mask to be 90 dpi. + // Cairo surface is expecting the mask to be 96 dpi. float surface_width = _width; float surface_height = _height; if( _vector_based_target ) { - surface_width *= 1.25; - surface_height *= 1.25; + surface_width *= 4.0/3.0; + surface_height *= 4.0/3.0; } if (!mask_ctx->setupSurface( surface_width, surface_height )) { TRACE(("mask: setupSurface failed\n")); diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 0c314a576..e5c9406c9 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -149,7 +149,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) { g_warning("Parameter <textToPath> might not exist"); @@ -157,7 +157,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -247,10 +247,13 @@ CairoRendererPdfOutput::init (void) #endif "<_item value='PDF-1.4'>" N_("PDF 1.4") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("PDF+LaTeX: Omit text in PDF, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" - "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" + "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size:") "\" type=\"optiongroup\" >\n" "<_option value=\"page\">" N_("Use document's page size") "</_option>" "<_option value=\"drawing\">" N_("Use exported object's size") "</_option>" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index a725685d4..1f48d2097 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -147,13 +147,13 @@ Here comes the rendering part which could be put into the 'render' methods of SP /* The below functions are copy&pasted plus slightly modified from *_invoke_print functions. */ static void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx); -static void sp_group_render(SPItem *item, CairoRenderContext *ctx); -static void sp_use_render(SPItem *item, CairoRenderContext *ctx); -static void sp_shape_render(SPItem *item, CairoRenderContext *ctx); -static void sp_text_render(SPItem *item, CairoRenderContext *ctx); -static void sp_flowtext_render(SPItem *item, CairoRenderContext *ctx); -static void sp_image_render(SPItem *item, CairoRenderContext *ctx); -static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx); +static void sp_group_render(SPGroup *group, CairoRenderContext *ctx); +static void sp_use_render(SPUse *use, CairoRenderContext *ctx); +static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx); +static void sp_text_render(SPText *text, CairoRenderContext *ctx); +static void sp_flowtext_render(SPFlowtext *flowtext, CairoRenderContext *ctx); +static void sp_image_render(SPImage *image, CairoRenderContext *ctx); +static void sp_symbol_render(SPSymbol *symbol, CairoRenderContext *ctx); static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx); static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Affine tr, SPStyle* style, CairoRenderContext *ctx) @@ -179,17 +179,15 @@ static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Affi } } -static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) +static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) { - SPShape *shape = SP_SHAPE(item); - if (!shape->_curve) { return; } - Geom::OptRect pbox = item->geometricBounds(); + Geom::OptRect pbox = shape->geometricBounds(); - SPStyle* style = item->style; + SPStyle* style = shape->style; Geom::PathVector const & pathv = shape->_curve->get_pathvector(); if (pathv.empty()) { @@ -201,14 +199,14 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) // START marker for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START if ( shape->_marker[i] ) { - SPMarker* marker = SP_MARKER (shape->_marker[i]); + SPMarker* marker = shape->_marker[i]; Geom::Affine tr; if (marker->orient_mode == MARKER_ORIENT_AUTO) { tr = sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { tr = Geom::Rotate::from_degrees( 180.0 ) * sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(pathv.begin()->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(pathv.begin()->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -216,7 +214,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) // MID marker for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if ( !shape->_marker[i] ) continue; - SPMarker* marker = SP_MARKER (shape->_marker[i]); + SPMarker* marker = shape->_marker[i]; for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { // START position if ( path_it != pathv.begin() @@ -226,7 +224,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(path_it->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(path_it->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -243,7 +241,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(curve_it1->pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(curve_it1->pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); @@ -259,7 +257,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -268,7 +266,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) // END marker for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END if ( shape->_marker[i] ) { - SPMarker* marker = SP_MARKER (shape->_marker[i]); + SPMarker* marker = shape->_marker[i]; /* Get reference to last curve in the path. * For moveto-only path, this returns the "closing line segment". */ @@ -283,7 +281,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); @@ -291,26 +289,25 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) } } -static void sp_group_render(SPItem *item, CairoRenderContext *ctx) +static void sp_group_render(SPGroup *group, CairoRenderContext *ctx) { - SPGroup *group = SP_GROUP(item); CairoRenderer *renderer = ctx->getRenderer(); TRACE(("sp_group_render opacity: %f\n", SP_SCALE24_TO_FLOAT(item->style->opacity.value))); GSList *l = g_slist_reverse(group->childList(false)); while (l) { - SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM(o)) { - renderer->renderItem (ctx, SP_ITEM (o)); + SPObject *o = reinterpret_cast<SPObject *>(l->data); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + renderer->renderItem(ctx, item); } l = g_slist_remove (l, o); } } -static void sp_use_render(SPItem *item, CairoRenderContext *ctx) +static void sp_use_render(SPUse *use, CairoRenderContext *ctx) { bool translated = false; - SPUse *use = SP_USE(item); CairoRenderer *renderer = ctx->getRenderer(); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { @@ -320,8 +317,8 @@ static void sp_use_render(SPItem *item, CairoRenderContext *ctx) translated = true; } - if (use->child && SP_IS_ITEM(use->child)) { - renderer->renderItem(ctx, SP_ITEM(use->child)); + if (use->child) { + renderer->renderItem(ctx, use->child); } if (translated) { @@ -329,30 +326,27 @@ static void sp_use_render(SPItem *item, CairoRenderContext *ctx) } } -static void sp_text_render(SPItem *item, CairoRenderContext *ctx) +static void sp_text_render(SPText *text, CairoRenderContext *ctx) { - SPText *group = SP_TEXT (item); - group->layout.showGlyphs(ctx); + text->layout.showGlyphs(ctx); } -static void sp_flowtext_render(SPItem *item, CairoRenderContext *ctx) +static void sp_flowtext_render(SPFlowtext *flowtext, CairoRenderContext *ctx) { - SPFlowtext *group = SP_FLOWTEXT(item); - group->layout.showGlyphs(ctx); + flowtext->layout.showGlyphs(ctx); } -static void sp_image_render(SPItem *item, CairoRenderContext *ctx) +static void sp_image_render(SPImage *image, CairoRenderContext *ctx) { - SPImage *image; - int w, h; - - image = SP_IMAGE (item); - - if (!image->pixbuf) return; - if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return; + if (!image->pixbuf) { + return; + } + if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) { + return; + } - w = image->pixbuf->width(); - h = image->pixbuf->height(); + int w = image->pixbuf->width(); + int h = image->pixbuf->height(); double x = image->x.computed; double y = image->y.computed; @@ -372,12 +366,11 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx) Geom::Scale s(width / (double)w, height / (double)h); Geom::Affine t(s * tp); - ctx->renderImage (image->pixbuf, t, item->style); + ctx->renderImage(image->pixbuf, t, image->style); } -static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) +static void sp_symbol_render(SPSymbol *symbol, CairoRenderContext *ctx) { - SPSymbol *symbol = SP_SYMBOL(item); if (!symbol->cloned) { return; } @@ -412,7 +405,7 @@ static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) ctx->transform(vb2user); } - sp_group_render(item, ctx); + sp_group_render(symbol, ctx); ctx->popState(); } @@ -479,7 +472,7 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) double shift_x = bbox->min()[Geom::X]; double shift_y = bbox->max()[Geom::Y]; - // For default 90 dpi, snap bitmap to pixel grid + // For default 96 dpi, snap bitmap to pixel grid if (res == Inkscape::Util::Quantity::convert(1, "in", "px")) { shift_x = round (shift_x); shift_y = -round (-shift_y); // Correct rounding despite coordinate inversion. @@ -524,34 +517,56 @@ static void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx) SPStyle* style = item->style; if((ctx->getFilterToBitmap() == TRUE) && (style->filter.set != 0)) { - return sp_asbitmap_render(item, ctx); + sp_asbitmap_render(item, ctx); } - if (SP_IS_ROOT(item)) { + SPRoot *root = dynamic_cast<SPRoot *>(item); + if (root) { TRACE(("root\n")); - return sp_root_render(SP_ROOT(item), ctx); - } else if (SP_IS_SYMBOL(item)) { - TRACE(("symbol\n")); - return sp_symbol_render(item, ctx); - } else if (SP_IS_GROUP(item)) { - TRACE(("group\n")); - return sp_group_render(item, ctx); - } else if (SP_IS_SHAPE(item)) { - TRACE(("shape\n")); - return sp_shape_render(item, ctx); - } else if (SP_IS_USE(item)) { - TRACE(("use begin---\n")); - sp_use_render(item, ctx); - TRACE(("---use end\n")); - } else if (SP_IS_TEXT(item)) { - TRACE(("text\n")); - return sp_text_render(item, ctx); - } else if (SP_IS_FLOWTEXT(item)) { - TRACE(("flowtext\n")); - return sp_flowtext_render(item, ctx); - } else if (SP_IS_IMAGE(item)) { - TRACE(("image\n")); - return sp_image_render(item, ctx); + sp_root_render(root, ctx); + } else { + SPSymbol *symbol = dynamic_cast<SPSymbol *>(item); + if (symbol) { + TRACE(("symbol\n")); + sp_symbol_render(symbol, ctx); + } else { + SPGroup *group = dynamic_cast<SPGroup *>(item); + if (group) { + TRACE(("group\n")); + sp_group_render(group, ctx); + } else { + SPShape *shape = dynamic_cast<SPShape *>(item); + if (shape) { + TRACE(("shape\n")); + sp_shape_render(shape, ctx); + } else { + SPUse *use = dynamic_cast<SPUse *>(item); + if (use) { + TRACE(("use begin---\n")); + sp_use_render(use, ctx); + TRACE(("---use end\n")); + } else { + SPText *text = dynamic_cast<SPText *>(item); + if (text) { + TRACE(("text\n")); + sp_text_render(text, ctx); + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(item); + if (flowtext) { + TRACE(("flowtext\n")); + sp_flowtext_render(flowtext, ctx); + } else { + SPImage *image = dynamic_cast<SPImage *>(item); + if (image) { + TRACE(("image\n")); + sp_image_render(image, ctx); + } + } + } + } + } + } + } } } @@ -571,8 +586,9 @@ CairoRenderer::setStateForItem(CairoRenderContext *ctx, SPItem const *item) // This is so because we use the image's/(flow)text's transform for positioning // instead of explicitly specifying it and letting the renderer do the // transformation before rendering the item. - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_IMAGE(item)) + if (dynamic_cast<SPText const *>(item) || dynamic_cast<SPFlowtext const *>(item) || dynamic_cast<SPImage const *>(item)) { state->parent_has_userspace = TRUE; + } TRACE(("setStateForItem opacity: %f\n", state->opacity)); } @@ -700,8 +716,8 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) TRACE(("BEGIN clip\n")); SPObject const *co = cp; for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SPItem const *item = SP_ITEM(child); + SPItem const *item = dynamic_cast<SPItem const *>(child); + if (item) { // combine transform of the item in clippath and the item using clippath: Geom::Affine tempmat = item->transform * ctx->getCurrentState()->item_transform; @@ -759,8 +775,8 @@ CairoRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) TRACE(("BEGIN mask\n")); SPObject const *co = mask; for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SPItem const *item = SP_ITEM(child); + SPItem const *item = dynamic_cast<SPItem const *>(child); + if (item) { // TODO fix const correctness: renderItem(ctx, const_cast<SPItem*>(item)); } diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index 3a3e2b58e..f4789a08f 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -263,7 +263,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { CdrImportDialog *dlg = 0; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new CdrImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; @@ -285,7 +285,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } return doc; } diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 0f43fbca1..f7b6626c4 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -144,7 +144,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc) // width and height in px _width = doc->getWidth().value("px"); _height = doc->getHeight().value("px"); - _doc_unit_scale = Inkscape::Util::Quantity::convert(1, (doc->getDefaultUnit()), "px"); + _doc_unit_scale = Inkscape::Util::Quantity::convert(1, &doc->getSVGUnit(), "px"); // initialize a few global variables hbrush = hbrushOld = hpen = 0; diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp index 48e64f089..b1993057d 100644 --- a/src/extension/internal/filter/filter-file.cpp +++ b/src/extension/internal/filter/filter-file.cpp @@ -29,7 +29,7 @@ namespace Filter { void Filter::filters_all_files(void) { - gchar *filtersProfilePath = profile_path("filters"); + gchar *filtersProfilePath = Inkscape::Application::profile_path("filters"); filters_load_dir(INKSCAPE_FILTERDIR, _("Bundled")); filters_load_dir(filtersProfilePath, _("Personal")); diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 28e44c461..f5fab1fa2 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -135,8 +135,8 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - std::cout << "Viewbox not set, setting" << std::endl; - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + // std::cerr << "Viewbox not set, setting" << std::endl; + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } // restore undo, as now this document may be shown to the user if a bitmap was opened diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index 0059bbec2..270edfe44 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -24,7 +24,7 @@ #include <gtkmm/spinbutton.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "selection.h" #include "sp-object.h" @@ -113,7 +113,7 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc bounding_area = temprec; } - gdouble scale = Inkscape::Util::Quantity::convert(1, "px", (document->doc())->getDefaultUnit()); + gdouble scale = Inkscape::Util::Quantity::convert(1, "px", &document->doc()->getSVGUnit()); bounding_area *= Geom::Scale(scale); Geom::Point spacings( scale * module->get_param_float("xspacing"), scale * module->get_param_float("yspacing") ); @@ -191,7 +191,9 @@ Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); + + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node * first_select = NULL; if (selected != NULL) { first_select = (*selected)->getRepr(); diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 398c9f061..ab0733848 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -66,7 +66,8 @@ latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, bool pageBoundingBox = true; if (exportId && strcmp(exportId, "")) { // we want to export the given item only - base = SP_ITEM(doc->getObjectById(exportId)); + base = dynamic_cast<SPItem *>(doc->getObjectById(exportId)); + g_assert(base != NULL); pageBoundingBox = exportCanvas; } else { @@ -225,26 +226,22 @@ LaTeXTextRenderer::writePostamble() fprintf(_stream, "%s", postamble); } -void -LaTeXTextRenderer::sp_group_render(SPItem *item) +void LaTeXTextRenderer::sp_group_render(SPGroup *group) { - SPGroup *group = SP_GROUP(item); - GSList *l = g_slist_reverse(group->childList(false)); while (l) { - SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM(o)) { - renderItem (SP_ITEM (o)); + SPObject *o = reinterpret_cast<SPObject *>(l->data); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + renderItem(item); } l = g_slist_remove (l, o); } } -void -LaTeXTextRenderer::sp_use_render(SPItem *item) +void LaTeXTextRenderer::sp_use_render(SPUse *use) { bool translated = false; - SPUse *use = SP_USE(item); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed)); @@ -252,8 +249,9 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) translated = true; } - if (use->child && SP_IS_ITEM(use->child)) { - renderItem(SP_ITEM(use->child)); + SPItem *childItem = dynamic_cast<SPItem *>(use->child); + if (childItem) { + renderItem(childItem); } if (translated) { @@ -261,16 +259,14 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) } } -void -LaTeXTextRenderer::sp_text_render(SPItem *item) +void LaTeXTextRenderer::sp_text_render(SPText *textobj) { // Only PDFLaTeX supports importing a single page of a graphics file, // so only PDF backend gets interleaved text/graphics if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP) _omittext_state = NEW_PAGE_ON_GRAPHIC; - SPText *textobj = SP_TEXT (item); - SPStyle *style = item->style; + SPStyle *style = textobj->style; // get position and alignment // Align vertically on the baseline of the font (retreived from the anchor point) @@ -312,7 +308,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) } // get rotation - Geom::Affine i2doc = item->i2doc_affine(); + Geom::Affine i2doc = textobj->i2doc_affine(); Geom::Affine wotransl = i2doc.withoutTranslation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); bool has_rotation = !Geom::are_near(degrees,0.); @@ -336,11 +332,11 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) // Walk through all spans in the text object. // Write span strings to LaTeX, associated with font weight and style. - Inkscape::Text::Layout const &layout = *(te_get_layout (item)); + Inkscape::Text::Layout const &layout = *(te_get_layout (textobj)); for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); li != le; li.nextStartOfSpan()) { - SPStyle const &spanstyle = *(sp_te_style_at_position (item, li)); + SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li)); bool is_bold = false, is_italic = false, is_oblique = false; if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || @@ -367,7 +363,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) Inkscape::Text::Layout::iterator ln = li; ln.nextStartOfSpan(); - Glib::ustring uspanstr = sp_te_get_string_multiline (item, li, ln); + Glib::ustring uspanstr = sp_te_get_string_multiline (textobj, li, ln); const gchar *spanstr = uspanstr.c_str(); if (!spanstr) { continue; @@ -394,8 +390,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) fprintf(_stream, "%s", os.str().c_str()); } -void -LaTeXTextRenderer::sp_flowtext_render(SPItem * item) +void LaTeXTextRenderer::sp_flowtext_render(SPFlowtext *flowtext) { /* Flowtext is possible by using a minipage! :) @@ -407,16 +402,15 @@ Flowing in rectangle is possible, not in arb shape. if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP) _omittext_state = NEW_PAGE_ON_GRAPHIC; - SPFlowtext *flowtext = SP_FLOWTEXT(item); - SPStyle *style = item->style; + SPStyle *style = flowtext->style; SPItem *frame_item = flowtext->get_frame(NULL); - if (!frame_item || !SP_IS_RECT(frame_item)) { + SPRect *frame = dynamic_cast<SPRect *>(frame_item); + if (!frame_item || !frame) { g_warning("LaTeX export: non-rectangular flowed text shapes are not supported, skipping text."); return; // don't know how to handle non-rect frames yet. is quite uncommon for latex users i think } - SPRect *frame = SP_RECT(frame_item); Geom::Rect framebox = frame->getRect() * transform(); // get position and alignment @@ -460,7 +454,7 @@ Flowing in rectangle is possible, not in arb shape. } // get rotation - Geom::Affine i2doc = item->i2doc_affine(); + Geom::Affine i2doc = flowtext->i2doc_affine(); Geom::Affine wotransl = i2doc.withoutTranslation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); bool has_rotation = !Geom::are_near(degrees,0.); @@ -485,11 +479,11 @@ Flowing in rectangle is possible, not in arb shape. // Walk through all spans in the text object. // Write span strings to LaTeX, associated with font weight and style. - Inkscape::Text::Layout const &layout = *(te_get_layout (item)); + Inkscape::Text::Layout const &layout = *(te_get_layout(flowtext)); for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); li != le; li.nextStartOfSpan()) { - SPStyle const &spanstyle = *(sp_te_style_at_position (item, li)); + SPStyle const &spanstyle = *(sp_te_style_at_position(flowtext, li)); bool is_bold = false, is_italic = false, is_oblique = false; if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || @@ -516,7 +510,7 @@ Flowing in rectangle is possible, not in arb shape. Inkscape::Text::Layout::iterator ln = li; ln.nextStartOfSpan(); - Glib::ustring uspanstr = sp_te_get_string_multiline (item, li, ln); + Glib::ustring uspanstr = sp_te_get_string_multiline(flowtext, li, ln); const gchar *spanstr = uspanstr.c_str(); if (!spanstr) { continue; @@ -558,22 +552,36 @@ LaTeXTextRenderer::sp_item_invoke_render(SPItem *item) return; } - if (SP_IS_ROOT(item)) { - return sp_root_render(SP_ROOT(item)); - } else if (SP_IS_GROUP(item)) { - return sp_group_render(item); - } else if (SP_IS_USE(item)) { - sp_use_render(item); - } else if (SP_IS_TEXT(item)) { - return sp_text_render(item); - } else if (SP_IS_FLOWTEXT(item)) { - return sp_flowtext_render(item); + SPRoot *root = dynamic_cast<SPRoot *>(item); + if (root) { + sp_root_render(root); } else { - // Only PDFLaTeX supports importing a single page of a graphics file, - // so only PDF backend gets interleaved text/graphics - if (_pdflatex && (_omittext_state == EMPTY || _omittext_state == NEW_PAGE_ON_GRAPHIC)) - writeGraphicPage(); - _omittext_state = GRAPHIC_ON_TOP; + SPGroup *group = dynamic_cast<SPGroup *>(item); + if (group) { + sp_group_render(group); + } else { + SPUse *use = dynamic_cast<SPUse *>(item); + if (use) { + sp_use_render(use); + } else { + SPText *text = dynamic_cast<SPText *>(item); + if (text) { + sp_text_render(text); + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(item); + if (flowtext) { + sp_flowtext_render(flowtext); + } else { + // Only PDFLaTeX supports importing a single page of a graphics file, + // so only PDF backend gets interleaved text/graphics + if (_pdflatex && (_omittext_state == EMPTY || _omittext_state == NEW_PAGE_ON_GRAPHIC)) { + writeGraphicPage(); + } + _omittext_state = GRAPHIC_ON_TOP; + } + } + } + } } } diff --git a/src/extension/internal/latex-text-renderer.h b/src/extension/internal/latex-text-renderer.h index 77d12bc61..b9563b53b 100644 --- a/src/extension/internal/latex-text-renderer.h +++ b/src/extension/internal/latex-text-renderer.h @@ -23,6 +23,10 @@ class SPItem; class SPRoot; +class SPGroup; +class SPUse; +class SPText; +class SPFlowtext; namespace Inkscape { namespace Extension { @@ -73,10 +77,10 @@ protected: void sp_item_invoke_render(SPItem *item); void sp_root_render(SPRoot *item); - void sp_group_render(SPItem *item); - void sp_use_render(SPItem *item); - void sp_text_render(SPItem *item); - void sp_flowtext_render(SPItem *item); + void sp_group_render(SPGroup *group); + void sp_use_render(SPUse *use); + void sp_text_render(SPText *text); + void sp_flowtext_render(SPFlowtext *flowtext); }; } /* namespace Internal */ diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index c8a7feabf..148d2dcba 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -720,7 +720,7 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { } PdfImportDialog *dlg = NULL; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new PdfImportDialog(pdf_doc, uri); if (!dlg->showDialog()) { _cancelled = true; @@ -883,7 +883,7 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } // Restore undo diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 0b7dc7905..812fa373f 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -923,7 +923,9 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) GBool isolated = gFalse; GBool knockout = gFalse; if (!obj4.dictLookup(const_cast<char*>("CS"), &obj5)->isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(NULL, &obj5, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); @@ -1159,7 +1161,13 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) res->lookupColorSpace(args[0].getName(), &obj); GfxColorSpace *colorSpace = 0; -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(NULL, &args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(NULL, &obj, NULL, NULL); + } +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); } else { @@ -1202,7 +1210,13 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(NULL, &args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(NULL, &obj, NULL, NULL); + } +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); } else { @@ -2910,7 +2924,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) } } if (!obj1.isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + colorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) colorSpace = GfxColorSpace::parse(&obj1, NULL); @@ -3004,7 +3020,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) obj2.free(); } } -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + GfxColorSpace *maskColorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); @@ -3196,7 +3214,9 @@ void PdfParser::doForm(Object *str) { if (obj1.dictLookup(const_cast<char*>("S"), &obj2)->isName(const_cast<char*>("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast<char*>("CS"), &obj3)->isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(NULL, &obj3, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 7a504add0..a3abb4045 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -91,9 +91,6 @@ SvgBuilder::SvgBuilder(SPDocument *document, gchar *docname, XRef *xref) _preferences = _xml_doc->createElement("svgbuilder:prefs"); _preferences->setAttribute("embedImages", "1"); _preferences->setAttribute("localFonts", "1"); - - _ttm[0] = 1; _ttm[1] = 0; _ttm[2] = 0; _ttm[3] = 1; _ttm[4] = 0; _ttm[5] = 0; - _ttm_is_set = false; } SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) { @@ -136,6 +133,9 @@ void SvgBuilder::_init() { initial_state.group_depth = 0; _state_stack.push_back(initial_state); _node_stack.push_back(_container); + + _ttm[0] = 1; _ttm[1] = 0; _ttm[2] = 0; _ttm[3] = 1; _ttm[4] = 0; _ttm[5] = 0; + _ttm_is_set = false; } void SvgBuilder::setDocumentSize(double width, double height) { diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 9f9bf2651..7fd0d363b 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -263,7 +263,7 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { VsdImportDialog *dlg = 0; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new VsdImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; @@ -285,7 +285,7 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } return doc; diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index 12d86a99a..54a14fc72 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -129,7 +129,7 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } delete input; diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp index 75d5a40e3..f9515197c 100644 --- a/src/extension/param/radiobutton.cpp +++ b/src/extension/param/radiobutton.cpp @@ -122,7 +122,7 @@ ParamRadioButton::ParamRadioButton (const gchar * name, defaultval = (static_cast<optionentry*> (choices->data))->value->c_str(); } - const char * indent = xml->attribute("indent"); + const char *indent = xml ? xml->attribute("indent") : NULL; if (indent != NULL) { _indent = atoi(indent) * 12; } diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 5225f11ee..6a95717f2 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -121,7 +121,7 @@ SPDocument *open(Extension *key, gchar const *filename) } if (last_chance_svg) { - if ( inkscape_use_gui() ) { + if ( INKSCAPE.use_gui() ) { sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); } else { g_warning("%s", _("Format autodetect failed. The file is being opened as SVG.")); diff --git a/src/file.cpp b/src/file.cpp index 307944001..72516d776 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -32,7 +32,7 @@ #include "ui/dialog/ocaldialogs.h" #include "desktop.h" -#include "desktop-handles.h" + #include "dir-util.h" #include "document-private.h" #include "document-undo.h" @@ -144,7 +144,7 @@ SPDesktop *sp_file_new(const std::string &templ) // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { DocumentUndo::setUndoSensitive(doc, false); - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); DocumentUndo::setUndoSensitive(doc, true); } @@ -177,7 +177,7 @@ SPDesktop *sp_file_new(const std::string &templ) Glib::ustring sp_file_default_template_uri() { std::list<gchar *> sources; - sources.push_back( profile_path("templates") ); // first try user's local dir + sources.push_back( Inkscape::Application::profile_path("templates") ); // first try user's local dir sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir std::list<gchar const*> baseNames; gchar const* localized = _("default.svg"); @@ -289,7 +289,7 @@ bool sp_file_open(const Glib::ustring &uri, if (doc) { - SPDocument *existing = desktop ? sp_desktop_document(desktop) : NULL; + SPDocument *existing = desktop ? desktop->getDocument() : NULL; if (existing && existing->virgin && replace_empty) { // If the current desktop is empty, open the document there @@ -316,7 +316,7 @@ bool sp_file_open(const Glib::ustring &uri, sp_file_add_recent( doc->getURI() ); } - if ( inkscape_use_gui() ) { + if ( INKSCAPE.use_gui() ) { // Perform a fixup pass for hrefs. if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) { Glib::ustring msg = _("Broken links have been changed to point to existing files."); @@ -348,7 +348,7 @@ void sp_file_revert_dialog() SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_assert(doc != NULL); Inkscape::XML::Node *repr = doc->getReprRoot(); @@ -1055,7 +1055,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) { //TODO: merge with file_import() - SPDocument *target_document = sp_desktop_document(desktop); + SPDocument *target_document = desktop->getDocument(); Inkscape::XML::Node *root = clipdoc->getReprRoot(); Inkscape::XML::Node *target_parent = desktop->currentLayer()->getRepr(); @@ -1086,7 +1086,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) } // Change the selection to the freshly pasted objects - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->setReprList(pasted_objects); // Apply inverse of parent transform @@ -1221,7 +1221,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // select and move the imported item if (new_obj && SP_IS_ITEM(new_obj)) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->set(SP_ITEM(new_obj)); // preserve parent and viewBox transformations @@ -1232,7 +1232,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // move to mouse pointer { - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 27f4d7a98..cf75f6cf0 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -31,7 +31,7 @@ #include "document-undo.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "ui/tools/tool-base.h" #include "selection.h" #include "verbs.h" @@ -868,9 +868,8 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint gchar const* color_str = sp_repr_css_property( stop, "stop-color", NULL ); if( color_str ) { SPColor color( 0 ); - SPStyle* style = sp_style_new(0); SPIPaint paint; - paint.read( color_str, *style ); + paint.read( color_str ); if( paint.isColor() ) { color = paint.value.color; } @@ -1569,20 +1568,20 @@ SPGradient *sp_gradient_vector_for_object( SPDocument *const doc, SPDesktop *con void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTarget fill_or_stroke) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { sp_item_gradient_invert_vector_color(SP_ITEM(i->data), fill_or_stroke); } // we did an undoable action - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Invert gradient colors")); } void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::UI::Tools::ToolBase *ev = desktop->getEventContext(); if (!ev) { @@ -1602,7 +1601,7 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) } // we did an undoable action - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Reverse gradient")); } diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index a14220cfa..154b7339b 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -22,11 +22,11 @@ #include <cstring> #include <string> -#include "desktop-handles.h" + #include "selection.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "display/sp-ctrlline.h" @@ -563,7 +563,7 @@ SPStop *GrDrag::addStopNearPoint(SPItem *item, Geom::Point mouse_p, double toler mg->array.built = false; mg->ensureArray(); // How do we do this? - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Added patch row or column")); } // Mesh @@ -631,7 +631,7 @@ GrDrag::GrDrag(SPDesktop *desktop) : vert_levels(), draggers(0), lines(0), - selection(sp_desktop_selection(desktop)), + selection(desktop->getSelection()), sel_changed_connection(), sel_modified_connection(), style_set_connection(), @@ -782,6 +782,8 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui // unlink and delete this dragger dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger); + d_new->parent->draggers = g_list_remove (d_new->parent->draggers, dragger); + d_new->parent->selected = g_list_remove (d_new->parent->selected, dragger); delete dragger; // throw out delayed snap context @@ -794,7 +796,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui d_new->updateKnotShape (); d_new->updateTip (); d_new->updateDependencies(true); - DocumentUndo::done(sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, _("Merge gradient handles")); + DocumentUndo::done(d_new->parent->desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Merge gradient handles")); return; } } @@ -1100,8 +1102,7 @@ static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer dragger->updateDependencies(true); // we did an undoable action - DocumentUndo::done(sp_desktop_document (dragger->parent->desktop), SP_VERB_CONTEXT_GRADIENT, - _("Move gradient handle")); + DocumentUndo::done(dragger->parent->desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Move gradient handle")); } /** @@ -1867,7 +1868,7 @@ void GrDrag::setDeselected(GrDragger *dragger) void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke) { CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY; - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(this->desktop), p1, p2, type); + SPCtrlLine *line = ControlManager::getManager().createControlLine(this->desktop->getControls(), p1, p2, type); sp_canvas_item_move_to_z(line, 0); line->item = item; @@ -1883,7 +1884,7 @@ void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::Pai void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, Inkscape::PaintTarget fill_or_stroke) { CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY; - SPCtrlCurve *line = ControlManager::getManager().createControlCurve(sp_desktop_controls(this->desktop), p0, p1, p2, p3, type); + SPCtrlCurve *line = ControlManager::getManager().createControlCurve(this->desktop->getControls(), p0, p1, p2, p3, type); sp_canvas_item_move_to_z(line, 0); line->item = item; @@ -2373,7 +2374,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (write_repr && did) { // we did an undoable action - DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmoveh", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(desktop->getDocument(), "grmoveh", SP_VERB_CONTEXT_GRADIENT, _("Move gradient handle(s)")); return; } @@ -2409,7 +2410,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (write_repr && did) { // we did an undoable action - DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmovem", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(desktop->getDocument(), "grmovem", SP_VERB_CONTEXT_GRADIENT, _("Move gradient mid stop(s)")); } } diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 18159cb41..e5d61ab64 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -117,7 +117,7 @@ void graphlayout(GSList const *const items) { // add the connector spacing to the size of node bounding boxes // so that connectors can always be routed between shapes - SPDesktop* desktop = inkscape_active_desktop(); + SPDesktop* desktop = SP_ACTIVE_DESKTOP; double spacing = 0; if(desktop) spacing = desktop->namedview->connector_spacing+0.1; diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index acb2be4da..9639096fb 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -34,20 +34,21 @@ #include "helper/pixbuf-ops.h" -// TODO look for copy-n-past duplication of this function: +// TODO look for copy-n-paste duplication of this function: /** * Hide all items that are not listed in list, recursively, skipping groups and defs. */ static void hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey) { - if ( SP_IS_ITEM(o) - && !SP_IS_DEFS(o) - && !SP_IS_ROOT(o) - && !SP_IS_GROUP(o) - && !SP_IS_USE(o) + SPItem *item = dynamic_cast<SPItem *>(o); + if ( item + && !dynamic_cast<SPDefs *>(item) + && !dynamic_cast<SPRoot *>(item) + && !dynamic_cast<SPGroup *>(item) + && !dynamic_cast<SPUse *>(item) && !g_slist_find(list, o) ) { - SP_ITEM(o)->invoke_hide(dkey); + item->invoke_hide(dkey); } // recurse diff --git a/src/helper/stock-items.cpp b/src/helper/stock-items.cpp index 582dcd2a8..5a56b89ff 100644 --- a/src/helper/stock-items.cpp +++ b/src/helper/stock-items.cpp @@ -29,7 +29,7 @@ #include "document-private.h" #include "sp-pattern.h" #include "sp-marker.h" -#include "desktop-handles.h" +#include "desktop.h" #include "inkscape.h" #include "io/sys.h" @@ -195,8 +195,8 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) gchar * base = g_strndup(e, a); - SPDesktop *desktop = inkscape_active_desktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); SPDefs *defs = doc->getDefs(); if (!defs) { g_free(base); @@ -265,8 +265,8 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) else { - SPDesktop *desktop = inkscape_active_desktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); SPObject *object = doc->getObjectById(urn); return object; diff --git a/src/inkscape-manifest-x64.xml b/src/inkscape-manifest-x64.xml index 38526cfe6..b5a6f11f2 100644 --- a/src/inkscape-manifest-x64.xml +++ b/src/inkscape-manifest-x64.xml @@ -1,5 +1,10 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <application xmlns="urn:schemas-microsoft-com:asm.v3"> + <windowsSettings> + <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> + </windowsSettings> + </application> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" diff --git a/src/inkscape-private.h b/src/inkscape-private.h deleted file mode 100644 index d28ed223e..000000000 --- a/src/inkscape-private.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef SEEN_INKSCAPE_PRIVATE_H -#define SEEN_INKSCAPE_PRIVATE_H - -/* - * Some forward declarations - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ -#include <glib-object.h> - -#define SP_TYPE_INKSCAPE (inkscape_get_type ()) -#define SP_INKSCAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_INKSCAPE, Inkscape)) -#define SP_INKSCAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_INKSCAPE, InkscapeClass)) -#define SP_IS_INKSCAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_INKSCAPE)) -#define SP_IS_INKSCAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_INKSCAPE)) - -#include "inkscape.h" - -struct SPColor; -namespace Inkscape { class Selection; } - -GType inkscape_get_type (void); - -void inkscape_ref (void); -void inkscape_unref (void); - -guint inkscape_mapalt(); -void inkscape_mapalt(guint); - -guint inkscape_trackalt(); -void inkscape_trackalt(guint); - -/* - * These are meant solely for desktop, document etc. implementations - */ - -void inkscape_selection_modified (Inkscape::Selection *selection, guint flags); -void inkscape_selection_changed (Inkscape::Selection * selection); -void inkscape_selection_set (Inkscape::Selection * selection); -void inkscape_eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext); -void inkscape_add_desktop (SPDesktop * desktop); -void inkscape_remove_desktop (SPDesktop * desktop); -void inkscape_activate_desktop (SPDesktop * desktop); -void inkscape_reactivate_desktop (SPDesktop * desktop); - -void inkscape_set_color (SPColor *color, float opacity); - -#endif // SEEN_INKSCAPE_PRIVATE_H - - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 36a802e5f..6a0e0f35a 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1,13 +1,15 @@ /** * @file - * Legacy interface to main application. + * Interface to main application. */ /* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> + * Liam P. White <inkscapebrony@gmail.com> * - * Copyright (C) 1999-2005 authors - * g++ port Copyright (C) 2003 Nathan Hurst + * Copyright (C) 1999-2014 authors + * c++ port Copyright (C) 2003 Nathan Hurst + * c++ification Copyright (C) 2014 Liam P. White * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -50,240 +52,174 @@ #include <gtk/gtk.h> #include <signal.h> #include <string> + #include "desktop.h" -#include "desktop-handles.h" + #include "device-manager.h" #include "document.h" -#include "ui/tools/tool-base.h" #include "extension/db.h" #include "extension/init.h" #include "extension/output.h" #include "extension/system.h" -#include "inkscape-private.h" +#include "helper/action-context.h" +#include "helper/sp-marshal.h" +#include "inkscape.h" #include "io/sys.h" #include "layer-model.h" #include "message-stack.h" #include "preferences.h" #include "resource-manager.h" #include "selection.h" +#include "ui/tools/tool-base.h" #include "ui/dialog/debug.h" #include "xml/repr.h" -#include "helper/action-context.h" -#include "helper/sp-marshal.h" - -static InkscapeApplication *inkscape = NULL; /* Backbones of configuration xml data */ #include "menus-skeleton.h" -enum { - MODIFY_SELECTION, // global: one of selections modified - CHANGE_SELECTION, // global: one of selections changed - CHANGE_SUBSELECTION, // global: one of subselections (text selection, gradient handle, etc) changed - SET_SELECTION, // global: one of selections set - SET_EVENTCONTEXT, // tool switched - ACTIVATE_DESKTOP, // some desktop got focus - DEACTIVATE_DESKTOP, // some desktop lost focus - SHUTDOWN_SIGNAL, // inkscape is quitting - DIALOGS_HIDE, // user pressed F12 - DIALOGS_UNHIDE, // user pressed F12 - EXTERNAL_CHANGE, // a document was changed by some external means (undo or XML editor); this - // may not be reflected by a selection change and thus needs a separate signal - LAST_SIGNAL -}; +// Inkscape::Application static members +Inkscape::Application * Inkscape::Application::_S_inst = NULL; +bool Inkscape::Application::_crashIsHappening = false; -#define DESKTOP_IS_ACTIVE(d) (inkscape->desktops && ((d) == inkscape->desktops->data)) +#define DESKTOP_IS_ACTIVE(d) (!INKSCAPE._desktops->empty() && ((d) == INKSCAPE._desktops->front())) +static void (* segv_handler) (int) = SIG_DFL; +static void (* abrt_handler) (int) = SIG_DFL; +static void (* fpe_handler) (int) = SIG_DFL; +static void (* ill_handler) (int) = SIG_DFL; +#ifndef WIN32 +static void (* bus_handler) (int) = SIG_DFL; +#endif -/*################################ -# FORWARD DECLARATIONS -################################*/ +#define INKSCAPE_PROFILE_DIR "inkscape" +#define INKSCAPE_PROFILE_DIR_047DEV "Inkscape" +#define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" +#define MENUS_FILE "menus.xml" -static void inkscape_dispose (GObject *object); +#define SP_INDENT 8 -static void inkscape_activate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); -static void inkscape_deactivate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); +#ifdef WIN32 +typedef int uid_t; +#define getuid() 0 +#endif + +/** C++ification TODO list + * - _S_inst should NOT need to be assigned inside the constructor, but if it isn't the Filters+Extensions menus break. + * - Application::_deskops has to be a pointer because of a signal bug somewhere else. Basically, it will attempt to access a deleted object in sp_ui_close_all(), + * but if it's a pointer we can stop and return NULL in Application::active_desktop() + * - These functions are calling Application::create for no good reason I can determine: + * + * Inkscape::UI::Dialog::SVGPreview::SVGPreview() + * src/ui/dialog/filedialogimpl-gtkmm.cpp:542:9 + * void Inkscape::UI::Widget::ImageIcon::init() + * src/ui/widget/imageicon.cpp:93:9 + */ -class AppSelectionModel { - Inkscape::LayerModel _layer_model; - Inkscape::Selection *_selection; +class InkErrorHandler : public Inkscape::ErrorReporter { public: - AppSelectionModel(SPDocument *doc) { - _layer_model.setDocument(doc); - // TODO: is this really how we should manage the lifetime of the selection? - // I just copied this from the initialization of the Selection in SPDesktop. - // When and how is it actually released? - _selection = Inkscape::GC::release(new Inkscape::Selection(&_layer_model, NULL)); + InkErrorHandler(bool useGui) : Inkscape::ErrorReporter(), + _useGui(useGui) + {} + virtual ~InkErrorHandler() {} + + virtual void handleError( Glib::ustring const& primary, Glib::ustring const& secondary ) const + { + if (_useGui) { + Gtk::MessageDialog err(primary, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); + err.set_secondary_text(secondary); + err.run(); + } else { + g_message("%s", primary.data()); + g_message("%s", secondary.data()); + } } - Inkscape::Selection *getSelection() const { return _selection; } +private: + bool _useGui; }; -struct InkscapeApplication { - GObject object; - Inkscape::XML::Document *menus; - std::map<SPDocument *, int> document_set; - std::map<SPDocument *, AppSelectionModel *> selection_models; - GSList *desktops; - gchar *argv0; - gboolean dialogs_toggle; - gboolean use_gui; // may want to consider a virtual function - // for overriding things like the warning dlg's - guint mapalt; - guint trackalt; -}; +void inkscape_ref(Inkscape::Application & in) +{ + in.refCount++; +} -struct InkscapeApplicationClass { - GObjectClass object_class; - - /* Signals */ - void (* change_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); - void (* change_subselection) (InkscapeApplication * inkscape, SPDesktop *desktop); - void (* modify_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection, guint flags); - void (* set_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); - void (* set_eventcontext) (InkscapeApplication * inkscape, Inkscape::UI::Tools::ToolBase * eventcontext); - void (* activate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); - void (* deactivate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); - void (* destroy_document) (InkscapeApplication *inkscape, SPDocument *doc); - void (* color_set) (InkscapeApplication *inkscape, SPColor *color, double opacity); - void (* shut_down) (InkscapeApplication *inkscape); - void (* dialogs_hide) (InkscapeApplication *inkscape); - void (* dialogs_unhide) (InkscapeApplication *inkscape); - void (* external_change) (InkscapeApplication *inkscape); -}; +void inkscape_unref(Inkscape::Application & in) +{ + in.refCount--; + + if (&in == Inkscape::Application::_S_inst) { + if (in.refCount <= 0) { + delete Inkscape::Application::_S_inst; + } + } else { + g_error("Attempt to unref an Application (=%p) not the current instance (=%p) (maybe it's already been destroyed?)", + &in, Inkscape::Application::_S_inst); + } +} -static guint inkscape_signals[LAST_SIGNAL] = {0}; +// Callback passed to g_timeout_add_seconds() +// gets the current instance and calls autosave() +int inkscape_autosave(gpointer) { + g_assert(Inkscape::Application::exists()); + return INKSCAPE.autosave(); +} -static void (* segv_handler) (int) = SIG_DFL; -static void (* abrt_handler) (int) = SIG_DFL; -static void (* fpe_handler) (int) = SIG_DFL; -static void (* ill_handler) (int) = SIG_DFL; -#ifndef WIN32 -static void (* bus_handler) (int) = SIG_DFL; -#endif +namespace Inkscape { -#define INKSCAPE_PROFILE_DIR "inkscape" -#define INKSCAPE_PROFILE_DIR_047DEV "Inkscape" -#define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" -#define MENUS_FILE "menus.xml" +/** + * Defined only for debugging purposes. If we are certain the bugs are gone we can remove this + * and the references in inkscape_ref and inkscape_unref. + */ +Application* +Application::operator &() const +{ + return const_cast<Application*>(this); +} +/** + * Creates a new Inkscape::Application global object. + */ +void +Application::create(const char *argv0, bool use_gui) +{ + if (!Application::exists()) { + new Application(argv0, use_gui); + } else { + g_assert_not_reached(); + } +} -G_DEFINE_TYPE(InkscapeApplication, inkscape, G_TYPE_OBJECT); /** - * Initializes the inkscape class, registering all of its signal handlers - * and virtual functions + * Checks whether the current Inkscape::Application global object exists. */ -static void -inkscape_class_init (InkscapeApplicationClass * klass) +bool +Application::exists() { - GObjectClass * object_class = G_OBJECT_CLASS(klass); - - inkscape_signals[MODIFY_SELECTION] = g_signal_new ("modify_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, modify_selection), - NULL, NULL, - sp_marshal_VOID__POINTER_UINT, - G_TYPE_NONE, 2, - G_TYPE_POINTER, G_TYPE_UINT); - inkscape_signals[CHANGE_SELECTION] = g_signal_new ("change_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, change_selection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[CHANGE_SUBSELECTION] = g_signal_new ("change_subselection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, change_subselection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SET_SELECTION] = g_signal_new ("set_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, set_selection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SET_EVENTCONTEXT] = g_signal_new ("set_eventcontext", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, set_eventcontext), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[ACTIVATE_DESKTOP] = g_signal_new ("activate_desktop", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, activate_desktop), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[DEACTIVATE_DESKTOP] = g_signal_new ("deactivate_desktop", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, deactivate_desktop), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SHUTDOWN_SIGNAL] = g_signal_new ("shut_down", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, shut_down), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[DIALOGS_HIDE] = g_signal_new ("dialogs_hide", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_hide), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[DIALOGS_UNHIDE] = g_signal_new ("dialogs_unhide", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_unhide), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[EXTERNAL_CHANGE] = g_signal_new ("external_change", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, external_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->dispose = inkscape_dispose; - - klass->activate_desktop = inkscape_activate_desktop_private; - klass->deactivate_desktop = inkscape_deactivate_desktop_private; + return Application::_S_inst != NULL; } -#ifdef WIN32 -typedef int uid_t; -#define getuid() 0 -#endif +/** + * Returns the current Inkscape::Application global object. + * \pre Application::_S_inst != NULL + */ +Application& +Application::instance() +{ + if (!exists()) { + g_error("Inkscape::Application does not yet exist."); + } + return *Application::_S_inst; +} /** * static gint inkscape_autosave(gpointer); * - * Callback passed to g_timeout_add_seconds() * Responsible for autosaving all open documents */ -static gint inkscape_autosave(gpointer) +int Application::autosave() { - if (inkscape->document_set.empty()) { // nothing to autosave + if (_document_set.empty()) { // nothing to autosave return TRUE; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -302,7 +238,7 @@ static gint inkscape_autosave(gpointer) } GDir *autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL); - if( !autosave_dir_ptr ){ + if (!autosave_dir_ptr) { // Try to create the autosave directory if it doesn't exist if (g_mkdir(autosave_dir.c_str(), 0755)) { // the creation failed @@ -333,8 +269,8 @@ static gint inkscape_autosave(gpointer) gint docnum = 0; SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents...")); - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { SPDocument *doc = iter->first; @@ -342,7 +278,6 @@ static gint inkscape_autosave(gpointer) ++docnum; Inkscape::XML::Node *repr = doc->getReprRoot(); - // g_debug("Document %d: \"%s\" %s", docnum, doc ? doc->getName() : "(null)", doc ? (doc->isModifiedSinceSave() ? "(dirty)" : "(clean)") : "(null)"); if (doc->isModifiedSinceSave()) { gchar *oldest_autosave = 0; @@ -373,8 +308,6 @@ static gint inkscape_autosave(gpointer) } } - // g_debug("%d previous autosaves exists. Max = %d", count, autosave_max); - // Have we reached the limit for number of autosaves? if ( count >= autosave_max ){ // Remove the oldest file @@ -396,8 +329,6 @@ static gint inkscape_autosave(gpointer) g_free(baseName); baseName = 0; - // g_debug("Filename: %s", full_path); - // Try to save the file FILE *file = Inkscape::IO::fopen_utf8name(full_path, "w"); gchar *errortext = 0; @@ -435,7 +366,7 @@ static gint inkscape_autosave(gpointer) return TRUE; } -void inkscape_autosave_init() +void Application::autosave_init() { static guint32 autosave_timeout_id = 0; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -446,139 +377,149 @@ void inkscape_autosave_init() autosave_timeout_id = 0; } - // g_debug("options.autosave.enable = %d", prefs->getBool("/options/autosave/enable", true)); // Is autosave enabled? if (!prefs->getBool("/options/autosave/enable", true)){ autosave_timeout_id = 0; } else { // Turn on autosave guint32 timeout = prefs->getInt("/options/autosave/interval", 10) * 60; - // g_debug("options.autosave.interval = %d", prefs->getInt("/options/autosave/interval", 10)); autosave_timeout_id = g_timeout_add_seconds(timeout, inkscape_autosave, NULL); } } - -static void -inkscape_init (InkscapeApplication * object) +void Application::argv0(char const* argv) { - if (!inkscape) { - inkscape = (InkscapeApplication *) object; - } else { - g_assert_not_reached (); - } - - new (&inkscape->document_set) std::map<SPDocument *, int>(); - new (&inkscape->selection_models) std::map<SPDocument *, AppSelectionModel *>(); - - inkscape->menus = NULL; - inkscape->desktops = NULL; - inkscape->dialogs_toggle = TRUE; - inkscape->mapalt = GDK_MOD1_MASK; - inkscape->trackalt = FALSE; + _argv0 = g_strdup(argv); } -static void -inkscape_dispose (GObject *object) +/* \brief Constructor for the application. + * Creates a new Inkscape::Application. + * + * \pre Application::_S_inst == NULL + */ + +Application::Application(const char* argv, bool use_gui) : + _menus(NULL), + _desktops(NULL), + refCount(1), + _dialogs_toggle(TRUE), + _mapalt(GDK_MOD1_MASK), + _trackalt(FALSE), + _use_gui(use_gui) { - InkscapeApplication *inkscape = (InkscapeApplication *) object; + /* fixme: load application defaults */ - g_assert (!inkscape->desktops); + segv_handler = signal (SIGSEGV, Application::crash_handler); + abrt_handler = signal (SIGABRT, Application::crash_handler); + fpe_handler = signal (SIGFPE, Application::crash_handler); + ill_handler = signal (SIGILL, Application::crash_handler); +#ifndef WIN32 + bus_handler = signal (SIGBUS, Application::crash_handler); +#endif - Inkscape::Preferences::unload(); + _argv0 = g_strdup(argv); - if (inkscape->menus) { - /* fixme: This is not the best place */ - Inkscape::GC::release(inkscape->menus); - inkscape->menus = NULL; - } + // \TODO: this belongs to Application::init but if it isn't here + // then the Filters and Extensions menus don't work. + _S_inst = this; - inkscape->selection_models.~map(); - inkscape->document_set.~map(); + /* Load the preferences and menus */ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + InkErrorHandler* handler = new InkErrorHandler(use_gui); + prefs->setErrorHandler(handler); + { + Glib::ustring msg; + Glib::ustring secondary; + if (prefs->getLastError( msg, secondary )) { + handler->handleError(msg, secondary); + } + } - G_OBJECT_CLASS (inkscape_parent_class)->dispose (object); + if (use_gui) { + load_menus(); + Inkscape::DeviceManager::getManager().loadConfig(); + } + Inkscape::ResourceManager::getManager(); - gtk_main_quit (); -} + /* set language for user interface according setting in preferences */ + Glib::ustring ui_language = prefs->getString("/ui/language"); + if(!ui_language.empty()) + { + setenv("LANGUAGE", ui_language, 1); + } + /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON. + * Use only if use_gui is enabled + */ +#ifdef WIN32 +#define DEFAULT_LOG_REDIRECT true +#else +#define DEFAULT_LOG_REDIRECT false +#endif -void -inkscape_ref (void) -{ - if (inkscape) - g_object_ref (G_OBJECT (inkscape)); -} + if (use_gui == TRUE && prefs->getBool("/dialogs/debug/redirect", DEFAULT_LOG_REDIRECT)) + { + Inkscape::UI::Dialog::DebugDialog::getInstance()->captureLogMessages(); + } + /* Check for global remapping of Alt key */ + if (use_gui) + { + mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); + trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); + } -void -inkscape_unref (void) -{ - if (inkscape) - g_object_unref (G_OBJECT (inkscape)); -} + /* Initialize the extensions */ + Inkscape::Extension::init(); -/* returns the mask of the keyboard modifier to map to Alt, zero if no mapping */ -/* Needs to be a guint because gdktypes.h does not define a 'no-modifier' value */ -guint -inkscape_mapalt() { - return inkscape->mapalt; + autosave_init(); } -/* Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default */ -void inkscape_mapalt(guint maskvalue) +Application::~Application() { - if(maskvalue<2 || maskvalue> 5 ){ /* MOD5 is the highest defined in gdktypes.h */ - inkscape->mapalt=0; - }else{ - inkscape->mapalt=(GDK_MOD1_MASK << (maskvalue-1)); + if (_desktops) { + g_error("FATAL: desktops still in list on application destruction!"); } -} -guint -inkscape_trackalt() { - return inkscape->trackalt; -} - -void inkscape_trackalt(guint trackvalue) -{ - inkscape->trackalt = trackvalue; -} + Inkscape::Preferences::unload(); + if (_menus) { + Inkscape::GC::release(_menus); + _menus = NULL; + } -static void -inkscape_activate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) -{ - desktop->set_active (true); -} + if (_argv0) { + g_free(_argv0); + _argv0 = NULL; + } + _S_inst = NULL; // this will probably break things -static void -inkscape_deactivate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) -{ - desktop->set_active (false); + refCount = 0; + gtk_main_quit (); } - -/* fixme: This is EVIL, and belongs to main after all */ - -#define SP_INDENT 8 - - -static bool crashIsHappening = false; - -bool inkscapeIsCrashing() +/** Sets the keyboard modifer to map to Alt. + * + * Zero switches off mapping, as does '1', which is the default. + */ +void Application::mapalt(guint maskvalue) { - return crashIsHappening; + if ( maskvalue < 2 || maskvalue > 5 ) { // MOD5 is the highest defined in gdktypes.h + _mapalt = 0; + } else { + _mapalt = (GDK_MOD1_MASK << (maskvalue-1)); + } } -static void -inkscape_crash_handler (int /*signum*/) +void +Application::crash_handler (int /*signum*/) { using Inkscape::Debug::SimpleEvent; using Inkscape::Debug::EventTracker; using Inkscape::Debug::Logger; - static gint recursion = FALSE; + static bool recursion = false; /* * reset all signal handlers: any further crashes should just be allowed @@ -596,9 +537,9 @@ inkscape_crash_handler (int /*signum*/) if (recursion) { abort (); } - recursion = TRUE; + recursion = true; - crashIsHappening = true; + _crashIsHappening = true; EventTracker<SimpleEvent<Inkscape::Debug::Event::CORE> > tracker("crash"); tracker.set<SimpleEvent<> >("emergency-save"); @@ -612,11 +553,11 @@ inkscape_crash_handler (int /*signum*/) gint count = 0; gchar *curdir = g_get_current_dir(); // This one needs to be freed explicitly - gchar *inkscapedir = g_path_get_dirname(INKSCAPE->argv0); // Needs to be freed + gchar *inkscapedir = g_path_get_dirname(INKSCAPE._argv0); // Needs to be freed GSList *savednames = NULL; GSList *failednames = NULL; - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = INKSCAPE._document_set.begin(), e = INKSCAPE._document_set.end(); + iter != e; ++iter) { SPDocument *doc = iter->first; Inkscape::XML::Node *repr; @@ -757,7 +698,7 @@ inkscape_crash_handler (int /*signum*/) } *(b + pos) = '\0'; - if ( inkscape_get_instance() && inkscape_use_gui() ) { + if ( exists() && instance().use_gui() ) { GtkWidget *msgbox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", b); gtk_dialog_run (GTK_DIALOG (msgbox)); gtk_widget_destroy (msgbox); @@ -774,132 +715,19 @@ inkscape_crash_handler (int /*signum*/) /* on exit, allow restored signal handler to take over and crash us */ } - -class InkErrorHandler : public Inkscape::ErrorReporter { -public: - InkErrorHandler(bool useGui) : Inkscape::ErrorReporter(), - _useGui(useGui) - {} - virtual ~InkErrorHandler() {} - - virtual void handleError( Glib::ustring const& primary, Glib::ustring const& secondary ) const - { - if (_useGui) { - Gtk::MessageDialog err(primary, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); - err.set_secondary_text(secondary); - err.run(); - } else { - g_message("%s", primary.data()); - g_message("%s", secondary.data()); - } - } - -private: - bool _useGui; -}; - -void -inkscape_application_init (const gchar *argv0, gboolean use_gui) -{ - inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); - /* fixme: load application defaults */ - - segv_handler = signal (SIGSEGV, inkscape_crash_handler); - abrt_handler = signal (SIGABRT, inkscape_crash_handler); - fpe_handler = signal (SIGFPE, inkscape_crash_handler); - ill_handler = signal (SIGILL, inkscape_crash_handler); -#ifndef WIN32 - bus_handler = signal (SIGBUS, inkscape_crash_handler); -#endif - - inkscape->use_gui = use_gui; - inkscape->argv0 = g_strdup(argv0); - - /* Load the preferences and menus */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - InkErrorHandler* handler = new InkErrorHandler(use_gui); - prefs->setErrorHandler(handler); - { - Glib::ustring msg; - Glib::ustring secondary; - if (prefs->getLastError( msg, secondary )) { - handler->handleError(msg, secondary); - } - } - - if (use_gui) { - inkscape_load_menus(inkscape); - Inkscape::DeviceManager::getManager().loadConfig(); - } - Inkscape::ResourceManager::getManager(); - - /* set language for user interface according setting in preferences */ - Glib::ustring ui_language = prefs->getString("/ui/language"); - if(!ui_language.empty()) - { - setenv("LANGUAGE", ui_language, 1); - } - - /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON. - * Use only if use_gui is enabled - */ -#ifdef WIN32 -#define DEFAULT_LOG_REDIRECT true -#else -#define DEFAULT_LOG_REDIRECT false -#endif - - if (use_gui == TRUE && prefs->getBool("/dialogs/debug/redirect", DEFAULT_LOG_REDIRECT)) - { - Inkscape::UI::Dialog::DebugDialog::getInstance()->captureLogMessages(); - } - - /* Check for global remapping of Alt key */ - if (use_gui) - { - inkscape_mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); - inkscape_trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); - } - - /* Initialize the extensions */ - Inkscape::Extension::init(); - - inkscape_autosave_init(); - - return; -} - -/** - * Returns the current InkscapeApplication global object - */ -InkscapeApplication * -inkscape_get_instance() -{ - return inkscape; -} - -gboolean inkscape_use_gui() -{ - return inkscape_get_instance()->use_gui; -} - /** * Menus management * */ -bool inkscape_load_menus( InkscapeApplication * inkscape ) +bool Application::load_menus() { gchar *fn = profile_path(MENUS_FILE); gchar *menus_xml = 0; gsize len = 0; - if ( inkscape != inkscape_get_instance() ) { - g_warning("BAD BAD BAD THINGS"); - } - if ( g_file_get_contents(fn, &menus_xml, &len, NULL) ) { // load the menus_xml file - inkscape->menus = sp_repr_read_mem(menus_xml, len, NULL); + _menus = sp_repr_read_mem(menus_xml, len, NULL); g_free(menus_xml); menus_xml = 0; @@ -907,146 +735,157 @@ bool inkscape_load_menus( InkscapeApplication * inkscape ) g_free(fn); fn = 0; - if ( !inkscape->menus ) { - inkscape->menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); + if ( !_menus ) { + _menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); } - return (inkscape->menus != NULL); + return (_menus != 0); } void -inkscape_selection_modified (Inkscape::Selection *selection, guint flags) +Application::selection_modified (Inkscape::Selection *selection, guint flags) { g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[MODIFY_SELECTION], 0, selection, flags); + signal_selection_modified.emit(selection, flags); } } void -inkscape_selection_changed (Inkscape::Selection * selection) +Application::selection_changed (Inkscape::Selection * selection) { g_return_if_fail (selection != NULL); - + if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + signal_selection_changed.emit(selection); } } void -inkscape_subselection_changed (SPDesktop *desktop) +Application::subselection_changed (SPDesktop *desktop) { g_return_if_fail (desktop != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SUBSELECTION], 0, desktop); + signal_subselection_changed.emit(desktop); } } void -inkscape_selection_set (Inkscape::Selection * selection) +Application::selection_set (Inkscape::Selection * selection) { g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, selection); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + signal_selection_set.emit(selection); + signal_selection_changed.emit(selection); } } void -inkscape_eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext) +Application::eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext) { g_return_if_fail (eventcontext != NULL); g_return_if_fail (SP_IS_EVENT_CONTEXT (eventcontext)); if (DESKTOP_IS_ACTIVE (eventcontext->desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, eventcontext); + signal_eventcontext_set.emit(eventcontext); } } void -inkscape_add_desktop (SPDesktop * desktop) +Application::add_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); + if (_desktops == NULL) { + _desktops = new std::vector<SPDesktop*>; + } - g_assert (!g_slist_find (inkscape->desktops, desktop)); + if (std::find(_desktops->begin(), _desktops->end(), desktop) != _desktops->end()) { + g_error("Attempted to add desktop already in list."); + } - inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop); + _desktops->insert(_desktops->begin(), desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set.emit(desktop->getSelection()); + signal_selection_changed.emit(desktop->getSelection()); } void -inkscape_remove_desktop (SPDesktop * desktop) +Application::remove_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); - g_assert (g_slist_find (inkscape->desktops, desktop)); + if (std::find (_desktops->begin(), _desktops->end(), desktop) == _desktops->end() ) { + g_error("Attempted to remove desktop not in list."); + } if (DESKTOP_IS_ACTIVE (desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, desktop); - if (inkscape->desktops->next != NULL) { - SPDesktop * new_desktop = static_cast<SPDesktop *>(inkscape->desktops->next->data); - inkscape->desktops = g_slist_remove (inkscape->desktops, new_desktop); - inkscape->desktops = g_slist_prepend (inkscape->desktops, new_desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, new_desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, new_desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (new_desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (new_desktop)); + signal_deactivate_desktop.emit(desktop); + if (_desktops->size() > 1) { + SPDesktop * new_desktop = *(++_desktops->begin()); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), new_desktop)); + _desktops->insert(_desktops->begin(), new_desktop); + + signal_activate_desktop.emit(new_desktop); + signal_eventcontext_set.emit(new_desktop->getEventContext()); + signal_selection_set.emit(new_desktop->getSelection()); + signal_selection_changed.emit(new_desktop->getSelection()); } else { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, NULL); - if (sp_desktop_selection(desktop)) - sp_desktop_selection(desktop)->clear(); + signal_eventcontext_set.emit(NULL); + if (desktop->getSelection()) + desktop->getSelection()->clear(); } } - inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), desktop)); // if this was the last desktop, shut down the program - if (inkscape->desktops == NULL) { - inkscape_exit (inkscape); + if (_desktops->empty()) { + this->exit(); + delete _desktops; + _desktops = NULL; } } void -inkscape_activate_desktop (SPDesktop * desktop) +Application::activate_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { return; } - g_assert (g_slist_find (inkscape->desktops, desktop)); + std::vector<SPDesktop*>::iterator i; + + if ((i = std::find (_desktops->begin(), _desktops->end(), desktop)) == _desktops->end()) { + g_error("Tried to activate desktop not added to list."); + } - SPDesktop *current = static_cast<SPDesktop *>(inkscape->desktops->data); + SPDesktop *current = _desktops->front(); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, current); + signal_deactivate_desktop.emit(current); - inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); - inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop); + _desktops->erase (i); + _desktops->insert (_desktops->begin(), desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set(desktop->getSelection()); + signal_selection_changed(desktop->getSelection()); } @@ -1054,65 +893,62 @@ inkscape_activate_desktop (SPDesktop * desktop) * Resends ACTIVATE_DESKTOP for current desktop; needed when a new desktop has got its window that dialogs will transientize to */ void -inkscape_reactivate_desktop (SPDesktop * desktop) +Application::reactivate_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); - if (DESKTOP_IS_ACTIVE (desktop)) - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); + if (DESKTOP_IS_ACTIVE (desktop)) { + signal_activate_desktop.emit(desktop); + } } SPDesktop * -inkscape_find_desktop_by_dkey (unsigned int dkey) +Application::find_desktop_by_dkey (unsigned int dkey) { - for (GSList *r = inkscape->desktops; r; r = r->next) { - if ((static_cast<SPDesktop *>(r->data))->dkey == dkey){ - return (static_cast<SPDesktop *>(r->data)); + for (std::vector<SPDesktop*>::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { + if ((*r)->dkey == dkey){ + return *r; } } return NULL; } - - -static unsigned int -inkscape_maximum_dkey() +unsigned int +Application::maximum_dkey() { unsigned int dkey = 0; - for (GSList *r = inkscape->desktops; r; r = r->next) { - if ((static_cast<SPDesktop *>(r->data))->dkey > dkey){ - dkey = (static_cast<SPDesktop *>(r->data))->dkey; + for (std::vector<SPDesktop*>::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { + if ((*r)->dkey > dkey){ + dkey = (*r)->dkey; } } - return dkey; } -static SPDesktop * -inkscape_next_desktop () +SPDesktop * +Application::next_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (static_cast<SPDesktop *>(inkscape->desktops->data))->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; - if (dkey_current < inkscape_maximum_dkey()) { + if (dkey_current < maximum_dkey()) { // find next existing - for (unsigned int i = dkey_current + 1; i <= inkscape_maximum_dkey(); i++) { - d = inkscape_find_desktop_by_dkey (i); + for (unsigned int i = dkey_current + 1; i <= maximum_dkey(); ++i) { + d = find_desktop_by_dkey (i); if (d) { break; } } } else { // find first existing - for (unsigned int i = 0; i <= inkscape_maximum_dkey(); i++) { - d = inkscape_find_desktop_by_dkey (i); + for (unsigned int i = 0; i <= maximum_dkey(); ++i) { + d = find_desktop_by_dkey (i); if (d) { break; } @@ -1120,22 +956,21 @@ inkscape_next_desktop () } g_assert (d); - return d; } -static SPDesktop * -inkscape_prev_desktop () +SPDesktop * +Application::prev_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (static_cast<SPDesktop *>(inkscape->desktops->data))->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; if (dkey_current > 0) { // find prev existing - for (signed int i = dkey_current - 1; i >= 0; i--) { - d = inkscape_find_desktop_by_dkey (i); + for (signed int i = dkey_current - 1; i >= 0; --i) { + d = find_desktop_by_dkey (i); if (d) { break; } @@ -1143,81 +978,74 @@ inkscape_prev_desktop () } if (!d) { // find last existing - d = inkscape_find_desktop_by_dkey (inkscape_maximum_dkey()); + d = find_desktop_by_dkey (maximum_dkey()); } g_assert (d); - return d; } void -inkscape_switch_desktops_next () +Application::switch_desktops_next () { - inkscape_next_desktop()->presentWindow(); + next_desktop()->presentWindow(); } - - void -inkscape_switch_desktops_prev () +Application::switch_desktops_prev() { - inkscape_prev_desktop()->presentWindow(); + prev_desktop()->presentWindow(); } - - void -inkscape_dialogs_hide () +Application::dialogs_hide() { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_HIDE], 0); - inkscape->dialogs_toggle = FALSE; + signal_dialogs_hide.emit(); + _dialogs_toggle = false; } void -inkscape_dialogs_unhide () +Application::dialogs_unhide() { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_UNHIDE], 0); - inkscape->dialogs_toggle = TRUE; + signal_dialogs_unhide.emit(); + _dialogs_toggle = true; } void -inkscape_dialogs_toggle () +Application::dialogs_toggle() { - if (inkscape->dialogs_toggle) { - inkscape_dialogs_hide (); + if (_dialogs_toggle) { + dialogs_hide(); } else { - inkscape_dialogs_unhide (); + dialogs_unhide(); } } void -inkscape_external_change () +Application::external_change() { - g_return_if_fail (inkscape != NULL); - - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[EXTERNAL_CHANGE], 0); + signal_external_change.emit(); } /** * fixme: These need probably signals too */ void -inkscape_add_document (SPDocument *document) +Application::add_document (SPDocument *document) { g_return_if_fail (document != NULL); // try to insert the pair into the list - if (!(inkscape->document_set.insert(std::make_pair(document, 1)).second)) { + if (!(_document_set.insert(std::make_pair(document, 1)).second)) { //insert failed, this key (document) is already in the list - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, increase its count @@ -1227,10 +1055,10 @@ inkscape_add_document (SPDocument *document) } else { // insert succeeded, this document is new. Do we need to create a // selection model for it, i.e. are we running without a desktop? - if (!inkscape->use_gui) { + if (!_use_gui) { // Create layer model and selection model so we can run some verbs without a GUI - g_assert(inkscape->selection_models.find(document) == inkscape->selection_models.end()); - inkscape->selection_models[document] = new AppSelectionModel(document); + g_assert(_selection_models.find(document) == _selection_models.end()); + _selection_models[document] = new AppSelectionModel(document); } } } @@ -1238,24 +1066,24 @@ inkscape_add_document (SPDocument *document) // returns true if this was last reference to this document, so you can delete it bool -inkscape_remove_document (SPDocument *document) +Application::remove_document (SPDocument *document) { g_return_val_if_fail (document != NULL, false); - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument *,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, decrease its count iter->second --; if (iter->second < 1) { // this was the last one, remove the pair from list - inkscape->document_set.erase (iter); + _document_set.erase (iter); // also remove the selection model - std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = inkscape->selection_models.find(document); - if (sel_iter != inkscape->selection_models.end()) { - inkscape->selection_models.erase(sel_iter); + std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = _selection_models.find(document); + if (sel_iter != _selection_models.end()) { + _selection_models.erase(sel_iter); } return true; @@ -1269,37 +1097,38 @@ inkscape_remove_document (SPDocument *document) } SPDesktop * -inkscape_active_desktop (void) +Application::active_desktop() { - if (inkscape->desktops == NULL) { + if (!_desktops || _desktops->empty()) { return NULL; } - return static_cast<SPDesktop *>(inkscape->desktops->data); + return _desktops->front(); } SPDocument * -inkscape_active_document (void) +Application::active_document() { if (SP_ACTIVE_DESKTOP) { - return sp_desktop_document (SP_ACTIVE_DESKTOP); - } else if (!inkscape->document_set.empty()) { + return SP_ACTIVE_DESKTOP->getDocument(); + } else if (!_document_set.empty()) { // If called from the command line there will be no desktop // So 'fall back' to take the first listed document in the Inkscape instance - return inkscape->document_set.begin()->first; + return _document_set.begin()->first; } return NULL; } -bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop) { +bool +Application::sole_desktop_for_document(SPDesktop const &desktop) { SPDocument const* document = desktop.doc(); if (!document) { return false; } - for ( GSList *iter = inkscape->desktops ; iter ; iter = iter->next ) { - SPDesktop *other_desktop=static_cast<SPDesktop *>(iter->data); - SPDocument *other_document=other_desktop->doc(); + for ( std::vector<SPDesktop*>::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e; ++iter ) { + SPDesktop *other_desktop = *iter; + SPDocument *other_document = other_desktop->doc(); if ( other_document == document && other_desktop != &desktop ) { return false; } @@ -1308,7 +1137,7 @@ bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop) { } Inkscape::UI::Tools::ToolBase * -inkscape_active_event_context (void) +Application::active_event_context (void) { if (SP_ACTIVE_DESKTOP) { return SP_ACTIVE_DESKTOP->getEventContext(); @@ -1318,34 +1147,36 @@ inkscape_active_event_context (void) } Inkscape::ActionContext -inkscape_active_action_context() +Application::active_action_context() { if (SP_ACTIVE_DESKTOP) { return Inkscape::ActionContext(SP_ACTIVE_DESKTOP); } - SPDocument *doc = inkscape_active_document(); + SPDocument *doc = active_document(); if (!doc) { return Inkscape::ActionContext(); } - return inkscape_action_context_for_document(doc); + return action_context_for_document(doc); } Inkscape::ActionContext -inkscape_action_context_for_document(SPDocument *doc) +Application::action_context_for_document(SPDocument *doc) { // If there are desktops, check them first to see if the document is bound to one of them - for (GSList *iter = inkscape->desktops ; iter ; iter = iter->next) { - SPDesktop *desktop=static_cast<SPDesktop *>(iter->data); - if (desktop->doc() == doc) { - return Inkscape::ActionContext(desktop); + if (_desktops != NULL) { + for (std::vector<SPDesktop*>::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e ; ++iter) { + SPDesktop *desktop = *iter; + if (desktop->doc() == doc) { + return Inkscape::ActionContext(desktop); + } } } // Document is not associated with any desktops - maybe we're in command-line mode - std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = inkscape->selection_models.find(doc); - if (sel_iter == inkscape->selection_models.end()) { + std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = _selection_models.find(doc); + if (sel_iter == _selection_models.end()) { return Inkscape::ActionContext(); } return Inkscape::ActionContext(sel_iter->second->getSelection()); @@ -1357,10 +1188,10 @@ inkscape_action_context_for_document(SPDocument *doc) #####################*/ void -inkscape_refresh_display (InkscapeApplication *inkscape) +Application::refresh_display () { - for (GSList *l = inkscape->desktops; l != NULL; l = l->next) { - (static_cast<Inkscape::UI::View::View*>(l->data))->requestRedraw(); + for (std::vector<SPDesktop*>::iterator l = _desktops->begin(), e = _desktops->end(); l != e; ++l) { + (*l)->requestRedraw(); } } @@ -1370,26 +1201,26 @@ inkscape_refresh_display (InkscapeApplication *inkscape) * saves the preferences if appropriate, and quits. */ void -inkscape_exit (InkscapeApplication */*inkscape*/) +Application::exit () { - g_assert (INKSCAPE); - //emit shutdown signal so that dialogs could remember layout - g_signal_emit (G_OBJECT (INKSCAPE), inkscape_signals[SHUTDOWN_SIGNAL], 0); + signal_shut_down.emit(); Inkscape::Preferences::unload(); gtk_main_quit (); } char * -homedir_path(const char *filename) +Application::homedir_path(const char *filename) { static const gchar *homedir = NULL; if (!homedir) { homedir = g_get_home_dir(); } if (!homedir) { - homedir = g_path_get_dirname(INKSCAPE->argv0); + if (Application::exists()) { + homedir = g_path_get_dirname(Application::instance()._argv0); + } } return g_build_filename(homedir, filename, NULL); } @@ -1400,7 +1231,7 @@ homedir_path(const char *filename) * file should be located. */ gchar * -profile_path(const char *filename) +Application::profile_path(const char *filename) { static const gchar *prefdir = NULL; @@ -1512,21 +1343,21 @@ profile_path(const char *filename) } Inkscape::XML::Node * -inkscape_get_menus (InkscapeApplication * inkscape) +Application::get_menus() { - Inkscape::XML::Node *repr = inkscape->menus->root(); + Inkscape::XML::Node *repr = _menus->root(); g_assert (!(strcmp (repr->name(), "inkscape"))); return repr->firstChild(); } void -inkscape_get_all_desktops(std::list< SPDesktop* >& listbuf) +Application::get_all_desktops(std::list< SPDesktop* >& listbuf) { - for(GSList* l = inkscape->desktops; l != NULL; l = l->next) { - listbuf.push_back(static_cast< SPDesktop* >(l->data)); - } + listbuf.insert(listbuf.end(), _desktops->begin(), _desktops->end()); } +} // namespace Inkscape + /* Local Variables: mode:c++ diff --git a/src/inkscape.h b/src/inkscape.h index 3a9b85fc9..fe424377c 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -6,116 +6,220 @@ * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> + * Liam P. White <inkscapebrony@gmail.com> * - * Copyright (C) 1999-2003 Authors + * Copyright (C) 1999-2014 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <list> +#include <map> +#include <vector> #include <glib.h> +#include <glib-object.h> +#include <sigc++/signal.h> +#include "layer-model.h" +#include "selection.h" class SPDesktop; class SPDocument; +struct SPColor; namespace Inkscape { + +class Application; namespace UI { namespace Tools { class ToolBase; -} -} -} - -struct InkscapeApplication; - -namespace Inkscape { - class ActionContext; - namespace XML { - class Node; - struct Document; - } -} - -#define INKSCAPE inkscape_get_instance() - -void inkscape_autosave_init(); - -void inkscape_application_init (const gchar *argv0, gboolean use_gui); - -bool inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, const gchar *e_notsp, const gchar *warn); - -/* Menus */ -bool inkscape_load_menus (InkscapeApplication * inkscape); -bool inkscape_save_menus (InkscapeApplication * inkscape); -Inkscape::XML::Node *inkscape_get_menus (InkscapeApplication * inkscape); - -InkscapeApplication *inkscape_get_instance(); -gboolean inkscape_use_gui(); - -bool inkscapeIsCrashing(); +} // namespace Tools +} // namespace UI -SPDesktop * inkscape_find_desktop_by_dkey (unsigned int dkey); +class ActionContext; -#define SP_ACTIVE_EVENTCONTEXT inkscape_active_event_context () -Inkscape::UI::Tools::ToolBase * inkscape_active_event_context (void); +namespace XML { +class Node; +struct Document; +} // namespace XML -#define SP_ACTIVE_DOCUMENT inkscape_active_document () -SPDocument * inkscape_active_document (void); +} // namespace Inkscape -#define SP_ACTIVE_DESKTOP inkscape_active_desktop () -SPDesktop * inkscape_active_desktop (void); +void inkscape_ref (Inkscape::Application & in); +void inkscape_unref(Inkscape::Application & in); -// Use this function to get selection model etc for a document, if possible! -// The "active" alternative below has all the horrible static cling of a singleton. -Inkscape::ActionContext -inkscape_action_context_for_document(SPDocument *doc); +#define INKSCAPE (Inkscape::Application::instance()) +#define SP_ACTIVE_EVENTCONTEXT (INKSCAPE.active_event_context()) +#define SP_ACTIVE_DOCUMENT (INKSCAPE.active_document()) +#define SP_ACTIVE_DESKTOP (INKSCAPE.active_desktop()) -// More horrible static cling... sorry about this. Should really replace all of -// the static stuff with a single instance of some kind of engine class holding -// all the document / non-GUI stuff, and an optional GUI class that behaves a -// bit like SPDesktop does currently. Then it will be easier to write good code -// that doesn't just expect a GUI all the time (like lots of the app currently -// does). -// Also, while the "active" document / desktop concepts are convenient, they -// appear to have been abused somewhat, further increasing static cling. -Inkscape::ActionContext inkscape_active_action_context(); +class AppSelectionModel { + Inkscape::LayerModel _layer_model; + Inkscape::Selection *_selection; -bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop); +public: + AppSelectionModel(SPDocument *doc) { + _layer_model.setDocument(doc); + // TODO: is this really how we should manage the lifetime of the selection? + // I just copied this from the initialization of the Selection in SPDesktop. + // When and how is it actually released? + _selection = Inkscape::GC::release(new Inkscape::Selection(&_layer_model, NULL)); + } -gchar *homedir_path(const char *filename); -gchar *profile_path(const char *filename); + Inkscape::Selection *getSelection() const { return _selection; } +}; -/* Inkscape desktop stuff */ -void inkscape_activate_desktop (SPDesktop * desktop); -void inkscape_switch_desktops_next (); -void inkscape_switch_desktops_prev (); -void inkscape_get_all_desktops (std::list< SPDesktop* >& listbuf); - -void inkscape_dialogs_hide (); -void inkscape_dialogs_unhide (); -void inkscape_dialogs_toggle (); - -void inkscape_external_change (); -void inkscape_subselection_changed (SPDesktop *desktop); - -/* Moved document add/remove functions into public inkscape.h as they are used - (rightly or wrongly) by console-mode functions */ -void inkscape_add_document (SPDocument *document); -bool inkscape_remove_document (SPDocument *document); - -/* - * fixme: This has to be rethought - */ - -void inkscape_refresh_display (InkscapeApplication *inkscape); - -/* - * fixme: This also - */ +namespace Inkscape { -void inkscape_exit (InkscapeApplication *inkscape); +class Application { +public: + static Application& instance(); + static bool exists(); + static void create(const char* argv0, bool use_gui); + + // returns the mask of the keyboard modifier to map to Alt, zero if no mapping + // Needs to be a guint because gdktypes.h does not define a 'no-modifier' value + guint mapalt() const { return _mapalt; } + + // Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default + void mapalt(guint maskvalue); + + guint trackalt() const { return _trackalt; } + void trackalt(guint trackvalue) { _trackalt = trackvalue; } + + bool use_gui() const { return _use_gui; } + void use_gui(gboolean guival) { _use_gui = guival; } + + char const* argv0() const { return _argv0; } + void argv0(char const *); + + // no setter for this -- only we can control this variable + static bool isCrashing() { return _crashIsHappening; } + + // useful functions + void autosave_init(); + void application_init (const gchar *argv0, gboolean use_gui); + void load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, + unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, + const gchar *e_notsp, const gchar *warn); + + bool load_menus(); + bool save_menus(); + Inkscape::XML::Node * get_menus(); + + Inkscape::UI::Tools::ToolBase * active_event_context(); + SPDocument * active_document(); + SPDesktop * active_desktop(); + + // Use this function to get selection model etc for a document + Inkscape::ActionContext action_context_for_document(SPDocument *doc); + Inkscape::ActionContext active_action_context(); + + bool sole_desktop_for_document(SPDesktop const &desktop); + + // Inkscape desktop stuff + void add_desktop(SPDesktop * desktop); + void remove_desktop(SPDesktop* desktop); + void activate_desktop (SPDesktop * desktop); + void switch_desktops_next (); + void switch_desktops_prev (); + void get_all_desktops (std::list< SPDesktop* >& listbuf); + void reactivate_desktop (SPDesktop * desktop); + SPDesktop * find_desktop_by_dkey (unsigned int dkey); + unsigned int maximum_dkey(); + SPDesktop * next_desktop (); + SPDesktop * prev_desktop (); + + void dialogs_hide (); + void dialogs_unhide (); + void dialogs_toggle (); + + void external_change (); + void selection_modified (Inkscape::Selection *selection, guint flags); + void selection_changed (Inkscape::Selection * selection); + void subselection_changed (SPDesktop *desktop); + void selection_set (Inkscape::Selection * selection); + + void eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext); + + // Moved document add/remove functions into public inkscape.h as they are used + // (rightly or wrongly) by console-mode functions + void add_document (SPDocument *document); + bool remove_document (SPDocument *document); + + static char *homedir_path(const char *filename); + static char *profile_path(const char *filename); + + // fixme: This has to be rethought + void refresh_display (); + + // fixme: This also + void exit (); + + static void crash_handler(int signum); + + int autosave(); + + // nobody should be accessing our reference count, so it's made private. + friend void ::inkscape_ref (Application & in); + friend void ::inkscape_unref(Application & in); + + // signals + + // one of selections changed + sigc::signal<void, Inkscape::Selection *> signal_selection_changed; + // one of subselections (text selection, gradient handle, etc) changed + sigc::signal<void, SPDesktop *> signal_subselection_changed; + // one of selections modified + sigc::signal<void, Inkscape::Selection *, guint /*flags*/> signal_selection_modified; + // one of selections set + sigc::signal<void, Inkscape::Selection *> signal_selection_set; + // tool switched + sigc::signal<void, Inkscape::UI::Tools::ToolBase * /*eventcontext*/> signal_eventcontext_set; + // some desktop got focus + sigc::signal<void, SPDesktop *> signal_activate_desktop; + // some desktop lost focus + sigc::signal<void, SPDesktop *> signal_deactivate_desktop; + + // these are orphaned signals (nothing emits them and nothing connects to them) + sigc::signal<void, SPDocument *> signal_destroy_document; + sigc::signal<void, SPColor *, double /*opacity*/> signal_color_set; + + // inkscape is quitting + sigc::signal<void> signal_shut_down; + // user pressed F12 + sigc::signal<void> signal_dialogs_hide; + // user pressed F12 + sigc::signal<void> signal_dialogs_unhide; + // a document was changed by some external means (undo or XML editor); this + // may not be reflected by a selection change and thus needs a separate signal + sigc::signal<void> signal_external_change; + +private: + static Inkscape::Application * _S_inst; + + Application(const char* argv0, bool use_gui); + ~Application(); + + Application(Application const&); // no copy + Application& operator=(Application const&); // no assign + Application* operator&() const; // no pointer access + + Inkscape::XML::Document * _menus; + std::map<SPDocument *, int> _document_set; + std::map<SPDocument *, AppSelectionModel *> _selection_models; + std::vector<SPDesktop *> * _desktops; + + unsigned refCount; + bool _dialogs_toggle; + guint _mapalt; + guint _trackalt; + char * _argv0; + static bool _crashIsHappening; + bool _use_gui; +}; + +} // namespace Inkscape #endif diff --git a/src/inkview.cpp b/src/inkview.cpp index 2969bb140..0b7b4d35c 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -60,9 +60,7 @@ #include "io/inkjar.h" #endif -#include "inkscape-private.h" - -InkscapeApplication *inkscape; +#include "inkscape.h" #include <iostream> @@ -232,7 +230,8 @@ main (int argc, const char **argv) ss.view = NULL; ss.fullscreen = false; - inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); + Inkscape::Application::create(argv[0], true); + //Inkscape::Application &inkscape = Inkscape::Application::instance(); // starting at where the commandline options stopped parsing because // we want all the files to be in the list diff --git a/src/io/resource.cpp b/src/io/resource.cpp index ac1c5f06b..501eab03b 100644 --- a/src/io/resource.cpp +++ b/src/io/resource.cpp @@ -73,7 +73,7 @@ Util::ptr_shared<char> get_path(Domain domain, Type type, char const *filename) case TEMPLATES: name = "templates"; break; default: return get_path(SYSTEM, type, filename); } - path = profile_path(name); + path = Inkscape::Application::profile_path(name); } break; } diff --git a/src/knot.cpp b/src/knot.cpp index 4118873c1..b3813ab53 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -19,7 +19,7 @@ #include <glibmm/i18n.h> #include "display/sodipodi-ctrl.h" #include "desktop.h" -#include "desktop-handles.h" + #include "knot.h" #include "knot-ptr.h" #include "document.h" @@ -109,7 +109,7 @@ SPKnot::SPKnot(SPDesktop *desktop, gchar const *tip) this->tip = g_strdup (tip); } - this->item = sp_canvas_item_new(sp_desktop_controls (desktop), + this->item = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, @@ -342,7 +342,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot knot->ungrabbed_signal.emit(knot, event->button.state); - DocumentUndo::undo(sp_desktop_document(knot->desktop)); + DocumentUndo::undo(knot->desktop->getDocument()); knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); transform_escaped = true; consumed = TRUE; diff --git a/src/layer-manager.cpp b/src/layer-manager.cpp index c02d75d16..b1e365fe2 100644 --- a/src/layer-manager.cpp +++ b/src/layer-manager.cpp @@ -15,7 +15,7 @@ #include "gc-finalized.h" #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "layer-manager.h" #include "preferences.h" #include "ui/view/view.h" @@ -154,7 +154,7 @@ void LayerManager::setCurrentLayer( SPObject* obj ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/selection/layerdeselect", true)) { - sp_desktop_selection( _desktop )->clear(); + _desktop->getSelection()->clear(); } } } diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7eb53446f..beff3734b 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -344,7 +344,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (char_attributes.is_mandatory_break && span->end != span->start) { *last_emergency_break_span = *last_break_span = *span; - TRACE(("span %d end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("span %ld end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } @@ -362,7 +362,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } // todo: break between chars if necessary (ie no word breaks present) when doing rectangular flowing - // sum the glyph widths, letter spacing and word spacing to get the character width + // sum the glyph widths, letter spacing, word spacing, and textLength adjustment to get the character width double char_width = 0.0; while (span->end_glyph_index < (unsigned)span->end.iter_span->glyph_string->num_glyphs && span->end.iter_span->glyph_string->log_clusters[span->end_glyph_index] <= (int)span->end.char_byte) { @@ -373,9 +373,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->end_glyph_index++; } if (char_attributes.is_cursor_position) - char_width += text_source->style->letter_spacing.computed; + char_width += text_source->style->letter_spacing.computed * _flow.getTextLengthMultiplierDue(); if (char_attributes.is_white) - char_width += text_source->style->word_spacing.computed; + char_width += text_source->style->word_spacing.computed * _flow.getTextLengthMultiplierDue(); + char_width += _flow.getTextLengthIncrementDue(); span->width += char_width; IFTRACE(char_count++); @@ -400,13 +401,13 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->word_spacing = text_source->style->word_spacing.computed; if (test_width > maximum_width && !char_attributes.is_white) { // whitespaces don't matter, we can put as many as we want at eol - TRACE(("span %d exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("span %ld exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } } while (span->end.char_byte != 0); // while we haven't wrapped to the next span - TRACE(("fitted span %d width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("fitted span %ld width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return true; } @@ -661,6 +662,14 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_glyph.in_character = _flow._characters.size(); new_glyph.rotation = glyph_rotate; + // We may have scaled font size to fit textLength; now, if + // @lengthAdjust=spacingAndGlyphs, this scaling must be only horizontal, + // not vertical, so we unscale it back vertically during output + if (_flow.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS) + new_glyph.vertical_scale = 1.0 / _flow.getTextLengthMultiplierDue(); + else + new_glyph.vertical_scale = 1.0; + /* put something like this back in when we do glyph-rotation-horizontal/vertical if (new_span.block_progression == LEFT_TO_RIGHT || new_span.block_progression == RIGHT_TO_LEFT) { new_glyph.x += new_span.line_height.ascent; @@ -704,6 +713,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ // create the Layout::Character(s) double advance_width = new_glyph.width; if (newcluster){ + newcluster = 0; // find where the text ends for this log_cluster end_byte = it_span->start.iter_span->text_bytes; // Upper limit for(int next_glyph_index = glyph_index+1; next_glyph_index < unbroken_span.glyph_string->num_glyphs; next_glyph_index++){ @@ -742,27 +752,25 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_character.in_glyph = _flow._glyphs.size() - 1; _flow._characters.push_back(new_character); if (new_character.char_attributes.is_white) - advance_width += text_source->style->word_spacing.computed + add_to_each_whitespace; // justification + advance_width += text_source->style->word_spacing.computed * _flow.getTextLengthMultiplierDue() + add_to_each_whitespace; // justification if (new_character.char_attributes.is_cursor_position) - advance_width += text_source->style->letter_spacing.computed; + advance_width += text_source->style->letter_spacing.computed * _flow.getTextLengthMultiplierDue(); + advance_width += _flow.getTextLengthIncrementDue(); iter_source_text++; char_index_in_unbroken_span++; char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); log_cluster_size_chars--; } - if (newcluster){ - advance_width *= direction_sign; - if (new_span.direction != para.direction) { - counter_directional_width_remaining -= advance_width; - x -= advance_width; - x_in_span_last -= advance_width; - } else { - x += advance_width; - x_in_span_last += advance_width; - } + advance_width *= direction_sign; + if (new_span.direction != para.direction) { + counter_directional_width_remaining -= advance_width; + x -= advance_width; + x_in_span_last -= advance_width; + } else { + x += advance_width; + x_in_span_last += advance_width; } - newcluster = 0; } } else if (_flow._input_stream[unbroken_span.input_index]->Type() == CONTROL_CODE) { x += static_cast<InputStreamControlCode const *>(_flow._input_stream[unbroken_span.input_index])->width; @@ -1080,7 +1088,9 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font bool compareGlyphWidth(const PangoGlyphInfo &a, const PangoGlyphInfo &b) { - return (a.geometry.width > b.geometry.width); + bool retval = false; + if ( b.geometry.width == 0 && (a.geometry.width > 0))retval = true; + return (retval); } @@ -1111,13 +1121,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const UnbrokenSpan new_span; new_span.pango_item_index = -1; new_span.input_index = input_index; - new_span.line_height.ascent = control_code->ascent; - new_span.line_height.descent = control_code->descent; + new_span.line_height.ascent = control_code->ascent * _flow.getTextLengthMultiplierDue(); + new_span.line_height.descent = control_code->descent * _flow.getTextLengthMultiplierDue(); new_span.line_height.leading = 0.0; new_span.text_bytes = 0; new_span.char_index_in_para = char_index_in_para; para->unbroken_spans.push_back(new_span); - TRACE(("add gap span %d\n", para->unbroken_spans.size() - 1)); + TRACE(("add gap span %lu\n", para->unbroken_spans.size() - 1)); } } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE && pango_item_index < para->pango_items.size()) { Layout::InputStreamTextSource const *text_source = static_cast<Layout::InputStreamTextSource const *>(_flow._input_stream[input_index]); @@ -1154,13 +1164,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const if (_block_progression == TOP_TO_BOTTOM || _block_progression == BOTTOM_TO_TOP) { if (text_source->x.size() > char_index_in_source) new_span.x = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.y = text_source->y[char_index_in_source]; - if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source]; - if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); + if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); } else { if (text_source->x.size() > char_index_in_source) new_span.y = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.x = text_source->y[char_index_in_source]; - if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source]; - if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); + if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); } if (text_source->rotate.size() > char_index_in_source) new_span.rotate = text_source->rotate[char_index_in_source]; else if (char_index_in_source == 0) new_span.rotate = 0.f; @@ -1189,7 +1199,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const } // now we know the length, do some final calculations and add the UnbrokenSpan to the list - new_span.font_size = text_source->styleComputeFontSize(); + new_span.font_size = text_source->styleComputeFontSize() * _flow.getTextLengthMultiplierDue(); if (new_span.text_bytes) { new_span.glyph_string = pango_glyph_string_new(); /* Some assertions intended to help diagnose bug #1277746. */ @@ -1227,13 +1237,27 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const /* CAREFUL, within a log_cluster the order of glyphs may not map 1:1, or even in the same order, to the original unicode characters!!! Among - other things, diacritical mark glyphs can end up in front of the base - character. That makes determining kerning, even approximately, difficult - later on. To resolve this somewhat sort the glyphs with the same - log_cluster into descending order by width. In theory there should be 1 - that is nonzero, and N that are zero. The order of the zero width ones - does not matter. Sort the glyphs before copying. If ligatures other than with - Mark, nonspacing are ever implemented in Pango this will screw up, for instance + other things, diacritical mark glyphs can end up sequentially in front of the base + character glyph. That makes determining kerning, even approximately, difficult + later on. + + To resolve this to the extent possible sort the glyphs within the same + log_cluster into descending order by width in a special manner before copying. Diacritical marks + and similar have zero width and the glyph they modify has nonzero width. The order + of the zero width ones does not matter. A logical cluster is sorted into sequential order + [base] [zw_modifier1] [zw_modifier2] + where all the modifiers have zero width and the base does not. This works for languages like Hebrew. + + Pango also creates log clusters for languages like Telugu having many glyphs with nonzero widths. + Since these are nonzero, their order is not modified. + + If some language mixes these modes, having a log cluster having something like + [base1] [zw_modifier1] [base2] [zw_modifier2] + the result will be incorrect: + base1] [base2] [zw_modifier1] [zw_modifier2] + + + If ligatures other than with Mark, nonspacing are ever implemented in Pango this will screw up, for instance changing "fi" to "if". */ if(j - i){ @@ -1258,6 +1282,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const while( (j < nglyphs-1) && (new_span.glyph_string->log_clusters[j+1] == new_span.glyph_string->log_clusters[i]) )j++; + /* see note in preceding section */ if(j - i){ std::sort(&(new_span.glyph_string->glyphs[i]), &(new_span.glyph_string->glyphs[j+1]), compareGlyphWidth); } @@ -1274,7 +1299,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.baseline_shift = text_source->style->baseline_shift.computed; // TODO: metrics for vertical text - TRACE(("add text span %d \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); + TRACE(("add text span %lu \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); TRACE((" %d glyphs\n", new_span.glyph_string->num_glyphs)); } else { // if there's no text we still need to initialise the styles @@ -1287,7 +1312,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.line_height.setZero(); new_span.line_height_multiplier = 1.0; } - TRACE(("add style init span %d\n", para->unbroken_spans.size())); + TRACE(("add style init span %lu\n", para->unbroken_spans.size())); } para->unbroken_spans.push_back(new_span); @@ -1323,7 +1348,7 @@ bool Layout::Calculator::_goToNextWrapShape() _current_shape_index++; if (_current_shape_index == _flow._input_wrap_shapes.size()) return false; _scanline_maker = new ShapeScanlineMaker(_flow._input_wrap_shapes[_current_shape_index].shape, _block_progression); - TRACE(("begin wrap shape %d\n", _current_shape_index)); + TRACE(("begin wrap shape %u\n", _current_shape_index)); return true; } @@ -1381,7 +1406,7 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, scan_runs = _scanline_maker->makeScanline(*line_height); } - TRACE(("finding line fit y=%f, %d scan runs\n", scan_runs.front().y, scan_runs.size())); + TRACE(("finding line fit y=%f, %lu scan runs\n", scan_runs.front().y, scan_runs.size())); chunk_info->clear(); chunk_info->reserve(scan_runs.size()); if (para.direction == RIGHT_TO_LEFT) std::reverse(scan_runs.begin(), scan_runs.end()); @@ -1480,7 +1505,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } } - TRACE(("chunk complete, used %f width (%d whitespaces, %d brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); + TRACE(("chunk complete, used %f width (%d whitespaces, %lu brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); chunk_info->push_back(new_chunk); if (scan_run.width() >= 4.0 * line_height->total() && last_span_at_break.end == start_span_pos) { @@ -1518,7 +1543,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, chunk_info->back().text_width += last_span_at_break.width; chunk_info->back().whitespace_count += last_span_at_break.whitespace_count; } - TRACE(("correction: fitted span %d width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); + TRACE(("correction: fitted span %lu width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); } } @@ -1541,6 +1566,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, return true; } + /** The management function to start the whole thing off. */ bool Layout::Calculator::calculate() { @@ -1590,7 +1616,7 @@ bool Layout::Calculator::calculate() else para.alignment = para.direction == LEFT_TO_RIGHT ? LEFT : RIGHT; - TRACE(("para prepared, adding as #%d\n", _flow._paragraphs.size())); + TRACE(("para prepared, adding as #%lu\n", _flow._paragraphs.size())); Layout::Paragraph new_paragraph; new_paragraph.base_direction = para.direction; new_paragraph.alignment = para.alignment; @@ -1612,7 +1638,7 @@ bool Layout::Calculator::calculate() _scanline_maker->completeLine(); // Increments y by line height } while (span_pos.iter_span != para.unbroken_spans.end()); - TRACE(("para %d end\n\n", _flow._paragraphs.size() - 1)); + TRACE(("para %lu end\n\n", _flow._paragraphs.size() - 1)); if (_scanline_maker != NULL) { bool is_empty_para = _flow._characters.empty() || _flow._characters.back().line(&_flow).in_paragraph != _flow._paragraphs.size() - 1; if ((is_empty_para && para_end_input_index + 1 >= _flow._input_stream.size()) @@ -1675,6 +1701,14 @@ bool Layout::Calculator::calculate() _flow._input_truncated = true; } + if (_flow.textLength._set) { + // Calculate the adjustment needed to meet the textLength + double actual_length = _flow.getActualLength(); + double difference = _flow.textLength.computed - actual_length; + _flow.textLengthMultiplier = (actual_length + difference) / actual_length; + _flow.textLengthIncrement = difference / (_flow._characters.size() == 1? 1 : _flow._characters.size() - 1); + } + return true; } @@ -1724,7 +1758,12 @@ void Layout::_calculateCursorShapeForEmpty() bool Layout::calculateFlow() { - bool result = Calculator(this).calculate(); + Layout::Calculator calc = Calculator(this); + bool result = calc.calculate(); + if (textLengthIncrement != 0) { + TRACE(("Recalculating layout the second time to fit textLength!\n")); + result = calc.calculate(); + } if (_characters.empty()) _calculateCursorShapeForEmpty(); return result; diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index fa1e8c11b..84f3f260e 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -72,6 +72,11 @@ void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_ last_rotate = *it; new_source->rotate.resize(1, last_rotate); } + new_source->textLength._set = optional_attributes->textLength._set; + new_source->textLength.value = optional_attributes->textLength.value; + new_source->textLength.computed = optional_attributes->textLength.computed; + new_source->textLength.unit = optional_attributes->textLength.unit; + new_source->lengthAdjust = optional_attributes->lengthAdjust; } _input_stream.push_back(new_source); @@ -325,7 +330,7 @@ PangoFontDescription *Layout::InputStreamTextSource::styleGetFontDescription() c Layout::InputStreamTextSource::~InputStreamTextSource() { - sp_style_unref(style); + sp_style_unref(style); } }//namespace Text diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 6dc42d998..c9c318960 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -401,15 +401,17 @@ std::vector<Geom::Point> Layout::createSelectionShape(iterator const &it_start, bottom_right[Geom::X] = span_x + _characters[char_index].x; double baseline_y = _spans[span_index].line(this).baseline_y + _spans[span_index].baseline_shift; + double vertical_scale = _glyphs.back().vertical_scale; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - double span_height = _spans[span_index].line_height.ascent + _spans[span_index].line_height.descent; + double span_height = vertical_scale * (_spans[span_index].line_height.ascent + _spans[span_index].line_height.descent); top_left[Geom::Y] = top_left[Geom::X]; top_left[Geom::X] = baseline_y - span_height * 0.5; bottom_right[Geom::Y] = bottom_right[Geom::X]; bottom_right[Geom::X] = baseline_y + span_height * 0.5; } else { - top_left[Geom::Y] = baseline_y - _spans[span_index].line_height.ascent; - bottom_right[Geom::Y] = baseline_y + _spans[span_index].line_height.descent; + top_left[Geom::Y] = baseline_y - vertical_scale * _spans[span_index].line_height.ascent; + bottom_right[Geom::Y] = baseline_y + vertical_scale * _spans[span_index].line_height.descent; } } @@ -505,21 +507,23 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double position[Geom::Y] = span->line(this).baseline_y + span->baseline_shift; } // up to now *position is the baseline point, not the final point which will be the bottom of the descent + double vertical_scale = _glyphs.back().vertical_scale; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - height = span->line_height.ascent + span->line_height.descent; + height = vertical_scale * span->line_height.ascent + span->line_height.descent; rotation += M_PI / 2; std::swap(position[Geom::X], position[Geom::Y]); - position[Geom::X] -= sin(rotation) * height * 0.5; - position[Geom::Y] += cos(rotation) * height * 0.5; + position[Geom::X] -= vertical_scale * sin(rotation) * height * 0.5; + position[Geom::Y] += vertical_scale * cos(rotation) * height * 0.5; } else { double caret_slope_run = 0.0, caret_slope_rise = 1.0; if (span->font) const_cast<font_instance*>(span->font)->FontSlope(caret_slope_run, caret_slope_rise); double caret_slope = atan2(caret_slope_run, caret_slope_rise); - height = (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); + height = vertical_scale * (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); rotation += caret_slope; - position[Geom::X] -= sin(rotation) * span->line_height.descent; - position[Geom::Y] += cos(rotation) * span->line_height.descent; + position[Geom::X] -= sin(rotation) * vertical_scale * span->line_height.descent; + position[Geom::Y] += cos(rotation) * vertical_scale * span->line_height.descent; } } } @@ -601,9 +605,10 @@ void Layout::simulateLayoutUsingKerning(iterator const &from, iterator const &to if (input_item->Type() == TEXT_SOURCE) { SPStyle const *style = static_cast<InputStreamTextSource*>(input_item)->style; if (_characters[char_index].char_attributes.is_white) - dx -= style->word_spacing.computed; + dx -= style->word_spacing.computed * getTextLengthMultiplierDue(); if (_characters[char_index].char_attributes.is_cursor_position) - dx -= style->letter_spacing.computed; + dx -= style->letter_spacing.computed * getTextLengthMultiplierDue(); + dx -= getTextLengthIncrementDue(); } if (fabs(dx) > 0.0001) { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 61a141cc3..6e3faf33b 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -108,7 +108,7 @@ void Layout::_getGlyphTransformMatrix(int glyph_index, Geom::Affine *matrix) con (*matrix)[0] = span.font_size * cos_rotation; (*matrix)[1] = span.font_size * sin_rotation; (*matrix)[2] = span.font_size * sin_rotation; - (*matrix)[3] = -span.font_size * cos_rotation; + (*matrix)[3] = -span.font_size * cos_rotation * (_glyphs[glyph_index].vertical_scale); // unscale vertically so the specified text height is preserved if lengthAdjust=spacingAndGlyphs if (span.block_progression == LEFT_TO_RIGHT || span.block_progression == RIGHT_TO_LEFT) { (*matrix)[4] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; (*matrix)[5] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; @@ -804,6 +804,36 @@ void Layout::transform(Geom::Affine const &transform) } } +double Layout::getTextLengthIncrementDue() const +{ + if (textLength._set && textLengthIncrement != 0 && lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACING) { + return textLengthIncrement; + } + return 0; +} + + +double Layout::getTextLengthMultiplierDue() const +{ + if (textLength._set && textLengthMultiplier != 1 && (lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS)) { + return textLengthMultiplier; + } + return 1; +} + +double Layout::getActualLength() const +{ + double length = 0; + for (std::vector<Span>::const_iterator it_span = _spans.begin() ; it_span != _spans.end() ; it_span++) { + // take x_end of the last span of each chunk + if (it_span == _spans.end() - 1 || (it_span + 1)->in_chunk != it_span->in_chunk) + length += it_span->x_end; + } + return length; + + +} + }//namespace Text }//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp index dd9c90949..8b0889188 100644 --- a/src/libnrtype/Layout-TNG.cpp +++ b/src/libnrtype/Layout-TNG.cpp @@ -20,6 +20,10 @@ Layout::Layout() : _input_truncated(0), _path_fitted(NULL) { + textLength._set = false; + textLengthMultiplier = 1; + textLengthIncrement = 0; + lengthAdjust = LENGTHADJUST_SPACING; } Layout::~Layout() @@ -31,6 +35,11 @@ void Layout::clear() { _clearInputObjects(); _clearOutputObjects(); + + textLength._set = false; + textLengthMultiplier = 1; + textLengthIncrement = 0; + lengthAdjust = LENGTHADJUST_SPACING; } bool Layout::_directions_are_orthogonal(Direction d1, Direction d2) diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index efb5ebc24..e91c32ebe 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -21,6 +21,7 @@ #include <algorithm> #include <vector> #include <boost/optional.hpp> +#include <svg/svg-length.h> #ifdef HAVE_CAIRO_PDF namespace Inkscape { @@ -37,7 +38,6 @@ using Inkscape::Extension::Internal::CairoRenderContext; class SPStyle; class Shape; struct SPPrintContext; -class SVGLength; class Path; class SPCurve; class font_instance; @@ -160,6 +160,9 @@ public: /** Display alignment for shapes. See appendWrapShape(). */ enum DisplayAlign {DISPLAY_ALIGN_BEFORE, DISPLAY_ALIGN_CENTER, DISPLAY_ALIGN_AFTER}; + /** lengthAdjust values */ + enum LengthAdjust {LENGTHADJUST_SPACING, LENGTHADJUST_SPACINGANDGLYPHS}; + /** The optional attributes which can be applied to a SVG text or related tag. See appendText(). See SVG1.1 section 10.4 for the definitions of all these members. See sp_svg_length_list_read() for @@ -172,6 +175,8 @@ public: std::vector<SVGLength> dx; std::vector<SVGLength> dy; std::vector<SVGLength> rotate; + SVGLength textLength; + LengthAdjust lengthAdjust; }; /** Control codes which can be embedded in the text to be flowed. See @@ -290,6 +295,43 @@ public: //@} + // ************************** textLength and friends ************************* + + /** Gives the length target of this layout, as given by textLength attribute. + + FIXME: by putting it here we only support @textLength on text and flowRoot, not on any + spans inside. For spans, we will need to add markers of start and end of a textLength span + into the _input_stream. These spans can nest (SVG 1.1, section 10.5). After a first layout + calculation, we would go through the input stream and, for each end of a textLength span, + go through its items, choose those where it wasn't yet set by a nested span, calculate + their number of characters, divide the length deficit by it, and set set the + textLengthMultiplier for those characters only. For now we do this for the entire layout, + without dealing with spans. + */ + SVGLength textLength; + + /** How do we meet textLength if specified: by letterspacing or by scaling horizontally */ + LengthAdjust lengthAdjust; + + /** By how much each character needs to be wider or narrower, using the specified lengthAdjust + strategy, for the layout to meet its textLength target. Is set to non-zero after the layout + is calculated for the first time, then it is recalculated with each glyph getting its adjustment. */ + /** This one is used by scaling strategies: each glyph width is multiplied by this */ + double textLengthMultiplier; + /** This one is used by letterspacing strategy: to each glyph width, this is added */ + double textLengthIncrement; + + /** Get the actual spacing increment if it's due with the current values of above stuff, otherwise 0 */ + double getTextLengthIncrementDue() const; + /** Get the actual scale multiplier if it's due with the current values of above stuff, otherwise 1 */ + double getTextLengthMultiplierDue() const; + + /** Get actual length of layout, by summing span lengths. For one-line non-flowed text, just + the width; for multiline non-flowed, sum of lengths of all lines; for flowed text, sum of + scanline widths for all non-last lines plus text width of last line. */ + double getActualLength() const; + + // ************************** doing the actual flowing ************************* /** \name Processing @@ -481,6 +523,7 @@ public: from a call to appendText() then the optional \a text_iterator parameter is set to point to the actual character, otherwise \a text_iterator is unaltered. */ + // TODO FIXME a void* cookie is a very unsafe design, and C++ makes it unnecessary. void getSourceOfCharacter(iterator const &it, void **source_cookie, Glib::ustring::iterator *text_iterator = NULL) const; /** For latin text, the left side of the character, on the baseline */ @@ -617,6 +660,8 @@ private: std::vector<SVGLength> dx; std::vector<SVGLength> dy; std::vector<SVGLength> rotate; + SVGLength textLength; + LengthAdjust lengthAdjust; // a few functions for some of the more complicated style accesses float styleComputeFontSize() const; @@ -700,6 +745,7 @@ private: float y; /// relative to the current line's baseline float rotation; /// absolute, modulo any object transforms, which we don't know about float width; + float vertical_scale; /// to implement lengthAdjust="spacingAndGlyphs" that must scale glyphs only horizontally; instead we change font size and then undo that change vertically only inline Span const & span(Layout const *l) const {return l->_spans[l->_characters[in_character].in_span];} inline Chunk const & chunk(Layout const *l) const {return l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk];} inline Line const & line(Layout const *l) const {return l->_lines[l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk].in_line];} diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index fad06cd00..a6ab3b239 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -385,27 +385,27 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update() #endif // Get fontspec from a selection, preferences, or thin air. Glib::ustring fontspec; - SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // Directly from stored font specification. int result = - sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); //std::cout << " Attempting selected style" << std::endl; - if (result != QUERY_STYLE_NOTHING && query->font_specification.set) { - fontspec = query->font_specification.value; + if (result != QUERY_STYLE_NOTHING && query.font_specification.set) { + fontspec = query.font_specification.value; //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; } // From style if (fontspec.empty()) { //std::cout << " Attempting desktop style" << std::endl; - int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); // Must have text in selection if (rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING) { - fontspec = fontspec_from_style(query); + fontspec = fontspec_from_style(&query); } //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; } @@ -413,11 +413,10 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update() // From preferences if (fontspec.empty()) { //std::cout << " Attempting preferences" << std::endl; - sp_style_read_from_prefs(query, "/tools/text"); - fontspec = fontspec_from_style(query); + query.readFromPrefs("/tools/text"); + fontspec = fontspec_from_style(&query); //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; } - sp_style_unref(query); // From thin air if (fontspec.empty()) { diff --git a/src/line-geometry.cpp b/src/line-geometry.cpp index 566af8840..c5357e213 100644 --- a/src/line-geometry.cpp +++ b/src/line-geometry.cpp @@ -13,7 +13,7 @@ #include "inkscape.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/sp-ctrlline.h" #include "display/sodipodi-ctrl.h" @@ -201,8 +201,8 @@ boost::optional<Geom::Point> Line::intersection_with_viewbox (SPDesktop *desktop void create_canvas_point(Geom::Point const &pos, double size, guint32 rgba) { - SPDesktop *desktop = inkscape_active_desktop(); - SPCanvasItem * canvas_pt = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRL, + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPCanvasItem * canvas_pt = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "size", size, "filled", 1, "fill_color", rgba, @@ -214,8 +214,8 @@ void create_canvas_point(Geom::Point const &pos, double size, guint32 rgba) void create_canvas_line(Geom::Point const &p1, Geom::Point const &p2, guint32 rgba) { - SPDesktop *desktop = inkscape_active_desktop(); - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop), p1, p2); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPCtrlLine *line = ControlManager::getManager().createControlLine(desktop->getControls(), p1, p2); line->setRgba32(rgba); sp_canvas_item_show(line); } diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 1a64defd9..827f70749 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -75,8 +75,6 @@ #include <glibmm/i18n.h> #include "ui/tools/pen-tool.h" #include "ui/tools-switch.h" -#include "message-stack.h" -#include "desktop.h" #include "knotholder.h" #include "sp-lpe-item.h" #include "live_effects/lpeobject.h" @@ -370,6 +368,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) { registerParameter( dynamic_cast<Parameter *>(&is_visible) ); is_visible.widget_is_visible = false; + current_zoom = 0.0; } Effect::~Effect() @@ -398,6 +397,38 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) { } +void +Effect::setSelectedNodePoints(std::vector<Geom::Point> sNP) +{ + selectedNodesPoints = sNP; +} + +void +Effect::setCurrentZoom(double cZ) +{ + current_zoom = cZ; +} + +bool +Effect::isNodePointSelected(Geom::Point const &nodePoint) const +{ + if (selectedNodesPoints.size() > 0) { + using Geom::X; + using Geom::Y; + for (std::vector<Geom::Point>::const_iterator i = selectedNodesPoints.begin(); + i != selectedNodesPoints.end(); ++i) { + Geom::Point p = *i; + Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine(); + Geom::Point p2(nodePoint[X],nodePoint[Y]); + p2 *= transformCoordinate; + if (Geom::are_near(p, p2, 0.01)) { + return true; + } + } + } + return false; +} + /** * Is performed each time before the effect is updated. */ @@ -419,6 +450,7 @@ void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); + defaultUnit = &sp_lpe_item->document->getDisplayUnit()->abbr; /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); pathvector_before_effect = sp_curve->get_pathvector();*/ doOnApply(lpeitem); @@ -427,6 +459,7 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); + defaultUnit = &sp_lpe_item->document->getDisplayUnit()->abbr; //printf("(SPLPEITEM*) %p\n", sp_lpe_item); sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); pathvector_before_effect = sp_curve->get_pathvector(); @@ -443,7 +476,7 @@ void Effect::doAcceptPathPreparations(SPLPEItem *lpeitem) { // switch to pen context - SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // TODO: Is there a better method to find the item's desktop? if (!tools_isactive(desktop, TOOLS_FREEHAND_PEN)) { tools_switch(desktop, TOOLS_FREEHAND_PEN); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index a486e8491..7da76b267 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -13,6 +13,7 @@ #include "parameter/bool.h" #include "effect-enum.h" + #define LPE_CONVERSION_TOLERANCE 0.01 // FIXME: find good solution for this. class SPDocument; @@ -57,7 +58,9 @@ public: //of indirection is needed. We first call these methods, then the below. void doOnApply_impl(SPLPEItem const* lpeitem); void doBeforeEffect_impl(SPLPEItem const* lpeitem); - + void setCurrentZoom(double cZ); + void setSelectedNodePoints(std::vector<Geom::Point> sNP); + bool isNodePointSelected(Geom::Point const &nodePoint) const; virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); @@ -156,6 +159,9 @@ protected: bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + Glib::ustring const * defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + double current_zoom; + std::vector<Geom::Point> selectedNodesPoints; SPCurve * sp_curve; std::vector<Geom::Path> pathvector_before_effect; private: diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index b68799d08..2bed90139 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -24,11 +24,6 @@ #include "live_effects/lpeobject.h" #include "live_effects/parameter/parameter.h" #include "ui/widget/scalar.h" -#include "ui/tool/node.h" -#include "ui/tools/node-tool.h" -#include "ui/tool/control-point-selection.h" -#include "ui/tool/selectable-control-point.h" -#include "selection.h" #include "xml/repr.h" #include "svg/svg.h" #include "sp-path.h" @@ -36,7 +31,6 @@ #include "document-private.h" #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" #include "verbs.h" #include "sp-lpe-item.h" #include "sp-namedview.h" @@ -47,7 +41,6 @@ // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" -#include "desktop.h" using Inkscape::DocumentUndo; @@ -64,7 +57,7 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) // initialise your parameters here: //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, //Geom::Point(100,100)), - steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2), + steps(_("Steps with CTRL:"), _("Change number of steps with CTRL pressed"), "steps", &wr, this, 2), ignoreCusp(_("Ignore cusp nodes"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), onlySelected(_("Change only selected nodes"), _("Change only selected nodes"), "onlySelected", &wr, this, false), showHelper(_("Show helper paths"), _("Show helper paths"), "showHelper", &wr, this, false), @@ -87,7 +80,7 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) LPEBSpline::~LPEBSpline() {} -void LPEBSpline::doBeforeEffect (SPLPEItem const* lpeitem) +void LPEBSpline::doBeforeEffect (SPLPEItem const* /*lpeitem*/) { if(!hp.empty()){ hp.clear(); @@ -95,25 +88,12 @@ void LPEBSpline::doBeforeEffect (SPLPEItem const* lpeitem) } -void LPEBSpline::createAndApply(const char *name, SPDocument *doc, - SPItem *item) +void LPEBSpline::doOnApply(SPLPEItem const* lpeitem) { - if (!SP_IS_SHAPE(item)) { + if (!SP_IS_SHAPE(lpeitem)) { g_warning("LPE BSpline can only be applied to shapes (not groups)."); - } else { - // Path effect definition - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); - repr->setAttribute("effect", name); - - doc->getDefs()->getRepr() - ->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute - const gchar *repr_id = repr->attribute("id"); - Inkscape::GC::release(repr); - - gchar *href = g_strdup_printf("#%s", repr_id); - SP_LPE_ITEM(item)->addPathEffect(href, true); - g_free(href); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->removeCurrentPathEffect(false); } } @@ -127,12 +107,8 @@ void LPEBSpline::doEffect(SPCurve *curve) Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); double radiusHelperNodes = 6.0; - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop){ - radiusHelperNodes /= SP_ACTIVE_DESKTOP->current_zoom(); - SPNamedView *nv = sp_desktop_namedview(desktop); - radiusHelperNodes = Inkscape::Util::Quantity::convert(radiusHelperNodes, "px", nv->doc_units->abbr); - } + radiusHelperNodes /= current_zoom; + radiusHelperNodes = Inkscape::Util::Quantity::convert(radiusHelperNodes, "px", *defaultUnit); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) @@ -165,16 +141,8 @@ void LPEBSpline::doEffect(SPCurve *curve) curve_endit = path_it->end_open(); } } - //Si la curva está cerrada calculamos el punto donde - //deveria estar el nodo BSpline de cierre/inicio de la curva - //en posible caso de que se cierre con una linea recta creando un nodo - //BSPline nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último while (curve_it1 != curve_endit) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path - //recto de entrada y de salida SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -260,10 +228,7 @@ void LPEBSpline::doEffect(SPCurve *curve) SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); delete lineHelper; - //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de - //principio de curva previousNode = node; - //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) { @@ -274,12 +239,6 @@ void LPEBSpline::doEffect(SPCurve *curve) if(!are_near(node,curve_it1->finalPoint()) && showHelper){ drawHandle(node, radiusHelperNodes); } - //La curva BSpline se forma calculando el centro del segmanto de unión - //de el punto situado en las 2/3 partes de el segmento de entrada - //con el punto situado en la posición 1/3 del segmento de salida - //Estos dos puntos ademas estan posicionados en el lugas correspondiente - //de los manejadores de la curva - //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } @@ -293,7 +252,7 @@ void LPEBSpline::doEffect(SPCurve *curve) } if(showHelper){ Geom::PathVector const pathv = curve->get_pathvector(); - hp.push_back(pathv[0]); + hp.push_back(pathv[0]); } } @@ -314,7 +273,6 @@ LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom:: { hp_vec.push_back(hp); } - Gtk::Widget *LPEBSpline::newWidget() { // use manage here, because after deletion of Effect object, others might @@ -332,12 +290,12 @@ Gtk::Widget *LPEBSpline::newWidget() Gtk::Button *defaultWeight = Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); defaultWeight->signal_clicked() - .connect(sigc::bind<Gtk::Widget *>(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight), widg)); + .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); buttons->pack_start(*defaultWeight, true, true, 2); Gtk::Button *makeCusp = Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); makeCusp->signal_clicked() - .connect(sigc::bind<Gtk::Widget *>(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp), widg)); + .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); buttons->pack_start(*makeCusp, true, true, 2); vbox->pack_start(*buttons, true, true, 2); } @@ -381,24 +339,14 @@ Gtk::Widget *LPEBSpline::newWidget() return dynamic_cast<Gtk::Widget *>(vbox); } -void LPEBSpline::toDefaultWeight(Gtk::Widget *widgWeight) +void LPEBSpline::toDefaultWeight() { - weight.param_set_value(defaultStartPower); changeWeight(defaultStartPower); - Gtk::HBox * scalarParameter = dynamic_cast<Gtk::HBox *>(widgWeight); - std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); - Gtk::Entry* entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); - entryWidg->set_text("defaultStartPower"); } -void LPEBSpline::toMakeCusp(Gtk::Widget *widgWeight) +void LPEBSpline::toMakeCusp() { - weight.param_set_value(noPower); changeWeight(noPower); - Gtk::HBox * scalarParameter = dynamic_cast<Gtk::HBox *>(widgWeight); - std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); - Gtk::Entry* entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); - entryWidg->set_text("noPower"); } void LPEBSpline::toWeight() @@ -408,91 +356,34 @@ void LPEBSpline::toWeight() void LPEBSpline::changeWeight(double weightValue) { - SPDesktop *desktop = inkscape_active_desktop(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList *items = (GSList *)selection->itemList(); - SPItem *item = (SPItem *)g_slist_nth(items, 0)->data; - SPPath *path = SP_PATH(item); + SPPath *path = SP_PATH(sp_lpe_item); SPCurve *curve = path->get_curve_for_edit(); LPEBSpline::doBSplineFromWidget(curve, weightValue); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - nt->desktop->updateNow(); - } - g_free(str); - curve->unref(); - desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, - _("Modified the weight of the BSpline")); -} - -bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint) -{ - using Geom::X; - using Geom::Y; - - if (points.size() > 0) { - for (std::vector<Geom::Point>::iterator i = points.begin(); - i != points.end(); ++i) { - Geom::Point p = *i; - if (Geom::are_near(p, nodePoint, handleCubicGap)) { - return true; - } else { - } - } - } - return false; } void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { using Geom::X; using Geom::Y; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = - nt->_selected_nodes->allPoints(); - points.clear(); - std::vector<Geom::Point>::iterator pbegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = - selection.begin(); - i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); - pbegin = points.begin(); - points.insert(pbegin, desktop->doc2dt(n->position())); - } - } - } - //bool hasNodesSelected = LPEBspline::hasNodesSelected(); + if (curve->get_segment_count() < 1) return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el - //penúltimo for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - //Si está vacío... - if (path_it->empty()) + + if (path_it->empty()){ continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = - ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_endit = - path_it->end_default(); // this determines when the loop has to stop - //Creamos las lineas rectas que unen todos los puntos del trazado y donde se - //calcularán - //los puntos clave para los manejadores. - //Esto hace que la curva BSpline no pierda su condición aunque se trasladen - //dichos manejadores + } + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + SPCurve *nCurve = new SPCurve(); Geom::Point pointAt0(0, 0); Geom::Point pointAt1(0, 0); @@ -515,16 +406,8 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) curve_endit = path_it->end_open(); } } - //Si la curva está cerrada calculamos el punto donde - //deveria estar el nodo BSpline de cierre/inicio de la curva - //en posible caso de que se cierre con una linea recta creando un nodo - //BSPline nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último while (curve_it1 != curve_endit) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path - //recto de entrada y de salida SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -572,7 +455,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) } else { if (cubic) { if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { - if (nodeIsSelected(pointAt0)) { + if (isNodePointSelected(pointAt0)) { pointAt1 = SBasisIn.valueAt(weightValue); if (weightValue != noPower) { pointAt1 = @@ -585,7 +468,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) pointAt1 = in->first_segment()->initialPoint(); } if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { - if (nodeIsSelected(pointAt3)) { + if (isNodePointSelected(pointAt3)) { pointAt2 = SBasisIn.valueAt(1 - weightValue); if (weightValue != noPower) { pointAt2 = @@ -599,14 +482,14 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) } } else { if (!ignoreCusp && weightValue != noPower) { - if (nodeIsSelected(pointAt0)) { + if (isNodePointSelected(pointAt0)) { pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + handleCubicGap, pointAt1[Y] + handleCubicGap); } else { pointAt1 = in->first_segment()->initialPoint(); } - if (nodeIsSelected(pointAt3)) { + if (isNodePointSelected(pointAt3)) { pointAt2 = SBasisIn.valueAt(weightValue); pointAt2 = Geom::Point(pointAt2[X] + handleCubicGap, pointAt2[Y] + handleCubicGap); @@ -621,14 +504,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) } in->reset(); delete in; - //La curva BSpline se forma calculando el centro del segmanto de unión - //de el punto situado en las 2/3 partes de el segmento de entrada - //con el punto situado en la posición 1/3 del segmento de salida - //Estos dos puntos ademas estan posicionados en el lugas correspondiente - //de - //los manejadores de la curva nCurve->curveto(pointAt1, pointAt2, pointAt3); - //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } @@ -638,7 +514,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) } else { nCurve->move_endpoints(path_it->begin()->initialPoint(), pointAt3); } - //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); } diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 169658b94..a17c0c4ac 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -19,27 +19,25 @@ public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); - virtual void createAndApply(const char *name, SPDocument *doc, SPItem *item); virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } + virtual void doOnApply(SPLPEItem const* lpeitem); virtual void doEffect(SPCurve *curve); virtual void doBeforeEffect (SPLPEItem const* lpeitem); void drawHandle(Geom::Point p, double radiusHelperNodes); - void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); virtual void doBSplineFromWidget(SPCurve *curve, double value); - virtual bool nodeIsSelected(Geom::Point nodePoint); + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); virtual Gtk::Widget *newWidget(); virtual void changeWeight(double weightValue); - virtual void toDefaultWeight(Gtk::Widget *widgWeight); - virtual void toMakeCusp(Gtk::Widget *widgWeight); + virtual void toDefaultWeight(); + virtual void toMakeCusp(); virtual void toWeight(); // TODO make this private ScalarParam steps; private: - std::vector<Geom::Point> points; BoolParam ignoreCusp; BoolParam onlySelected; BoolParam showHelper; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index e466093d3..0fa2ebedc 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -15,9 +15,6 @@ #include <gdk/gdk.h> #include "live_effects/lpe-copy_rotate.h" -#include "sp-shape.h" -#include "display/curve.h" - #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> @@ -45,24 +42,33 @@ public: virtual Geom::Point knot_get() const; }; +class KnotHolderEntityOrigin : public LPEKnotHolderEntity { +public: + KnotHolderEntityOrigin(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; + } // namespace CR LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), + origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), - origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), - dist_angle_handle(100) + copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), + dist_angle_handle(100.0) { show_orig_path = true; _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast<Parameter *>(&starting_angle) ); - registerParameter( dynamic_cast<Parameter *>(&rotation_angle) ); - registerParameter( dynamic_cast<Parameter *>(&num_copies) ); - registerParameter( dynamic_cast<Parameter *>(&origin) ); + registerParameter(&copiesTo360); + registerParameter(&starting_angle); + registerParameter(&rotation_angle); + registerParameter(&num_copies); + registerParameter(&origin); num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); @@ -76,42 +82,58 @@ LPECopyRotate::~LPECopyRotate() void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { - SPCurve const *curve = SP_SHAPE(lpeitem)->_curve; - - A = *(curve->first_point()); - B = *(curve->last_point()); + using namespace Geom; + original_bbox(lpeitem); + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); origin.param_setValue(A); - - dir = unit_vector(B - A); dist_angle_handle = L2(B - A); + dir = unit_vector(B - A); } -Geom::Piecewise<Geom::D2<Geom::SBasis> > -LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) + +void +LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - + original_bbox(lpeitem); + if(copiesTo360 ){ + rotation_angle.param_set_value(360.0/(double)num_copies); + } + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); + dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle)) * dist_angle_handle; + rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + if(copiesTo360 ){ + rot_pos = origin; + } + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->apply_to_clippath(item); + item->apply_to_mask(item); - A = pwd2_in.firstValue(); - B = pwd2_in.lastValue(); - dir = unit_vector(B - A); +} - Piecewise<D2<SBasis> > output; +Geom::Piecewise<Geom::D2<Geom::SBasis> > +LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) +{ + using namespace Geom; + + if(num_copies == 1){ + return pwd2_in; + } + + Piecewise<D2<SBasis> > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) Rotate rot(-deg_to_rad(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } - return output; } @@ -119,29 +141,37 @@ void LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) { using namespace Geom; - - Path path(start_pos); - path.appendNew<LineSegment>((Geom::Point) origin); - path.appendNew<LineSegment>(rot_pos); - - PathVector pathv; - pathv.push_back(path); + hp_vec.clear(); + Geom::Path hp; + hp.start(start_pos); + hp.appendNew<Geom::LineSegment>((Geom::Point)origin); + hp.appendNew<Geom::LineSegment>(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); + Geom::PathVector pathv; + pathv.push_back(hp); hp_vec.push_back(pathv); } + void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the starting angle") ); + _("Adjust the starting angle")); knotholder->add(e); } { KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the rotation angle") ); + _("Adjust the rotation angle")); knotholder->add(e); } +} + +void +LPECopyRotate::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); }; namespace CR { @@ -204,8 +234,6 @@ KnotHolderEntityRotationAngle::knot_get() const } // namespace CR - - /* ######################## */ } //namespace LivePathEffect diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index ca7aa269c..9392026a7 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -16,6 +16,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/point.h" +#include "live_effects/lpegroupbbox.h" namespace Inkscape { namespace LivePathEffect { @@ -26,7 +27,7 @@ namespace CR { class KnotHolderEntityRotationAngle; } -class LPECopyRotate : public Effect { +class LPECopyRotate : public Effect, GroupBBoxEffect { public: LPECopyRotate(LivePathEffectObject *lpeobject); virtual ~LPECopyRotate(); @@ -35,6 +36,10 @@ public: virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void resetDefaults(SPItem const* item); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; friend class CR::KnotHolderEntityRotationAngle; @@ -44,11 +49,11 @@ protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); private: + PointParam origin; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; - - PointParam origin; + BoolParam copiesTo360; Geom::Point A; Geom::Point B; diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 8a8f68d80..d2bdf2d8d 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -28,12 +28,7 @@ #include "live_effects/parameter/filletchamferpointarray.h" // for programmatically updating knots -#include "selection.h" #include "ui/tools-switch.h" -#include "ui/tool/control-point-selection.h" -#include "ui/tool/selectable-control-point.h" -#include "ui/tool/node.h" -#include "ui/tools/node-tool.h" #include <util/units.h> // TODO due to internal breakage in glibmm headers, this must be last: @@ -62,15 +57,18 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false), use_knot_distance(_("Use knots distance instead radius"), _("Use knots distance instead radius"), "use_knot_distance", &wr, this, false), - unit(_("Unit"), _("Unit"), "unit", &wr, this), - method(_("Method"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), - radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, this, 0.), - helper_size(_("Helper size with direction"), _("Helper size with direction"), "helper_size", &wr, this, 0) + unit(_("Unit:"), _("Unit"), "unit", &wr, this), + method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), + radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, this, 0.), + chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", &wr, this, 0), + + helper_size(_("Helper size with direction:"), _("Helper size with direction"), "helper_size", &wr, this, 0) { registerParameter(&fillet_chamfer_values); registerParameter(&unit); registerParameter(&method); registerParameter(&radius); + registerParameter(&chamfer_steps); registerParameter(&helper_size); registerParameter(&flexible); registerParameter(&use_knot_distance); @@ -81,9 +79,13 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : radius.param_set_range(0., infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); + chamfer_steps.param_set_range(1, 999); + chamfer_steps.param_set_increments(1, 1); + chamfer_steps.param_set_digits(0); helper_size.param_set_range(0, infinity()); helper_size.param_set_increments(5, 5); helper_size.param_set_digits(0); + fillet_chamfer_values.set_chamfer_steps(3); } LPEFilletChamfer::~LPEFilletChamfer() {} @@ -112,6 +114,16 @@ Gtk::Widget *LPEFilletChamfer::newWidget() Gtk::Entry *entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); entryWidg->set_width_chars(6); } + } else if (param->param_key == "chamfer_steps") { + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamferSubdivisions)); + widg = widgRegistered; + if (widg) { + Gtk::HBox *scalarParameter = dynamic_cast<Gtk::HBox *>(widg); + std::vector<Gtk::Widget *> childList = scalarParameter->get_children(); + Gtk::Entry *entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); + entryWidg->set_width_chars(3); + } } else if (param->param_key == "flexible") { Gtk::CheckButton *widgRegistered = Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg)); widgRegistered->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleFlexFixed)); @@ -141,27 +153,26 @@ Gtk::Widget *LPEFilletChamfer::newWidget() ++it; } - - Gtk::HBox *filletButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::HBox *filletContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); fillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); - filletButtonsContainer->pack_start(*fillet, true, true, 2); - Gtk::Button *inverse = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); - inverse->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); - filletButtonsContainer->pack_start(*inverse, true, true, 2); - - Gtk::HBox *chamferButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + filletContainer->pack_start(*fillet, true, true, 2); + Gtk::Button *inverseFillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverseFillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseFillet)); + filletContainer->pack_start(*inverseFillet, true, true, 2); + + Gtk::HBox *chamferContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); chamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); - chamferButtonsContainer->pack_start(*chamfer, true, true, 2); - Gtk::Button *doubleChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Double chamfer")))); - doubleChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::doubleChamfer)); - chamferButtonsContainer->pack_start(*doubleChamfer, true, true, 2); + chamferContainer->pack_start(*chamfer, true, true, 2); + Gtk::Button *inverseChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer")))); + inverseChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseChamfer)); + chamferContainer->pack_start(*inverseChamfer, true, true, 2); - vbox->pack_start(*filletButtonsContainer, true, true, 2); - vbox->pack_start(*chamferButtonsContainer, true, true, 2); + vbox->pack_start(*filletContainer, true, true, 2); + vbox->pack_start(*chamferContainer, true, true, 2); return vbox; } @@ -212,8 +223,7 @@ void LPEFilletChamfer::updateFillet() { double power = 0; if (!flexible) { - Inkscape::Util::Unit const *doc_units = inkscape_active_desktop()->namedview->doc_units; - power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), doc_units->abbr) * -1; + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), *defaultUnit) * -1; } else { power = radius; } @@ -227,64 +237,46 @@ void LPEFilletChamfer::fillet() doChangeType(path_from_piecewise(pwd2, tolerance), 1); } -void LPEFilletChamfer::inverse() +void LPEFilletChamfer::inverseFillet() { Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), 2); } +void LPEFilletChamfer::chamferSubdivisions() +{ + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); + Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 5000); +} + void LPEFilletChamfer::chamfer() { + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); - doChangeType(path_from_piecewise(pwd2, tolerance), 3); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3000); } -void LPEFilletChamfer::doubleChamfer() +void LPEFilletChamfer::inverseChamfer() { + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); - doChangeType(path_from_piecewise(pwd2, tolerance), 4); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 4000); } void LPEFilletChamfer::refreshKnots() { Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); fillet_chamfer_values.recalculate_knots(pwd2); - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (tools_isactive(desktop, TOOLS_NODES)) { tools_switch(desktop, TOOLS_SELECT); tools_switch(desktop, TOOLS_NODES); } } -bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, std::vector<Geom::Point> point) -{ - if (point.size() > 0) { - for (std::vector<Geom::Point>::iterator i = point.begin(); i != point.end(); - ++i) { - Geom::Point p = *i; - if (Geom::are_near(p, nodePoint, 2)) { - return true; - } - } - } - return false; -} void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pathv, double power) { - std::vector<Geom::Point> point; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nodeTool = INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = nodeTool->_selected_nodes->allPoints(); - std::vector<Geom::Point>::iterator pBegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); - pBegin = point.begin(); - point.insert(pBegin, desktop->doc2dt(n->position())); - } - } - } std::vector<Point> filletChamferData = fillet_chamfer_values.data(); std::vector<Geom::Point> result; std::vector<Geom::Path> original_pathv_processed = pathv_to_linear_and_cubic_beziers(original_pathv); @@ -319,7 +311,7 @@ void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pa if (filletChamferData[counter][Y] == 0) { powerend = filletChamferData[counter][X]; } - if (only_selected && !nodeIsSelected(curve_it1->initialPoint(), point)) { + if (only_selected && !isNodePointSelected(curve_it1->initialPoint())) { powerend = filletChamferData[counter][X]; } result.push_back(Point(powerend, filletChamferData[counter][Y])); @@ -333,24 +325,6 @@ void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pa void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_pathv, int type) { - std::vector<Geom::Point> point; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nodeTool = - INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = - nodeTool->_selected_nodes->allPoints(); - std::vector<Geom::Point>::iterator pBegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = - selection.begin(); - i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); - pBegin = point.begin(); - point.insert(pBegin, desktop->doc2dt(n->position())); - } - } - } std::vector<Point> filletChamferData = fillet_chamfer_values.data(); std::vector<Geom::Point> result; std::vector<Geom::Path> original_pathv_processed = pathv_to_linear_and_cubic_beziers(original_pathv); @@ -373,12 +347,18 @@ void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_path bool toggle = true; if (filletChamferData[counter][Y] == 0 || (ignore_radius_0 && (filletChamferData[counter][X] == 0 || - filletChamferData[counter][X] == counter)) || - (only_selected && - !nodeIsSelected(curve_it1->initialPoint(), point))) { + filletChamferData[counter][X] == counter)) || + (only_selected && !isNodePointSelected(curve_it1->initialPoint()))) { toggle = false; } if (toggle) { + if(type >= 5000){ + if(filletChamferData[counter][Y] >= 3000 && filletChamferData[counter][Y] < 4000){ + type = type - 2000; + } else if (filletChamferData[counter][Y] >= 4000 && filletChamferData[counter][Y] < 5000){ + type = type - 1000; + } + } result.push_back(Point(filletChamferData[counter][X], type)); } else { result.push_back(filletChamferData[counter]); @@ -451,6 +431,8 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) fillet_chamfer_values.param_set_and_write_new_value(point); } else { g_warning("LPE Fillet can only be applied to shapes (not groups)."); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeItem); + item->removeCurrentPathEffect(false); } } @@ -462,6 +444,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) } else { fillet_chamfer_values.set_helper_size(helper_size); } + fillet_chamfer_values.set_document_unit(defaultUnit); fillet_chamfer_values.set_use_distance(use_knot_distance); fillet_chamfer_values.set_unit(unit.get_abbreviation()); SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast<SPPath const *>(lpeItem) @@ -597,11 +580,37 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) } else { type = std::abs(filletChamferData[counter + 1][Y]); } - if (type == 3 || type == 4) { - if (type == 4) { - Geom::Point central = middle_point(startArcPoint, endArcPoint); - LineSegment chamferCenter(central, curve_it1->finalPoint()); - path_out.appendNew<Geom::LineSegment>(chamferCenter.pointAt(0.5)); + if(are_near(middle_point(startArcPoint,endArcPoint),curve_it1->finalPoint(), 0.0001)){ + path_out.appendNew<Geom::LineSegment>(endArcPoint); + } else if (type >= 3000 && type < 4000) { + unsigned int chamferSubs = type-3000; + Geom::Path path_chamfer; + path_chamfer.start(path_out.finalPoint()); + if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ + path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); + } else { + path_chamfer.appendNew<Geom::CubicBezier>(handle1, handle2, endArcPoint); + } + double chamfer_stepsTime = 1.0/chamferSubs; + for(unsigned int i = 1; i < chamferSubs; i++){ + Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i); + path_out.appendNew<Geom::LineSegment>(chamferStep); + } + path_out.appendNew<Geom::LineSegment>(endArcPoint); + } else if (type >= 4000 && type < 5000) { + unsigned int chamferSubs = type-4000; + Geom::Path path_chamfer; + path_chamfer.start(path_out.finalPoint()); + if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ + ccwToggle = ccwToggle?0:1; + path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); + }else{ + path_chamfer.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); + } + double chamfer_stepsTime = 1.0/chamferSubs; + for(unsigned int i = 1; i < chamferSubs; i++){ + Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i); + path_out.appendNew<Geom::LineSegment>(chamferStep); } path_out.appendNew<Geom::LineSegment>(endArcPoint); } else if (type == 2) { @@ -611,7 +620,7 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) }else{ path_out.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); } - } else { + } else if (type == 1){ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); } else { diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h index 873684101..0d6a1ff17 100644 --- a/src/live_effects/lpe-fillet-chamfer.h +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -56,13 +56,13 @@ public: void toggleHide(); void toggleFlexFixed(); void chamfer(); + void chamferSubdivisions(); + void inverseChamfer(); void fillet(); - void doubleChamfer(); - void inverse(); + void inverseFillet(); void updateFillet(); void doUpdateFillet(std::vector<Geom::Path> const& original_pathv, double power); void doChangeType(std::vector<Geom::Path> const& original_pathv, int type); - bool nodeIsSelected(Geom::Point nodePoint, std::vector<Geom::Point> points); void refreshKnots(); FilletChamferPointArrayParam fillet_chamfer_values; @@ -77,6 +77,7 @@ private: UnitParam unit; EnumParam<FilletMethod> method; ScalarParam radius; + ScalarParam chamfer_steps; ScalarParam helper_size; LPEFilletChamfer(const LPEFilletChamfer &); diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 8fadd79ed..e1cd91340 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -394,7 +394,7 @@ LPELattice2::resetGrid() grid_point32x33x34x35.param_set_and_write_default(); //todo:this hack is only to reposition the knots on reser grid button //Better update path effect in LPEITEM - SPDesktop * desktop = inkscape_active_desktop(); + SPDesktop * desktop = SP_ACTIVE_DESKTOP; tools_switch(desktop, TOOLS_SELECT); tools_switch(desktop, TOOLS_NODES); } diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 4d8c79198..b5ef26e2f 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -193,8 +193,8 @@ LPEPerspectiveEnvelope::project_point(Geom::Point p){ double height = boundingbox_Y.extent(); double delta_x = boundingbox_X.min() - p[X]; double delta_y = boundingbox_Y.max() - p[Y]; - Geom::Coord xratio = (delta_x * sgn(delta_x)) / width; - Geom::Coord yratio = (delta_y * sgn(delta_y)) / height; + Geom::Coord xratio = (delta_x * -1) / width; + Geom::Coord yratio = delta_y / height; Geom::Line* horiz = new Geom::Line(); Geom::Line* vert = new Geom::Line(); vert->setPoints (pointAtRatio(yratio,Down_Left_Point,Up_Left_Point),pointAtRatio(yratio,Down_Right_Point,Up_Right_Point)); @@ -337,7 +337,7 @@ LPEPerspectiveEnvelope::resetGrid() Down_Left_Point.param_set_and_write_default(); //todo:this hack is only to reposition the knots on reser grid button //Better update path effect in LPEITEM - SPDesktop * desktop = inkscape_active_desktop(); + SPDesktop * desktop = SP_ACTIVE_DESKTOP; tools_switch(desktop, TOOLS_SELECT); tools_switch(desktop, TOOLS_NODES); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index d43772cf7..901519b4f 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -23,7 +23,7 @@ #include "knot-holder-entity.h" #include "knotholder.h" #include "desktop.h" - +#include <util/units.h> #include "inkscape.h" #include <2geom/path.h> @@ -44,6 +44,8 @@ public: } // namespace PP static Glib::ustring perspectiveID = _("First perspective"); + + LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -62,35 +64,42 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; - unapply = false; - Persp3D *persp = persp3d_document_first_persp(lpeobject->document); +} + +LPEPerspectivePath::~LPEPerspectivePath() +{ + +} +void +LPEPerspectivePath::doOnApply(SPLPEItem const* lpeitem) +{ + Persp3D *persp = persp3d_document_first_persp(lpeitem->document); if(persp == 0 ){ char *msg = _("You need a BOX 3D object"); Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true); dialog.run(); - unapply = true; - return; + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->removeCurrentPathEffect(false); } - Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; - pmat = pmat * SP_ACTIVE_DESKTOP->doc2dt(); - pmat.copy_tmat(tmat); } - -LPEPerspectivePath::~LPEPerspectivePath() -{ - -} - void LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem, true); - if(unapply){ - SP_LPE_ITEM(lpeitem)->removeCurrentPathEffect(false); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + Persp3D *persp = persp3d_document_first_persp(lpeitem->document); + if(persp == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); return; } - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + Geom::Affine doc2d = Geom::Scale(1, -1) * Geom::Translate(0, item->document->getHeight().value("px")); + pmat = pmat * doc2d; + pmat.copy_tmat(tmat); item->apply_to_clippath(item); item->apply_to_mask(item); } diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index 6ccac4a51..c4ddf1853 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -33,9 +33,8 @@ class LPEPerspectivePath : public Effect, GroupBBoxEffect { public: LPEPerspectivePath(LivePathEffectObject *lpeobject); virtual ~LPEPerspectivePath(); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - + virtual void doOnApply(SPLPEItem const* lpeitem); virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); virtual void refresh(Gtk::Entry* perspective); @@ -53,8 +52,6 @@ private: ScalarParam offsety; BoolParam uses_plane_xy; // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist! - - bool unapply; Geom::Point orig; LPEPerspectivePath(const LPEPerspectivePath&); diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 03a10807a..f7fe9592d 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -277,7 +277,7 @@ LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem) double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed / 2 : 1.; SPCSSAttr *css = sp_repr_css_attr_new (); - if (true) { + if (lpeitem->style) { if (lpeitem->style->stroke.isPaintserver()) { SPPaintServer * server = lpeitem->style->getStrokePaintServer(); if (server) { diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index ffd5433bf..8cef9a3a3 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -14,12 +14,13 @@ */ #include <gtkmm.h> - +#include "desktop.h" #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include "live_effects/parameter/parameter.h" #include "helper/geom.h" #include <glibmm/i18n.h> +#include <util/units.h> #include <cmath> namespace Inkscape { @@ -46,6 +47,8 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "displaceX", &wr, this, 10.), displaceY(_("Max. displacement in Y"), _("Max. displacement in Y"), "displaceY", &wr, this, 10.), + globalRandomize(_("Global randomize"), _("Global randomize"), + "globalRandomize", &wr, this, 1.), shiftNodes(_("Shift nodes"), _("Shift nodes"), "shiftNodes", &wr, this, true), shiftNodeHandles(_("Shift node handles"), _("Shift node handles"), @@ -57,10 +60,12 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&segments); registerParameter(&displaceX); registerParameter(&displaceY); + registerParameter(&globalRandomize); registerParameter(&shiftNodes); registerParameter(&shiftNodeHandles); displaceX.param_set_range(0., Geom::infinity()); displaceY.param_set_range(0., Geom::infinity()); + globalRandomize.param_set_range(0., Geom::infinity()); maxSegmentSize.param_set_range(0., Geom::infinity()); maxSegmentSize.param_set_increments(1, 1); maxSegmentSize.param_set_digits(1); @@ -75,6 +80,7 @@ void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { displaceX.resetRandomizer(); displaceY.resetRandomizer(); + globalRandomize.resetRandomizer(); srand(1); SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); item->apply_to_clippath(item); @@ -118,6 +124,15 @@ Gtk::Widget *LPERoughen::newWidget() vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); } + if (param->param_key == "globalRandomize") { + Gtk::Label *displaceXLabel = Gtk::manage(new Gtk::Label( + Glib::ustring(_("<b>Extra roughen</b> Add a extra layer of rough")), + Gtk::ALIGN_START)); + displaceXLabel->set_use_markup(true); + vbox->pack_start(*displaceXLabel, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } Glib::ustring *tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); @@ -145,10 +160,11 @@ double LPERoughen::sign(double randNumber) Geom::Point LPERoughen::randomize() { + Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units; double displaceXParsed = Inkscape::Util::Quantity::convert( - displaceX, unit.get_abbreviation(), "px"); + displaceX * globalRandomize, unit.get_abbreviation(), svg_units->abbr); double displaceYParsed = Inkscape::Util::Quantity::convert( - displaceY, unit.get_abbreviation(), "px"); + displaceY * globalRandomize, unit.get_abbreviation(), svg_units->abbr); Geom::Point output = Geom::Point(sign(displaceXParsed), sign(displaceYParsed)); return output; @@ -159,6 +175,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); curve->reset(); + Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units; for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) @@ -185,6 +202,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Point A1(0, 0); Geom::Point A2(0, 0); Geom::Point A3(0, 0); + bool first = true; while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; A0 = curve_it1->initialPoint(); @@ -194,7 +212,7 @@ void LPERoughen::doEffect(SPCurve *curve) cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); if (cubic) { A1 = (*cubic)[1]; - if (shiftNodes) { + if (shiftNodes && first) { A1 = (*cubic)[1] + initialMove; } A2 = (*cubic)[2]; @@ -203,7 +221,7 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve->lineto(A3); } double length = Inkscape::Util::Quantity::convert( - curve_it1->length(0.001), "px", unit.get_abbreviation()); + curve_it1->length(0.001), svg_units->abbr, unit.get_abbreviation()); std::size_t splits = 0; if (method == DM_SEGMENTS) { splits = segments; @@ -232,6 +250,7 @@ void LPERoughen::doEffect(SPCurve *curve) if(curve_it2 != curve_endit) { ++curve_it2; } + first = false; } if (path_it->closed()) { nCurve->closepath_current(); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index d5ec726bd..74331f1ef 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -51,8 +51,10 @@ private: ScalarParam segments; RandomParam displaceX; RandomParam displaceY; + RandomParam globalRandomize; BoolParam shiftNodes; BoolParam shiftNodeHandles; + LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 7b2b445b7..2d8148730 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -25,15 +25,20 @@ LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject) nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true), handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true), originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true), - scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10) + scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10), + rotateNodes(_("Rotate nodes"), _("Rotate nodes"), "rotateNodes", &wr, this, 0) { registerParameter(dynamic_cast<Parameter *>(&nodes)); registerParameter(dynamic_cast<Parameter *>(&handles)); registerParameter(dynamic_cast<Parameter *>(&originalPath)); registerParameter(dynamic_cast<Parameter *>(&scaleNodesAndHandles)); + registerParameter(dynamic_cast<Parameter *>(&rotateNodes)); scaleNodesAndHandles.param_set_range(0, 500.); scaleNodesAndHandles.param_set_increments(1, 1); scaleNodesAndHandles.param_set_digits(2); + rotateNodes.param_set_range(0, 365); + rotateNodes.param_set_increments(1, 1); + rotateNodes.param_set_digits(0); strokeWidth = 1.0; } @@ -158,10 +163,11 @@ LPEShowHandles::drawNode(Geom::Point p) if(strokeWidth * scaleNodesAndHandles > 0.0) { double diameter = strokeWidth * scaleNodesAndHandles; char const * svgd; - svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; + svgd = "M 0.05,0 A 0.05,0.05 0 0 1 0,0.05 0.05,0.05 0 0 1 -0.05,0 0.05,0.05 0 0 1 0,-0.05 0.05,0.05 0 0 1 0.05,0 Z M -0.5,-0.5 0.5,-0.5 0.5,0.5 -0.5,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); - pathv *= Geom::Affine(diameter,0,0,diameter,0,0); - pathv += p - Geom::Point(diameter/2,diameter/2); + pathv *= Geom::Rotate::from_degrees(rotateNodes); + pathv *= Geom::Scale (diameter); + pathv += p; outlinepath.push_back(pathv[0]); outlinepath.push_back(pathv[1]); } @@ -175,8 +181,8 @@ LPEShowHandles::drawHandle(Geom::Point p) char const * svgd; svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); - pathv *= Geom::Affine(diameter,0,0,diameter,0,0); - pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35); + pathv *= Geom::Scale (diameter); + pathv += p-Geom::Point(diameter * 0.35,diameter * 0.35); outlinepath.push_back(pathv[0]); } } diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h index 278908bb5..a405c26ee 100644 --- a/src/live_effects/lpe-show_handles.h +++ b/src/live_effects/lpe-show_handles.h @@ -44,6 +44,7 @@ private: BoolParam handles; BoolParam originalPath; ScalarParam scaleNodesAndHandles; + ScalarParam rotateNodes; double strokeWidth; static bool alertsOff; diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index c191fbbe6..2b2efb1a9 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -157,8 +157,8 @@ LPESimplify::doEffect(SPCurve *curve) { Geom::PathVector outres = Geom::parse_svg_path(pathliv->svg_dump_path()); generateHelperPath(outres); curve->set_pathvector(outres); - if(SP_ACTIVE_DESKTOP && INK_IS_NODE_TOOL(SP_ACTIVE_DESKTOP->event_context)){ - SPDesktop* desktop = SP_ACTIVE_DESKTOP; + SPDesktop* desktop = SP_ACTIVE_DESKTOP; + if(desktop && INK_IS_NODE_TOOL(desktop->event_context)){ Inkscape::UI::Tools::NodeTool *nt = static_cast<Inkscape::UI::Tools::NodeTool*>(desktop->event_context); nt->update_helperpath(); } diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index b595b8d55..7a024147c 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -71,12 +71,12 @@ static const Util::EnumDataConverter<unsigned> JoinTypeConverter(JoinType, sizeo LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), - line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 1.), - attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), - attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), - smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), - join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), - miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.) + line_width(_("Stroke width:"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 1.), + attach_start(_("Start offset:"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), + attach_end(_("End offset:"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), + smoothing(_("Taper smoothing:"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), + join_type(_("Join type:"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), + miter_limit(_("Miter limit:"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.) { show_orig_path = true; _provides_knotholder_entities = true; diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index db24a9735..2ebe11b4b 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -354,11 +354,21 @@ void FilletChamferPointArrayParam::set_pwd2( last_pwd2_normal = pwd2_normal_in; } +void FilletChamferPointArrayParam::set_document_unit(Glib::ustring const * value_document_unit) +{ + documentUnit = value_document_unit; +} + void FilletChamferPointArrayParam::set_helper_size(int hs) { helper_size = hs; } +void FilletChamferPointArrayParam::set_chamfer_steps(int value_chamfer_steps) +{ + chamfer_steps = value_chamfer_steps; +} + void FilletChamferPointArrayParam::set_use_distance(bool use_knot_distance ) { use_distance = use_knot_distance; @@ -683,28 +693,6 @@ void FilletChamferPointArrayParam::set_oncanvas_looks(SPKnotShapeType shape, knot_mode = mode; knot_color = color; } -/* -class FilletChamferPointArrayParamKnotHolderEntity : public KnotHolderEntity { -public: - FilletChamferPointArrayParamKnotHolderEntity(FilletChamferPointArrayParam -*p, unsigned int index); - virtual ~FilletChamferPointArrayParamKnotHolderEntity() {} - - virtual void knot_set(Point const &p, Point const &origin, guint state); - virtual Point knot_get() const; - virtual void knot_click(guint state); - virtual void knot_doubleclicked(guint state); - - /Checks whether the index falls within the size of the parameter's vector/ - bool valid_index(unsigned int index) const { - return (_pparam->_vector.size() > index); - }; - -private: - FilletChamferPointArrayParam *_pparam; - unsigned int _index; -}; -/*/ FilletChamferPointArrayParamKnotHolderEntity:: FilletChamferPointArrayParamKnotHolderEntity( @@ -712,19 +700,18 @@ FilletChamferPointArrayParamKnotHolderEntity( : _pparam(p), _index(index) {} void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p, - Point const &origin, - guint state) + Point const &/*origin*/, + guint state) { using namespace Geom; if (!valid_index(_index)) { return; } - /// @todo how about item transforms??? Piecewise<D2<SBasis> > const &pwd2 = _pparam->get_pwd2(); - //todo: add snapping - //Geom::Point const s = snap_knot_position(p, state); double t = nearest_point(p, pwd2[_index]); + Geom::Point const s = snap_knot_position(pwd2[_index].valueAt(t), state); + t = nearest_point(s, pwd2[_index]); if (t == 1) { t = 0.9999; } @@ -766,28 +753,45 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); }else{ using namespace Geom; - double type = _pparam->_vector.at(_index)[Y] + 1; - if (type > 4) { - type = 1; + int type = (int)_pparam->_vector.at(_index)[Y]; + if (type >=3000 && type < 4000){ + type = 3; } - _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type); + if (type >=4000 && type < 5000){ + type = 4; + } + switch(type){ + case 1: + type = 2; + break; + case 2: + type = _pparam->chamfer_steps + 3000; + break; + case 3: + type = _pparam->chamfer_steps + 4000; + break; + default: + type = 1; + break; + } + _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], (double)type); _pparam->param_set_and_write_new_value(_pparam->_vector); sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); const gchar *tip; - if (type == 3) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + if (type >=3000 && type < 4000){ + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == 2) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, " + } else if (type >=4000 && type < 5000) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == 1) { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, " + } else if (type == 2) { + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else { - tip = _("<b>Double Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } @@ -809,7 +813,7 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) bool aprox = (A[0].degreesOfFreedom() != 2 || B[0].degreesOfFreedom() != 2) && !_pparam->use_distance?true:false; Geom::Point offset = Geom::Point(xModified, _pparam->_vector.at(_index).y()); Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog( - this->desktop, offset, this, _pparam->unit, _pparam->use_distance, aprox); + this->desktop, offset, this, _pparam->unit, _pparam->use_distance, aprox, _pparam->documentUnit); } } @@ -835,20 +839,20 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, continue; } const gchar *tip; - if (_vector[i][Y] == 3) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + if (_vector[i][Y] >=3000 && _vector[i][Y] < 4000){ + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); - } else if (_vector[i][Y] == 2) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, " + } else if (_vector[i][Y] >=4000 && _vector[i][Y] < 5000) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); - } else if (_vector[i][Y] == 1) { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, " + } else if (_vector[i][Y] == 2) { + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else { - tip = _("<b>Double Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } diff --git a/src/live_effects/parameter/filletchamferpointarray.h b/src/live_effects/parameter/filletchamferpointarray.h index a1fa698ae..6e5cce353 100644 --- a/src/live_effects/parameter/filletchamferpointarray.h +++ b/src/live_effects/parameter/filletchamferpointarray.h @@ -52,6 +52,8 @@ public: std::vector<double> get_times(int index, std::vector<Geom::Path> subpaths, bool last); virtual void set_helper_size(int hs); virtual void set_use_distance(bool use_knot_distance); + virtual void set_chamfer_steps(int value_chamfer_steps); + virtual void set_document_unit(Glib::ustring const * value_document_unit); virtual void set_unit(const gchar *abbr); virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); @@ -85,8 +87,10 @@ private: SPKnotModeType knot_mode; guint32 knot_color; int helper_size; + int chamfer_steps; bool use_distance; const gchar *unit; + Glib::ustring const * documentUnit; Geom::PathVector hp; Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2; diff --git a/src/live_effects/parameter/originalpath.cpp b/src/live_effects/parameter/originalpath.cpp index 6c4f2a100..0884c4c9c 100644 --- a/src/live_effects/parameter/originalpath.cpp +++ b/src/live_effects/parameter/originalpath.cpp @@ -27,7 +27,7 @@ #include "live_effects/effect.h" #include "inkscape.h" -#include "desktop-handles.h" +#include "desktop.h" #include "selection.h" #include "ui/icon-names.h" @@ -128,7 +128,7 @@ OriginalPathParam::on_select_original_button_click() if (desktop == NULL || original == NULL) { return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->set(original); } diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 7a2fd9769..beb750404 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -47,7 +47,7 @@ Parameter::param_write_to_repr(const char * svgd) // in gtk3, it is an issue: it allocates widget size for the maxmium // value you pass to it, leading to some insane lengths. // If you need this to be more, please be conservative about it. -const double SCALARPARAM_G_MAXDOUBLE = 10000000000; +const double SCALARPARAM_G_MAXDOUBLE = 10000000000.0; // TODO fixme: using an arbitrary large number as a magic value seems fragile. void Parameter::write_to_SVG(void) { diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 2a14d4208..ba95affd9 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -30,7 +30,7 @@ // needed for on-canvas editting: #include "ui/tools-switch.h" #include "ui/shape-editor.h" -#include "desktop-handles.h" + #include "selection.h" // clipboard support #include "ui/clipboard.h" @@ -414,7 +414,7 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) void PathParam::on_edit_button_click() { - SPItem * item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem * item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); if (item != NULL) { param_editOncanvas(item, SP_ACTIVE_DESKTOP); } diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 956a001ad..234a6174d 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -19,6 +19,7 @@ #include "inkscape.h" #include "verbs.h" #include "display/canvas-text.h" + #include <2geom/sbasis-geometric.h> namespace Inkscape { @@ -32,8 +33,8 @@ TextParam::TextParam( const Glib::ustring& label, const Glib::ustring& tip, value(default_value), defvalue(default_value) { - SPDesktop *desktop = inkscape_active_desktop(); // FIXME: we shouldn't use this! - canvas_text = (SPCanvasText *) sp_canvastext_new(sp_desktop_tempgroup(desktop), desktop, Geom::Point(0,0), ""); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: we shouldn't use this! + canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), ""); sp_canvastext_set_text (canvas_text, default_value.c_str()); sp_canvastext_set_coords (canvas_text, 0, 0); } diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp index 6af616e34..ade83dfda 100644 --- a/src/main-cmdlineact.cpp +++ b/src/main-cmdlineact.cpp @@ -9,7 +9,6 @@ #include <ui/view/view.h> #include <desktop.h> -#include <desktop-handles.h> #include <helper/action.h> #include <helper/action-context.h> #include <selection.h> @@ -82,7 +81,7 @@ CmdLineAction::doList (ActionContext const & context) { bool CmdLineAction::idle (void) { std::list<SPDesktop *> desktops; - inkscape_get_all_desktops(desktops); + INKSCAPE.get_all_desktops(desktops); // We're going to assume one desktop per document, because no one // should have had time to make more at this point. diff --git a/src/main.cpp b/src/main.cpp index caec66b05..06c0d4873 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,7 +74,7 @@ #include "svg/svg-color.h" #include "svg/stringstream.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "inkscape-version.h" #include "sp-namedview.h" @@ -322,7 +322,7 @@ struct poptOption options[] = { {"export-dpi", 'd', POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI, - N_("Resolution for exporting to bitmap and for rasterization of filters in PS/EPS/PDF (default 90)"), + N_("Resolution for exporting to bitmap and for rasterization of filters in PS/EPS/PDF (default 96)"), N_("DPI")}, {"export-area", 'a', @@ -933,9 +933,9 @@ guint get_group0_keyval(GdkEventKey const* event); static void snooper(GdkEvent *event, gpointer /*data*/) { - if (inkscape_mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ + if (INKSCAPE.mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ { - GdkModifierType mapping=(GdkModifierType)inkscape_mapalt(); + GdkModifierType mapping=(GdkModifierType)INKSCAPE.mapalt(); switch (event->type) { case GDK_MOTION_NOTIFY: if(event->motion.state & mapping) { @@ -957,7 +957,7 @@ snooper(GdkEvent *event, gpointer /*data*/) { } } - if (inkscape_trackalt()) { + if (INKSCAPE.trackalt()) { // MacOS X with X11 has some problem with the default // xmodmapping. A ~/.xmodmap solution does not work reliably due // to the way we package our executable in a .app that can launch @@ -1042,7 +1042,7 @@ sp_main_gui(int argc, char const **argv) } // Add our icon directory to the search path for icon theme lookups. - gchar *usericondir = profile_path("icons"); + gchar *usericondir = Inkscape::Application::profile_path("icons"); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), usericondir); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INKSCAPE_PIXMAPDIR); g_free(usericondir); @@ -1059,7 +1059,7 @@ sp_main_gui(int argc, char const **argv) gboolean create_new = TRUE; /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. - inkscape_application_init(argv[0], true); + Inkscape::Application::create(argv[0], true); while (fl) { if (sp_file_open((gchar *)fl->data,NULL)) { @@ -1125,14 +1125,14 @@ static int sp_process_file_list(GSList *fl) retVal++; } else { - inkscape_add_document(doc); + INKSCAPE.add_document(doc); if (sp_vacuum_defs) { doc->vacuumDocument(); } // Execute command-line actions (selections and verbs) using our local models - bool has_performed_actions = Inkscape::CmdLineAction::doList(inkscape_active_action_context()); + bool has_performed_actions = Inkscape::CmdLineAction::doList(INKSCAPE.active_action_context()); #ifdef WITH_DBUS // If we've been asked to listen for D-Bus messages, enter a main loop here @@ -1221,7 +1221,7 @@ static int sp_process_file_list(GSList *fl) do_query_dimension (doc, false, sp_query_x? Geom::X : Geom::Y, sp_query_id); } - inkscape_remove_document(doc); + INKSCAPE.remove_document(doc); delete doc; } @@ -1335,7 +1335,7 @@ int sp_main_console(int argc, char const **argv) exit(0); } - inkscape_application_init(argv[0], false); + Inkscape::Application::create(argv[0], false); if (sp_shell) { int retVal = sp_main_shell(argv[0]); // Run as interactive shell @@ -1738,12 +1738,12 @@ static int do_export_ps_pdf(SPDocument* doc, gchar const* uri, char const* mime) } else { (*i)->set_param_bool("blurToBitmap", TRUE); - gdouble dpi = 90.0; + gdouble dpi = 96.0; if (sp_export_dpi) { dpi = atof(sp_export_dpi); if ((dpi < 1) || (dpi > 10000.0)) { - g_warning("DPI value %s out of range [1 - 10000]. Using 90 dpi instead.", sp_export_dpi); - dpi = 90; + g_warning("DPI value %s out of range [1 - 10000]. Using 96 dpi instead.", sp_export_dpi); + dpi = 96; } } diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 18a26d82c..f5e815bf6 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -14,10 +14,8 @@ static char const menus_skeleton[] = " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\">\n" "\n" " <submenu name=\"" N_("_File") "\">\n" -" <submenu name=\"" N_("_New") "\">\n" -" <verb verb-id=\"FileNew\" />\n" -" <verb verb-id=\"FileTemplates\" />\n" -" </submenu>\n" +" <verb verb-id=\"FileNew\" />\n" +" <verb verb-id=\"FileTemplates\" />\n" " <verb verb-id=\"FileOpen\" />\n" " <recent-file-list/>\n" " <verb verb-id=\"FileRevert\" />\n" diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 2b29814b0..338f91463 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -91,7 +91,8 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, for ( SPObject *o = parent->firstChild(); o; o = o->getNext() ) { g_assert(dt != NULL); - if (SP_IS_ITEM(o) && !(dt->itemIsHidden(SP_ITEM(o)) && !clip_or_mask)) { + SPItem *item = dynamic_cast<SPItem *>(o); + if (item && !(dt->itemIsHidden(item) && !clip_or_mask)) { // Snapping to items in a locked layer is allowed // Don't snap to hidden objects, unless they're a clipped path or a mask /* See if this item is on the ignore list */ @@ -104,23 +105,22 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, } if (it == NULL || i == it->end()) { - SPItem *item = SP_ITEM(o); if (item) { if (!clip_or_mask) { // cannot clip or mask more than once // The current item is not a clipping path or a mask, but might // still be the subject of clipping or masking itself ; if so, then // we should also consider that path or mask for snapping to - SPObject *obj = SP_OBJECT(item->clip_ref ? item->clip_ref->getObject() : NULL); + SPObject *obj = item->clip_ref ? item->clip_ref->getObject() : NULL; if (obj && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_PATH_CLIP)) { _findCandidates(obj, it, false, bbox_to_snap, true, item->i2doc_affine()); } - obj = SP_OBJECT(item->mask_ref ? item->mask_ref->getObject() : NULL); + obj = item->mask_ref ? item->mask_ref->getObject() : NULL; if (obj && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_PATH_MASK)) { _findCandidates(obj, it, false, bbox_to_snap, true, item->i2doc_affine()); } } - if (SP_IS_GROUP(o)) { + if (dynamic_cast<SPGroup *>(item)) { _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine); } else { Geom::OptRect bbox_of_item; @@ -197,8 +197,10 @@ void Inkscape::ObjectSnapper::_collectNodes(SnapSourceType const &t, for (std::vector<SnapCandidateItem>::const_iterator i = _candidates->begin(); i != _candidates->end(); ++i) { //Geom::Affine i2doc(Geom::identity()); SPItem *root_item = (*i).item; - if (SP_IS_USE((*i).item)) { - root_item = SP_USE((*i).item)->root(); + + SPUse *use = dynamic_cast<SPUse *>((*i).item); + if (use) { + root_item = use->root(); } g_return_if_fail(root_item); @@ -382,9 +384,10 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/, Geom::Affine i2doc(Geom::identity()); SPItem *root_item = NULL; /* We might have a clone at hand, so make sure we get the root item */ - if (SP_IS_USE((*i).item)) { - i2doc = SP_USE((*i).item)->get_root_transform(); - root_item = SP_USE((*i).item)->root(); + SPUse *use = dynamic_cast<SPUse *>((*i).item); + if (use) { + i2doc = use->get_root_transform(); + root_item = use->root(); g_return_if_fail(root_item); } else { i2doc = (*i).item->i2doc_affine(); @@ -396,7 +399,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/, //Add the item's path to snap to if (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_PATH, SNAPTARGET_PATH_INTERSECTION, SNAPTARGET_TEXT_BASELINE)) { if (p_is_other || p_is_a_node || (!_snapmanager->snapprefs.getStrictSnapping() && p_is_a_bbox)) { - if (SP_IS_TEXT(root_item) || SP_IS_FLOWTEXT(root_item)) { + if (dynamic_cast<SPText *>(root_item) || dynamic_cast<SPFlowtext *>(root_item)) { if (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_TEXT_BASELINE)) { // Snap to the text baseline Text::Layout const *layout = te_get_layout(static_cast<SPItem *>(root_item)); @@ -411,15 +414,17 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/, // the CPU, so we'll only snap to paths having no more than 500 nodes // This also leads to a lag of approx. 500 msec (in my lousy test set-up). bool very_complex_path = false; - if (SP_IS_PATH(root_item)) { - very_complex_path = SP_PATH(root_item)->nodesInPath() > 500; + SPPath *path = dynamic_cast<SPPath *>(root_item); + if (path) { + very_complex_path = path->nodesInPath() > 500; } if (!very_complex_path && root_item && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_PATH, SNAPTARGET_PATH_INTERSECTION)) { SPCurve *curve = NULL; - if (SP_IS_SHAPE(root_item)) { - curve = SP_SHAPE(root_item)->getCurve(); - }/* else if (SP_IS_TEXT(root_item) || SP_IS_FLOWTEXT(root_item)) { + SPShape *shape = dynamic_cast<SPShape *>(root_item); + if (shape) { + curve = shape->getCurve(); + }/* else if (dynamic_cast<SPText *>(root_item) || dynamic_cast<SPFlowtext *>(root_item)) { curve = te_get_layout(root_item)->convertToCurves(); }*/ if (curve) { @@ -711,10 +716,11 @@ void Inkscape::ObjectSnapper::freeSnap(IntermSnapResults &isr, * That path must not be ignored however when snapping to the paths, so we add it here * manually when applicable */ - SPPath *path = NULL; + SPPath const *path = NULL; if (it != NULL) { - if (it->size() == 1 && SP_IS_PATH(*it->begin())) { - path = SP_PATH(*it->begin()); + SPPath const *tmpPath = dynamic_cast<SPPath const *>(*it->begin()); + if ((it->size() == 1) && tmpPath) { + path = tmpPath; } // else: *it->begin() might be a SPGroup, e.g. when editing a LPE of text that has been converted to a group of paths // as reported in bug #356743. In that case we can just ignore it, i.e. not snap to this item } diff --git a/src/object-test.h b/src/object-test.h new file mode 100644 index 000000000..d6a9dbbd3 --- /dev/null +++ b/src/object-test.h @@ -0,0 +1,233 @@ +#ifndef SEEN_OBJECT_TEST_H +#define SEEN_OBJECT_TEST_H + +#include <cassert> +#include <ctime> +#include <cxxtest/TestSuite.h> +#include <string> +#include <vector> + +#include "document.h" +#include "sp-item-group.h" +#include "sp-object.h" +#include "sp-path.h" +#include "sp-root.h" +#include "xml/document.h" +#include "xml/node.h" + +class ObjectTest : public CxxTest::TestSuite +{ +public: + virtual ~ObjectTest() {} + + static ObjectTest *createSuite() { return new ObjectTest(); } + static void destroySuite(ObjectTest *suite) { delete suite; } + + void testObjects() + { + clock_t begin, end; + // Sample document + // svg:svg + // svg:defs + // svg:path + // svg:linearGradient + // svg:stop + // svg:filter + // svg:feGaussianBlur (feel free to implement for other filters) + // svg:clipPath + // svg:rect + // svg:g + // svg:use + // svg:circle + // svg:ellipse + // svg:text + // svg:polygon + // svg:polyline + // svg:image + // svg:line + + char const *docString = + "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" + "<!-- just a comment -->\n" + "<title id=\"title\">SVG test</title>\n" + "<defs>\n" + " <path id=\"P\" d=\"M -21,-4 -5,0 -18,12 -3,4 -4,21 0,5 12,17 4,2 21,3 5,-1 17,-12 2,-4 3,-21 -1,-5 -12,-18 -4,-3z\"/>\n" + " <linearGradient id=\"LG\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n" + " <stop offset=\"0%\" style=\"stop-color:#ffff00;stop-opacity:1\"/>\n" + " <stop offset=\"100%\" style=\"stop-color:red;stop-opacity:1\"/>\n" + " </linearGradient>\n" + " <clipPath id=\"clip\" clipPathUnits=\"userSpaceOnUse\">\n" + " <rect x=\"10\" y=\"10\" width=\"100\" height=\"100\"/>\n" + " </clipPath>\n" + " <filter style=\"color-interpolation-filters:sRGB\" id=\"filter\" x=\"-0.15\" width=\"1.34\" y=\"0\" height=\"1\">\n" + " <feGaussianBlur stdDeviation=\"4.26\"/>\n" + " </filter>\n" + "</defs>\n" + + "<g id=\"G\" transform=\"skewX(10.5) translate(9,5)\">\n" + " <use id=\"U\" xlink:href=\"#P\" opacity=\"0.5\" fill=\"#1dace3\" transform=\"rotate(4)\"/>\n" + " <circle id=\"C\" cx=\"45.5\" cy=\"67\" r=\"23\" fill=\"#000\"/>\n" + " <ellipse id=\"E\" cx=\"200\" cy=\"70\" rx=\"85\" ry=\"55\" fill=\"url(#LG)\"/>\n" + " <text id=\"T\" fill=\"#fff\" style=\"font-size:45;font-family:Verdana\" x=\"150\" y=\"86\">TEST</text>\n" + " <polygon id=\"PG\" points=\"60,20 100,40 100,80 60,100 20,80 20,40\" clip-path=\"url(#clip)\" filter=\"url(#filter)\"/>\n" + " <polyline id=\"PL\" points=\"0,40 40,40 40,80 80,80 80,120 120,120 120,160\" style=\"fill:none;stroke:red;stroke-width:4\"/>\n" + " <image id=\"I\" xlink:href=\"data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE4MCIgd2lkdGg9IjUwMCI+PHBhdGggZD0iTTAsNDAgNDAsNDAgNDAs" // this is one line + "ODAgODAsODAgODAsMTIwIDEyMCwxMjAgMTIwLDE2MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOnJlZDtzdHJva2Utd2lkdGg6NCIvPjwvc3ZnPgo=\"/>\n" + " <line id=\"L\" x1=\"20\" y1=\"100\" x2=\"100\" y2=\"20\" stroke=\"black\" stroke-width=\"2\"/>\n" + "</g>\n" + "</svg>\n"; + + begin = clock(); + SPDocument *doc = SPDocument::createNewDocFromMem(docString, strlen(docString), false); + end = clock(); + + assert(doc != NULL); // cannot continue if doc is null, abort! + assert(doc->getRoot() != NULL); + + SPRoot *root = doc->getRoot(); + assert(root->getRepr() != NULL); + assert(root->hasChildren()); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to construct the test document\n"; + + SPPath *path = dynamic_cast<SPPath *>(doc->getObjectById("P")); + testClones(path); + + SPGroup *group = dynamic_cast<SPGroup *>(doc->getObjectById("G")); + testGrouping(group); + + // Test parent behavior + SPObject *child = root->firstChild(); + assert(child != NULL); + TS_ASSERT(child->parent == root); + TS_ASSERT(child->document == doc); + TS_ASSERT(root->isAncestorOf(child)); + + // Test list behavior + SPObject *next = child->getNext(); + SPObject *prev = next; + TS_ASSERT(next->getPrev() == child); + prev = next; + next = next->getNext(); + while (next != NULL) { + // Walk the list + TS_ASSERT(next->getPrev() == prev); + prev = next; + next = next->getNext(); + } + TS_ASSERT(child->lastChild() == next); + + // Test hrefcount + TS_ASSERT(path->isReferenced()); + } + + void testClones(SPPath *path) + { + clock_t begin, end; + + assert(path != NULL); + + // Since we don't yet have any clean way to do this (FIXME), we'll abuse the XML tree a bit. + Inkscape::XML::Node *node = path->getRepr(); + assert(node != NULL); + + Inkscape::XML::Document *xml_doc = node->document(); + + Inkscape::XML::Node *parent = node->parent(); + assert(parent != NULL); + + TS_TRACE("Benchmarking clones..."); + const size_t num_clones = 10000; + + std::string href(std::string("#") + std::string(path->getId())); + std::vector<Inkscape::XML::Node *> clones(num_clones, NULL); + + begin = clock(); + // Create num_clones clones of this path and stick them in the document + for (size_t i = 0; i < num_clones; ++i) { + Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); + Inkscape::GC::release(clone); + clone->setAttribute("xlink:href", href.c_str()); + parent->addChild(clone, node); + clones[i] = clone; + } + end = clock(); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to write " << num_clones << " clones of a path\n"; + + begin = clock(); + // Remove those clones + for (size_t i = num_clones - 1; i >= 1; --i) { + parent->removeChild(clones[i]); + } + end = clock(); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to remove " << num_clones << " clones of a path\n"; + } + + void testGrouping(SPGroup *group) + { + clock_t begin, end; + + assert(group != NULL); + + // Since we don't yet have any clean way to do this (FIXME), we'll abuse the XML tree a bit. + Inkscape::XML::Node *node = group->getRepr(); + assert(node != NULL); + + Inkscape::XML::Document *xml_doc = node->document(); + + TS_TRACE("Benchmarking groups..."); + const size_t num_elements = 10000; + + Inkscape::XML::Node *new_group = xml_doc->createElement("svg:g"); + Inkscape::GC::release(new_group); + node->addChild(new_group, NULL); + + std::vector<Inkscape::XML::Node *> elements(num_elements, NULL); + + begin = clock(); + for (size_t i = 0; i < num_elements; ++i) { + Inkscape::XML::Node *circle = xml_doc->createElement("svg:circle"); + Inkscape::GC::release(circle); + circle->setAttribute("cx", "2048"); + circle->setAttribute("cy", "1024"); + circle->setAttribute("r", "1.5"); + new_group->addChild(circle, NULL); + elements[i] = circle; + } + end = clock(); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to write " << num_elements << " elements into a group\n"; + + SPGroup *n_group = dynamic_cast<SPGroup *>(group->get_child_by_repr(new_group)); + assert(n_group != NULL); + + begin = clock(); + sp_item_group_ungroup(n_group, NULL, false); + end = clock(); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to ungroup a <g> with " << num_elements << " elements\n"; + + begin = clock(); + // Remove those elements + for (size_t i = num_elements - 1; i >= 1; --i) { + elements[i]->parent()->removeChild(elements[i]); + } + end = clock(); + + std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to remove " << num_elements << " elements\n"; + } +}; +#endif // SEEN_OBJECT_TEST_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 0c3f9cde7..5f6e1495b 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -35,7 +35,7 @@ #include "document-undo.h" #include "message-stack.h" #include "selection.h" -#include "desktop-handles.h" + #include "box3d.h" #include <2geom/pathvector.h> #include "selection-chemistry.h" @@ -47,11 +47,11 @@ using Inkscape::DocumentUndo; void sp_selected_path_combine(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (g_slist_length((GSList *) selection->itemList()) < 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); return; } @@ -170,7 +170,7 @@ sp_selected_path_combine(SPDesktop *desktop) // move to the position of the topmost, reduced by the number of deleted items repr->setPosition(position > 0 ? position : 0); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_COMBINE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_COMBINE, _("Combine")); selection->set(repr); @@ -178,7 +178,7 @@ sp_selected_path_combine(SPDesktop *desktop) Inkscape::GC::release(repr); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to combine in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to combine in the selection.")); } desktop->clearWaitingCursor(); @@ -187,10 +187,10 @@ sp_selected_path_combine(SPDesktop *desktop) void sp_selected_path_break_apart(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to break apart.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to break apart.")); return; } @@ -283,10 +283,10 @@ sp_selected_path_break_apart(SPDesktop *desktop) desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_BREAK_APART, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_BREAK_APART, _("Break apart")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to break apart in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to break apart in the selection.")); } } @@ -296,7 +296,7 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b { if (selection->isEmpty()) { if (interactive && desktop) - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to path.")); return; } @@ -323,10 +323,10 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b if (interactive && desktop) { desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_OBJECT_TO_CURVE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_TO_CURVE, _("Object to path")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection.")); return; } } @@ -335,7 +335,7 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b /** Converts the selected items to LPEItems if they are not already so; e.g. SPRects) */ void sp_selected_to_lpeitems(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { return; @@ -500,11 +500,12 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) /* Rotation center */ g_repr->setAttribute("inkscape:transform-center-x", item->getRepr()->attribute("inkscape:transform-center-x"), false); g_repr->setAttribute("inkscape:transform-center-y", item->getRepr()->attribute("inkscape:transform-center-y"), false); + /* Whole text's style */ - gchar *style_str = sp_style_write_difference(item->style, - item->parent ? item->parent->style : NULL); // TODO investigate posibility - g_repr->setAttribute("style", style_str); - g_free(style_str); + Glib::ustring style_str = + item->style->write( SP_STYLE_FLAG_IFDIFF, item->parent ? item->parent->style : NULL); // TODO investigate posibility + g_repr->setAttribute("style", style_str.c_str()); + Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); do { Inkscape::Text::Layout::iterator iter_next = iter; @@ -522,19 +523,17 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) while (dynamic_cast<SPString const *>(pos_obj) && pos_obj->parent) { pos_obj = pos_obj->parent; // SPStrings don't have style } - gchar *style_str = sp_style_write_difference(pos_obj->style, - pos_obj->parent ? pos_obj->parent->style : NULL); // TODO investigate posibility + Glib::ustring style_str = + pos_obj->style->write( SP_STYLE_FLAG_IFDIFF, pos_obj->parent ? pos_obj->parent->style : NULL); // TODO investigate posibility // get path from iter to iter_next: SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next); iter = iter_next; // shift to next glyph if (!curve) { // error converting this glyph - g_free (style_str); continue; } if (curve->is_empty()) { // whitespace glyph? curve->unref(); - g_free (style_str); continue; } @@ -545,8 +544,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) g_free(def_str); curve->unref(); - p_repr->setAttribute("style", style_str); - g_free(style_str); + p_repr->setAttribute("style", style_str.c_str()); g_repr->appendChild(p_repr); Inkscape::GC::release(p_repr); @@ -565,7 +563,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) if (shape) { curve = shape->getCurve(); } - } + } if (!curve) return NULL; @@ -581,11 +579,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); /* Transformation */ repr->setAttribute("transform", item->getRepr()->attribute("transform")); + /* Style */ - gchar *style_str = sp_style_write_difference(item->style, - item->parent ? item->parent->style : NULL); // TODO investigate posibility - repr->setAttribute("style", style_str); - g_free(style_str); + Glib::ustring style_str = + item->style->write( SP_STYLE_FLAG_IFDIFF, item->parent ? item->parent->style : NULL); // TODO investigate posibility + repr->setAttribute("style", style_str.c_str()); /* Mask */ gchar *mask_str = (gchar *) item->getRepr()->attribute("mask"); @@ -613,11 +611,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) void sp_selected_path_reverse(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList *items = (GSList *) selection->itemList(); if (!items) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); return; } @@ -660,10 +658,10 @@ sp_selected_path_reverse(SPDesktop *desktop) desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_REVERSE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_REVERSE, _("Reverse path")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); } } diff --git a/src/persp3d.cpp b/src/persp3d.cpp index b10e5f23b..c761947ad 100644 --- a/src/persp3d.cpp +++ b/src/persp3d.cpp @@ -19,9 +19,11 @@ #include "vanishing-point.h" #include "ui/tools/box3d-tool.h" #include "box3d.h" +#include "svg/stringstream.h" #include "xml/document.h" #include "xml/node-event-vector.h" -#include "desktop-handles.h" +#include "desktop.h" + #include <glibmm/i18n.h> #include "verbs.h" #include "util/units.h" @@ -30,9 +32,6 @@ using Inkscape::DocumentUndo; static void persp3d_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); -static void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image); -static gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis); - static int global_counter = 0; #include "sp-factory.h" @@ -102,36 +101,48 @@ void Persp3D::release() { // FIXME: Currently we only read the finite positions of vanishing points; // should we move VPs into their own repr (as it's done for SPStop, e.g.)? void Persp3D::set(unsigned key, gchar const *value) { - Persp3DImpl *persp_impl = this->perspective_impl; + + // Read values are in 'user units'. + double scale_x = 1.0; + double scale_y = 1.0; + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + } switch (key) { case SP_ATTR_INKSCAPE_PERSP3D_VP_X: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::X, new_image); + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::X, ptn ); } break; } case SP_ATTR_INKSCAPE_PERSP3D_VP_Y: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::Y, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::Y, ptn ); } + break; } case SP_ATTR_INKSCAPE_PERSP3D_VP_Z: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::Z, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::Z, ptn ); } + break; } case SP_ATTR_INKSCAPE_PERSP3D_ORIGIN: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::W, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::W, ptn ); } + break; } default: { SPObject::set(key, value); @@ -140,7 +151,7 @@ void Persp3D::set(unsigned key, gchar const *value) { } // FIXME: Is this the right place for resetting the draggers? - Inkscape::UI::Tools::ToolBase *ec = inkscape_active_event_context(); + Inkscape::UI::Tools::ToolBase *ec = INKSCAPE.active_event_context(); if (SP_IS_BOX3D_CONTEXT(ec)) { Inkscape::UI::Tools::Box3dTool *bc = SP_BOX3D_CONTEXT(ec); bc->_vpdrag->updateDraggers(); @@ -169,10 +180,19 @@ Persp3D *persp3d_create_xml_element(SPDocument *document, Persp3DImpl *dup) {// repr = xml_doc->createElement("inkscape:perspective"); repr->setAttribute("sodipodi:type", "inkscape:persp3d"); - Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight().value("px")/2, 1.0); - Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); - Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth().value("px"), document->getHeight().value("px")/2, 1.0); - Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth().value("px")/2, document->getHeight().value("px")/3, 1.0); + // Use 'user-units' + double width = document->getWidth().value("px"); + double height = document->getHeight().value("px"); + if( document->getRoot()->viewBox_set ) { + Geom::Rect vb = document->getRoot()->viewBox; + width = vb.width(); + height = vb.height(); + } + + Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, height/2.0, 1.0); + Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); + Proj::Pt2 proj_vp_z = Proj::Pt2 (width, height/2.0, 1.0); + Proj::Pt2 proj_origin = Proj::Pt2 (width/2.0, height/3.0, 1.0 ); if (dup) { proj_vp_x = dup->tmat.column (Proj::X); @@ -217,7 +237,6 @@ Persp3D *persp3d_document_first_persp(SPDocument *document) * Virtual write: write object attributes to repr. */ Inkscape::XML::Node* Persp3D::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - Persp3DImpl *persp_impl = this->perspective_impl; if ((flags & SP_OBJECT_WRITE_BUILD & SP_OBJECT_WRITE_EXT) && !repr) { // this is where we end up when saving as plain SVG (also in other circumstances?); @@ -226,18 +245,39 @@ Inkscape::XML::Node* Persp3D::write(Inkscape::XML::Document *xml_doc, Inkscape:: } if (flags & SP_OBJECT_WRITE_EXT) { - gchar *str = NULL; // FIXME: Should this be freed each time we set an attribute or only in the end or at all? - str = persp3d_pt_to_str (persp_impl, Proj::X); - repr->setAttribute("inkscape:vp_x", str); - - str = persp3d_pt_to_str (persp_impl, Proj::Y); - repr->setAttribute("inkscape:vp_y", str); - - str = persp3d_pt_to_str (persp_impl, Proj::Z); - repr->setAttribute("inkscape:vp_z", str); - str = persp3d_pt_to_str (persp_impl, Proj::W); - repr->setAttribute("inkscape:persp3d-origin", str); + // Written values are in 'user units'. + double scale_x = 1.0; + double scale_y = 1.0; + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + scale_x = root->viewBox.width() / root->width.computed; + scale_y = root->viewBox.height() / root->height.computed; + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::X ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_x", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Y ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_y", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Z ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_z", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::W ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:persp3d-origin", os.str().c_str()); + } } SPObject::write(xml_doc, repr, flags); @@ -289,7 +329,7 @@ persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo) { persp3d_update_box_reprs (persp); persp->updateRepr(SP_OBJECT_WRITE_EXT); if (set_undo) { - DocumentUndo::done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Toggle vanishing point")); } } @@ -300,7 +340,7 @@ persp3d_toggle_VPs (std::list<Persp3D *> p, Proj::Axis axis) { for (std::list<Persp3D *>::iterator i = p.begin(); i != p.end(); ++i) { persp3d_toggle_VP((*i), axis, false); } - DocumentUndo::done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Toggle multiple vanishing points")); } @@ -329,23 +369,12 @@ persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_press } void -persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image) { - persp_impl->tmat.set_image_pt (axis, new_image); -} - -void persp3d_apply_affine_transformation (Persp3D *persp, Geom::Affine const &xform) { persp->perspective_impl->tmat *= xform; persp3d_update_box_reprs(persp); persp->updateRepr(SP_OBJECT_WRITE_EXT); } -gchar * -persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis) -{ - return persp_impl->tmat.pt_to_str(axis); -} - void persp3d_add_box (Persp3D *persp, SPBox3D *box) { Persp3DImpl *persp_impl = persp->perspective_impl; @@ -527,7 +556,7 @@ persp3d_print_all_selected() { g_print ("\n======================================\n"); g_print ("Selected perspectives and their boxes:\n"); - std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList(); + std::list<Persp3D *> sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); for (std::list<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) { Persp3D *persp = SP_PERSP3D(*j); diff --git a/src/preferences.cpp b/src/preferences.cpp index d0c3783b5..e5a5fe7f0 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -91,11 +91,13 @@ Preferences::Preferences() : _hasError(false) { // profile_path essentailly returns the argument prefixed by the profile directory. - gchar *path = profile_path(NULL); + // \TODO this is kinda hackish, but the alternative (strrchr) is worse + + gchar *path = Inkscape::Application::profile_path(NULL); _prefs_dir = path; g_free(path); - path = profile_path(_prefs_basename.c_str()); + path = Inkscape::Application::profile_path(_prefs_basename.c_str()); _prefs_filename = path; g_free(path); @@ -155,7 +157,7 @@ void Preferences::_load() // create some subdirectories for user stuff char const *user_dirs[] = {"keys", "templates", "icons", "extensions", "palettes", NULL}; for (int i=0; user_dirs[i]; ++i) { - char *dir = profile_path(user_dirs[i]); + char *dir = Inkscape::Application::profile_path(user_dirs[i]); g_mkdir(dir, 0755); g_free(dir); } diff --git a/src/rubberband.cpp b/src/rubberband.cpp index 6ec4b3e45..4a171f4a1 100644 --- a/src/rubberband.cpp +++ b/src/rubberband.cpp @@ -12,7 +12,7 @@ #include "display/sodipodi-ctrlrect.h" #include "desktop.h" -#include "desktop-handles.h" + #include "rubberband.h" #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" @@ -98,7 +98,7 @@ void Inkscape::Rubberband::move(Geom::Point const &p) if (_mode == RUBBERBAND_MODE_RECT) { if (_rect == NULL) { - _rect = static_cast<CtrlRect *>(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL)); + _rect = static_cast<CtrlRect *>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); _rect->setShadow(1, 0xffffffff); } _rect->setRectangle(Geom::Rect(_start, _end)); @@ -109,7 +109,7 @@ void Inkscape::Rubberband::move(Geom::Point const &p) } else if (_mode == RUBBERBAND_MODE_TOUCHPATH) { if (_touchpath == NULL) { - _touchpath = sp_canvas_bpath_new(sp_desktop_sketch(_desktop), NULL); + _touchpath = sp_canvas_bpath_new(_desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_touchpath), 0xff0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_touchpath), 0, SP_WIND_RULE_NONZERO); } diff --git a/src/satisfied-guide-cns.cpp b/src/satisfied-guide-cns.cpp index 588c78ce0..028a22405 100644 --- a/src/satisfied-guide-cns.cpp +++ b/src/satisfied-guide-cns.cpp @@ -1,5 +1,5 @@ #include <2geom/coord.h> -#include "desktop-handles.h" +#include "desktop.h" #include "sp-guide.h" #include "sp-guide-constraint.h" #include "sp-namedview.h" @@ -9,7 +9,7 @@ void satisfied_guide_cns(SPDesktop const &desktop, std::vector<Inkscape::SnapCandidatePoint> const &snappoints, std::vector<SPGuideConstraint> &cns) { - SPNamedView const &nv = *sp_desktop_namedview(&desktop); + SPNamedView const &nv = *desktop.getNamedView(); for (GSList const *l = nv.guides; l != NULL; l = l->next) { SPGuide &g = *SP_GUIDE(l->data); for (unsigned int i = 0; i < snappoints.size(); ++i) { diff --git a/src/selcue.cpp b/src/selcue.cpp index 805629636..d2fa0970a 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -13,7 +13,8 @@ #include <string.h> -#include "desktop-handles.h" +#include "desktop.h" + #include "selection.h" #include "display/sp-canvas-util.h" #include "display/sodipodi-ctrl.h" @@ -40,7 +41,7 @@ Inkscape::SelCue::SelCue(SPDesktop *desktop) : _desktop(desktop), _bounding_box_prefs_observer(*this) { - _selection = sp_desktop_selection(_desktop); + _selection = _desktop->getSelection(); _sel_changed_connection = _selection->connectChanged( sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_newItemBboxes)) @@ -154,7 +155,7 @@ void Inkscape::SelCue::_newItemBboxes() if (b) { if (mode == MARK) { - box = sp_canvas_item_new(sp_desktop_controls(_desktop), + box = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRL, "mode", SP_CTRL_MODE_XOR, "shape", SP_CTRL_SHAPE_DIAMOND, @@ -170,7 +171,7 @@ void Inkscape::SelCue::_newItemBboxes() sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots } else if (mode == BBOX) { - box = sp_canvas_item_new(sp_desktop_controls(_desktop), + box = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL); @@ -207,7 +208,7 @@ void Inkscape::SelCue::_newTextBaselines() if (layout != NULL && layout->outputExists()) { boost::optional<Geom::Point> pt = layout->baselineAnchorPoint(); if (pt) { - baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL, + baseline_point = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRL, "mode", SP_CTRL_MODE_XOR, "size", 4.0, "filled", 0, diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 6a091bd12..c9837aabe 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -38,7 +38,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "layer-model.h" #include "selection.h" #include "ui/tools-switch.h" -#include "desktop-handles.h" + #include "message-stack.h" #include "sp-item-transform.h" #include "sp-marker.h" @@ -99,7 +99,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "display/curve.h" #include "display/canvas-bpath.h" #include "display/cairo-utils.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "path-chemistry.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/multi-path-manipulator.h" @@ -177,8 +177,8 @@ void SelectionHelper::selectNone(SPDesktop *dt) if (nt && !nt->_selected_nodes->empty()) { nt->_selected_nodes->clear(); - } else if (!sp_desktop_selection(dt)->isEmpty()) { - sp_desktop_selection(dt)->clear(); + } else if (!dt->getSelection()->isEmpty()) { + dt->getSelection()->clear(); } else { // If nothing selected switch to selection tool tools_switch(dt, TOOLS_SELECT); @@ -277,7 +277,7 @@ void SelectionHelper::fixSelection(SPDesktop *dt) if(!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); GSList *items = NULL; @@ -402,12 +402,12 @@ void sp_selection_delete(SPDesktop *desktop) if (tools_isactive(desktop, TOOLS_TEXT)) if (Inkscape::UI::Tools::sp_text_delete_selection(desktop->event_context)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete text")); return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -429,7 +429,7 @@ void sp_selection_delete(SPDesktop *desktop) */ tools_switch( desktop, tools_active( desktop ) ); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_DELETE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DELETE, _("Delete")); } @@ -454,7 +454,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) SPDocument *doc = desktop->doc(); Inkscape::XML::Document* xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -521,11 +521,9 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if (!strcmp(orig->getId(), old_ids[j])) { // we have both orig and clone in selection, relink // std::cout << id << " old, its ori: " << orig->getId() << "; will relink:" << new_ids[i] << " to " << new_ids[j] << "\n"; - gchar *newref = g_strdup_printf("#%s", new_ids[j]); SPObject *new_clone = doc->getObjectById(new_ids[i]); - new_clone->getRepr()->setAttribute("xlink:href", newref); + new_clone->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); new_clone->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - g_free(newref); } } } else { @@ -534,9 +532,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) for (guint j = 0; j < old_ids.size(); j++) { gchar *source_href = offset->sourceHref; if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - gchar *newref = g_strdup_printf("#%s", new_ids[j]); - doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", newref); - g_free(newref); + doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); } } } @@ -546,7 +542,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_DUPLICATE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DUPLICATE, _("Duplicate")); } @@ -613,7 +609,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i if (!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); g_return_if_fail(dynamic_cast<SPGroup *>(dt->currentLayer())); @@ -1146,7 +1142,7 @@ sp_undo(SPDesktop *desktop, SPDocument *) // No re/undo while dragging, too dangerous. if(desktop->getCanvas()->is_dragging) return; - if (!DocumentUndo::undo(sp_desktop_document(desktop))) { + if (!DocumentUndo::undo(desktop->getDocument())) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to undo.")); } } @@ -1157,7 +1153,7 @@ sp_redo(SPDesktop *desktop, SPDocument *) // No re/undo while dragging, too dangerous. if(desktop->getCanvas()->is_dragging) return; - if (!DocumentUndo::redo(sp_desktop_document(desktop))) { + if (!DocumentUndo::redo(desktop->getDocument())) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to redo.")); } } @@ -1198,6 +1194,9 @@ take_style_from_item(SPObject *object) } } + // Remove black-listed properties (those that should not be used in a default style) + css = sp_css_attr_unset_blacklist(css); + if (!(dynamic_cast<SPText *>(object) || dynamic_cast<SPTSpan *>(object) || dynamic_cast<SPTRef *>(object) || dynamic_cast<SPString *>(object))) { // do not copy text properties from non-text objects, it's confusing css = sp_css_attr_unset_text(css); @@ -1227,7 +1226,7 @@ void sp_selection_paste(SPDesktop *desktop, bool in_place) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->paste(desktop, in_place)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE, _("Paste")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE, _("Paste")); } } @@ -1235,7 +1234,7 @@ void sp_selection_paste_style(SPDesktop *desktop) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteStyle(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); } } @@ -1244,7 +1243,7 @@ void sp_selection_paste_livepatheffect(SPDesktop *desktop) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pastePathEffect(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, _("Paste live path effect")); } } @@ -1263,7 +1262,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) { if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1278,7 +1277,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, _("Remove live path effect")); } @@ -1286,7 +1285,7 @@ void sp_selection_remove_filter(SPDesktop *desktop) { if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1299,7 +1298,7 @@ void sp_selection_remove_filter(SPDesktop *desktop) sp_desktop_set_style(desktop, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_REMOVE_FILTER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_FILTER, _("Remove filter")); } @@ -1308,7 +1307,7 @@ void sp_selection_paste_size(SPDesktop *desktop, bool apply_x, bool apply_y) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteSize(desktop, false, apply_x, apply_y)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_SIZE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE, _("Paste size")); } } @@ -1317,14 +1316,14 @@ void sp_selection_paste_size_separately(SPDesktop *desktop, bool apply_x, bool a { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteSize(desktop, true, apply_x, apply_y)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, _("Paste size separately")); } } void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1343,9 +1342,9 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers GSList *copied; if (next) { - copied = sp_selection_paste_impl(sp_desktop_document(dt), next, &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), next, &temp_clip); } else { - copied = sp_selection_paste_impl(sp_desktop_document(dt), dt->currentLayer(), &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), &temp_clip); no_more = true; } selection->setReprList((GSList const *) copied); @@ -1353,7 +1352,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) if (temp_clip) g_slist_free(temp_clip); if (next) dt->setCurrentLayer(next); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO_NEXT, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_NEXT, _("Raise to next layer")); } } else { @@ -1369,7 +1368,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1388,9 +1387,9 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers GSList *copied; if (next) { - copied = sp_selection_paste_impl(sp_desktop_document(dt), next, &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), next, &temp_clip); } else { - copied = sp_selection_paste_impl(sp_desktop_document(dt), dt->currentLayer(), &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), &temp_clip); no_more = true; } selection->setReprList((GSList const *) copied); @@ -1398,7 +1397,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) if (temp_clip) g_slist_free(temp_clip); if (next) dt->setCurrentLayer(next); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO_PREV, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_PREV, _("Lower to previous layer")); } } else { @@ -1414,7 +1413,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1428,13 +1427,13 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) GSList *temp_clip = NULL; sp_selection_copy_impl(items, &temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs sp_selection_delete_impl(items, false, false); - GSList *copied = sp_selection_paste_impl(sp_desktop_document(dt), moveto, &temp_clip); + GSList *copied = sp_selection_paste_impl(dt->getDocument(), moveto, &temp_clip); selection->setReprList((GSList const *) copied); g_slist_free(copied); if (temp_clip) g_slist_free(temp_clip); if (moveto) dt->setCurrentLayer(moveto); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO, _("Move selection to layer")); } } @@ -1640,7 +1639,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), move, &move, compensate); } else if (prefs_unmoved) { - //if (SP_IS_USE(sp_use_get_original(SP_USE(item)))) + //if (dynamic_cast<SPUse *>(sp_use_get_original(dynamic_cast<SPUse *>(item)))) // clone_move = Geom::identity(); Geom::Affine move = result * clone_move; item->doWriteTransform(item->getRepr(), move, &t, compensate); @@ -1687,7 +1686,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *l = const_cast<GSList *>(selection->reprList()); while (l != NULL) { @@ -1695,7 +1694,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) l = l->next; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_OBJECT_FLATTEN, + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_FLATTEN, _("Remove transform")); } @@ -1785,7 +1784,7 @@ void sp_selection_move_relative(Inkscape::Selection *selection, double dx, doubl */ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) return; @@ -1801,7 +1800,7 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) } } - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), ccw ? SP_VERB_OBJECT_ROTATE_90_CCW : SP_VERB_OBJECT_ROTATE_90_CW, ccw ? _("Rotate 90\xc2\xb0 CCW") : _("Rotate 90\xc2\xb0 CW")); } @@ -1819,7 +1818,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) sp_selection_rotate_relative(selection, *center, angle_degrees); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( ( angle_degrees > 0 ) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -1853,7 +1852,7 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); GSList *all_matches = NULL; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); @@ -1906,7 +1905,7 @@ void sp_select_same_object_type(SPDesktop *desktop) GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); GSList *matches = all_list; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); @@ -1948,7 +1947,7 @@ void sp_select_same_stroke_style(SPDesktop *desktop) GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); GSList *matches = all_list; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); @@ -2111,7 +2110,7 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy SPStyle *sel_style_for_width = NULL; if (type == SP_STROKE_STYLE_WIDTH) { objects = g_slist_prepend(objects, sel); - sel_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); + sel_style_for_width = new SPStyle(SP_ACTIVE_DOCUMENT); objects_query_strokewidth (objects, sel_style_for_width); } @@ -2126,11 +2125,11 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy if (sel_style->stroke_width.set && iter_style->stroke_width.set) { GSList *objects = NULL; objects = g_slist_prepend(objects, iter); - SPStyle *iter_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); - objects_query_strokewidth (objects, iter_style_for_width); + SPStyle tmp_style(SP_ACTIVE_DOCUMENT); + objects_query_strokewidth (objects, &tmp_style); if (sel_style_for_width) { - match = (sel_style_for_width->stroke_width.computed == iter_style_for_width->stroke_width.computed); + match = (sel_style_for_width->stroke_width.computed == tmp_style.stroke_width.computed); } g_slist_free(objects); } @@ -2162,6 +2161,7 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy } } + if( sel_style_for_width != NULL ) delete sel_style_for_width; g_slist_free(objects); return matches; @@ -2206,7 +2206,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) sp_selection_rotate_relative(selection, *center, zangle); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (angle > 0) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -2236,7 +2236,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) double const times = 1.0 + grow / max_len; sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (grow > 0) ? "selector:scale:larger" : "selector:scale:smaller" ), @@ -2265,7 +2265,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) Geom::Point const center(sel_bbox->midpoint()); sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); } @@ -2377,7 +2377,7 @@ void sp_selection_item_next(SPDesktop *desktop) { g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs->getInt("/options/kbselection/inlayer", PREFS_SELECTION_LAYER); @@ -2404,10 +2404,10 @@ sp_selection_item_next(SPDesktop *desktop) void sp_selection_item_prev(SPDesktop *desktop) { - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); g_return_if_fail(document != NULL); g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); PrefsSelectionContext inlayer = (PrefsSelectionContext) prefs->getInt("/options/kbselection/inlayer", PREFS_SELECTION_LAYER); @@ -2435,7 +2435,7 @@ void sp_selection_next_patheffect_param(SPDesktop * dt) { if (!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); if ( selection && !selection->isEmpty() ) { SPItem *item = selection->singleItem(); if ( SPLPEItem *lpeitem = dynamic_cast<SPLPEItem*>(item) ) { @@ -2468,7 +2468,7 @@ void sp_selection_edit_clip_or_mask(SPDesktop * /*dt*/, bool /*clip*/) /*if (!dt) return; using namespace Inkscape::UI; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); if (!selection || selection->isEmpty()) return; GSList const *items = selection->itemList(); @@ -2608,7 +2608,7 @@ void sp_selection_clone(SPDesktop *desktop) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); @@ -2649,7 +2649,7 @@ void sp_selection_clone(SPDesktop *desktop) Inkscape::GC::release(clone); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE, C_("Action", "Clone")); selection->setReprList(newsel); @@ -2663,7 +2663,7 @@ sp_selection_relink(SPDesktop *desktop) if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to relink.")); @@ -2698,7 +2698,7 @@ sp_selection_relink(SPDesktop *desktop) if (!relinked) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to relink</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, _("Relink clone")); } } @@ -2710,7 +2710,7 @@ sp_selection_unlink(SPDesktop *desktop) if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink.")); @@ -2772,7 +2772,7 @@ sp_selection_unlink(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to unlink</b> in the selection.")); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, _("Unlink clone")); } @@ -2782,7 +2782,7 @@ sp_select_clone_original(SPDesktop *desktop) if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *item = selection->singleItem(); @@ -2857,7 +2857,7 @@ sp_select_clone_original(SPDesktop *desktop) curve->moveto(a->midpoint()); curve->lineto(b->midpoint()); - SPCanvasItem * canvasitem = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), curve); + SPCanvasItem * canvasitem = sp_canvas_bpath_new(desktop->getTempGroup(), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvasitem), 0x0000ddff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT, 5, 3); sp_canvas_item_show(canvasitem); curve->unref(); @@ -2881,17 +2881,19 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) if (desktop == NULL) { return; } - + + Inkscape::Selection *selection = desktop->getSelection(); + Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - for (const GSList * item = desktop->selection->itemList(); item != NULL; item = item->next) { + for (const GSList * item = selection->itemList(); item != NULL; item = item->next) { if (SP_IS_SHAPE(item->data) || SP_IS_TEXT(item->data)) { if (firstItem) { os << "|"; } else { firstItem = SP_ITEM(item->data); } - os << "#" << SP_ITEM(item->data)->getId() << ",0"; + os << '#' << SP_ITEM(item->data)->getId() << ",0"; } } if (firstItem) { @@ -2902,10 +2904,10 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::XML::Node *lpe_repr = xml_doc->createElement("inkscape:path-effect"); { lpe_repr->setAttribute("effect", "fill_between_many"); - lpe_repr->setAttribute("linkedpaths", os.str().c_str()); + lpe_repr->setAttribute("linkedpaths", os.str()); desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to <defs> and assigns the 'id' attribute } - const gchar * lpe_id = lpe_repr->attribute("id"); + std::string lpe_id_href = std::string("#") + lpe_repr->attribute("id"); Inkscape::GC::release(lpe_repr); // create the new path @@ -2917,13 +2919,15 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); SPLPEItem *clone_lpeitem = dynamic_cast<SPLPEItem *>(clone_obj); if (clone_lpeitem) { - gchar *href = g_strdup_printf("#%s", lpe_id); - clone_lpeitem->addPathEffect(href, false); - g_free(href); + clone_lpeitem->addPathEffect(lpe_id_href, false); } } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + // select the new object: + selection->set(clone); + + Inkscape::GC::release(clone); } else { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); } @@ -2936,10 +2940,10 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3037,8 +3041,8 @@ void sp_selection_to_guides(SPDesktop *desktop) if (desktop == NULL) return; - SPDocument *doc = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *doc = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); // we need to copy the list because it gets reset when objects are deleted GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList())); @@ -3095,10 +3099,10 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Check if something is selected. if (selection->isEmpty()) { @@ -3169,9 +3173,9 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) the_group->getAttribute("inkscape:transform-center-y")); the_group->setAttribute("style", NULL); - std::string id = symbol_repr->attribute("id"); + Glib::ustring id = symbol_repr->attribute("id"); id += "_transform"; - the_group->setAttribute("id", id.c_str()); + the_group->setAttribute("id", id); } @@ -3189,10 +3193,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) // Create <use> pointing to new symbol (to replace the moved objects). Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); - const gchar *symbol_id = symbol_repr->attribute("id"); - gchar *href_str = g_strdup_printf("#%s", symbol_id); - clone->setAttribute("xlink:href", href_str, false); - g_free(href_str); + clone->setAttribute("xlink:href", Glib::ustring("#")+symbol_repr->attribute("id"), false); the_parent_repr->appendChild(clone); @@ -3220,10 +3221,10 @@ void sp_selection_unsymbol(SPDesktop *desktop) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Check if something is selected. if (selection->isEmpty()) { @@ -3283,11 +3284,11 @@ void sp_selection_unsymbol(SPDesktop *desktop) // Need to delete <symbol>; all <use> elements that referenced <symbol> should // auto-magically reference <g> (if <symbol> deleted after setting <g> 'id'). Glib::ustring id = symbol->getAttribute("id"); - group->setAttribute("id",id.c_str()); + group->setAttribute("id", id); symbol->deleteObject(true); // Change selection to new <g> element. - SPItem *group_item = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(group)); + SPItem *group_item = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(group)); selection->set(group_item); // Clean up @@ -3305,10 +3306,10 @@ sp_selection_tile(SPDesktop *desktop, bool apply) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3400,7 +3401,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) // restore parent and position parent->getRepr()->appendChild(rect); rect->setPosition(pos > 0 ? pos : 0); - SPItem *rectangle = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(rect)); + SPItem *rectangle = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(rect)); Inkscape::GC::release(rect); @@ -3420,10 +3421,10 @@ void sp_selection_untile(SPDesktop *desktop) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3490,7 +3491,7 @@ void sp_selection_untile(SPDesktop *desktop) if (!did) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No pattern fills</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNTILE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNTILE, _("Pattern to objects")); selection->setList(new_select); } @@ -3575,10 +3576,10 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) return; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3625,7 +3626,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) directory = g_path_get_dirname( document->getURI() ); } if (directory == NULL) { - directory = homedir_path(NULL); + directory = INKSCAPE.homedir_path(NULL); } gchar *filepath = g_build_filename(directory, basename, NULL); g_free(directory); @@ -3661,7 +3662,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) if (hint_xdpi != 0) { res = hint_xdpi; } else { - // if all else fails, take the default 90 dpi + // if all else fails, take the default 96 dpi res = Inkscape::Util::Quantity::convert(1, "in", "px"); } } @@ -3709,7 +3710,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) double shift_x = bbox->min()[Geom::X]; double shift_y = bbox->max()[Geom::Y]; - if (res == Inkscape::Util::Quantity::convert(1, "in", "px")) { // for default 90 dpi, snap it to pixel grid + if (res == Inkscape::Util::Quantity::convert(1, "in", "px")) { // for default 96 dpi, snap it to pixel grid shift_x = round(shift_x); shift_y = -round(-shift_y); // this gets correct rounding despite coordinate inversion, remove the negations when the inversion is gone } @@ -3744,7 +3745,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) // TODO: avoid unnecessary roundtrip between data URI and decoded pixbuf Inkscape::XML::Node * repr = xml_doc->createElement("svg:image"); sp_embed_image(repr, pb); - if (res == Inkscape::Util::Quantity::convert(1, "in", "px")) { // for default 90 dpi, snap it to pixel grid + if (res == Inkscape::Util::Quantity::convert(1, "in", "px")) { // for default 96 dpi, snap it to pixel grid sp_repr_set_svg_double(repr, "width", width); sp_repr_set_svg_double(repr, "height", height); } else { @@ -3793,10 +3794,10 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) if (desktop == NULL) { return; } - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to create clippath or mask from.")); return; @@ -3909,10 +3910,10 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected bool is_empty = selection->isEmpty(); @@ -4081,9 +4082,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ Inkscape::GC::release(group); } - gchar *value_str = g_strdup_printf("url(#%s)", mask_id); - apply_mask_to->setAttribute(attributeName, value_str); - g_free(value_str); + apply_mask_to->setAttribute(attributeName, Glib::ustring("url(#") + mask_id + ')'); } @@ -4114,9 +4113,9 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -4183,7 +4182,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc); - if(copy->attribute("inkscape:original-d")) + if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { copy->setAttribute("d", copy->attribute("inkscape:original-d")); } @@ -4207,7 +4206,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { parent->appendChild(repr); repr->setPosition((pos + 1) > 0 ? (pos + 1) : 0); - SPItem *mask_item = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *mask_item = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); items_to_select = g_slist_prepend(items_to_select, mask_item); // transform mask, so it is moved the same spot where mask was applied @@ -4255,7 +4254,7 @@ bool fit_canvas_to_selection(SPDesktop *desktop, bool with_margins) { g_return_val_if_fail(desktop != NULL, false); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_return_val_if_fail(doc != NULL, false); g_return_val_if_fail(desktop->selection != NULL, false); @@ -4280,7 +4279,7 @@ void verb_fit_canvas_to_selection(SPDesktop *const desktop) { if (fit_canvas_to_selection(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION, + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION, _("Fit Page to Selection")); } } @@ -4308,8 +4307,8 @@ fit_canvas_to_drawing(SPDocument *doc, bool with_margins) void verb_fit_canvas_to_drawing(SPDesktop *desktop) { - if (fit_canvas_to_drawing(sp_desktop_document(desktop))) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_DRAWING, + if (fit_canvas_to_drawing(desktop->getDocument())) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_DRAWING, _("Fit Page to Drawing")); } } @@ -4321,7 +4320,7 @@ verb_fit_canvas_to_drawing(SPDesktop *desktop) */ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { g_return_if_fail(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_return_if_fail(doc != NULL); g_return_if_fail(desktop->selection != NULL); @@ -4330,7 +4329,7 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { ? fit_canvas_to_drawing(doc, true) : fit_canvas_to_selection(desktop, true) ); if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, _("Fit Page to Selection or Drawing")); } }; diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 1cb96fed0..f7814fd57 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -5,6 +5,7 @@ * MenTaLguY <mental@rydia.net> * bulia byak <buliabyak@users.sf.net> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2004-2006 Authors * @@ -46,11 +47,14 @@ char* collect_terms (GSList *items) bool first = true; for (GSList *i = (GSList *)items; i != NULL; i = i->next) { - const char *term = SP_ITEM(i->data)->displayName(); - if (term != NULL && g_slist_find (check, term) == NULL) { - check = g_slist_prepend (check, (void *) term); - ss << (first ? "" : ", ") << "<b>" << term << "</b>"; - first = false; + SPItem *item = dynamic_cast<SPItem *>(reinterpret_cast<SPObject *>(i->data)); + if (item) { + const char *term = item->displayName(); + if (term != NULL && g_slist_find (check, term) == NULL) { + check = g_slist_prepend (check, (void *) term); + ss << (first ? "" : ", ") << "<b>" << term << "</b>"; + first = false; + } } } return g_strdup(ss.str().c_str()); @@ -62,10 +66,13 @@ static int count_terms (GSList *items) GSList *check = NULL; int count=0; for (GSList *i = (GSList *)items; i != NULL; i = i->next) { - const char *term = SP_ITEM(i->data)->displayName(); - if (term != NULL && g_slist_find (check, term) == NULL) { - check = g_slist_prepend (check, (void *) term); - count++; + SPItem *item = dynamic_cast<SPItem *>(reinterpret_cast<SPObject *>(i->data)); + if (item) { + const char *term = item->displayName(); + if (term != NULL && g_slist_find (check, term) == NULL) { + check = g_slist_prepend (check, (void *) term); + count++; + } } } return count; @@ -76,8 +83,10 @@ static int count_filtered (GSList *items) { int count=0; for (GSList *i = items; i != NULL; i = i->next) { - SPItem *item = SP_ITEM(i->data); - count += item->isFiltered(); + SPItem *item = dynamic_cast<SPItem *>(reinterpret_cast<SPObject *>((i->data))); + if (item) { + count += item->isFiltered(); + } } return count; } @@ -118,7 +127,8 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select if (!items) { // no items _context.set(Inkscape::NORMAL_MESSAGE, _when_nothing); } else { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast<SPItem *>(reinterpret_cast<SPObject *>(items->data)); + g_assert(item != NULL); SPObject *layer = selection->layers()->layerForObject(item); SPObject *root = selection->layers()->currentRoot(); @@ -181,30 +191,41 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select if (!items->next) { // one item char *item_desc = item->detailedDescription(); - if (SP_IS_USE(item) && SP_IS_SYMBOL(item->firstChild())) { + bool isUse = dynamic_cast<SPUse *>(item) != NULL; + if (isUse && dynamic_cast<SPSymbol *>(item->firstChild())) { _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", item_desc, in_phrase, _("Convert symbol to group to edit"), _when_selected); - } else if (SP_IS_SYMBOL(item)) { + } else if (dynamic_cast<SPSymbol *>(item)) { _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s.", item_desc, in_phrase, _("Remove from symbols tray to edit symbol")); - } else if (SP_IS_USE(item) || (SP_IS_OFFSET(item) && SP_OFFSET(item)->sourceHref)) { - _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", - item_desc, in_phrase, - _("Use <b>Shift+D</b> to look up original"), _when_selected); - } else if (SP_IS_TEXT_TEXTPATH(item)) { - _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", - item_desc, in_phrase, - _("Use <b>Shift+D</b> to look up path"), _when_selected); - } else if (SP_IS_FLOWTEXT(item) && !SP_FLOWTEXT(item)->has_internal_frame()) { - _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", - item_desc, in_phrase, - _("Use <b>Shift+D</b> to look up frame"), _when_selected); } else { - _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s.", - item_desc, in_phrase, _when_selected); + SPOffset *offset = (isUse) ? NULL : dynamic_cast<SPOffset *>(item); + if (isUse || (offset && offset->sourceHref)) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, in_phrase, + _("Use <b>Shift+D</b> to look up original"), _when_selected); + } else { + SPText *text = dynamic_cast<SPText *>(item); + if (text && text->firstChild() && dynamic_cast<SPText *>(text->firstChild())) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, in_phrase, + _("Use <b>Shift+D</b> to look up path"), _when_selected); + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(item); + if (flowtext && !flowtext->has_internal_frame()) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, in_phrase, + _("Use <b>Shift+D</b> to look up frame"), _when_selected); + } else { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s.", + item_desc, in_phrase, _when_selected); + } + } + } } + g_free(item_desc); } else { // multiple items int objcount = g_slist_length((GSList *)items); diff --git a/src/selection.cpp b/src/selection.cpp index 17b7253f2..81139d044 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -20,7 +20,7 @@ # include <config.h> #endif #include "macros.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "document.h" #include "layer-model.h" #include "selection.h" @@ -89,7 +89,7 @@ Selection::_emit_modified(Selection *selection) } void Selection::_emitModified(guint flags) { - inkscape_selection_modified(this, flags); + INKSCAPE.selection_modified(this, flags); _modified_signal.emit(this, flags); } @@ -104,7 +104,7 @@ void Selection::_emitChanged(bool persist_selection_context/* = false */) { _releaseContext(_selection_context); } - inkscape_selection_changed(this); + INKSCAPE.selection_changed(this); _changed_signal.emit(this); } diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 96c7fb49b..5e4c0642e 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -26,7 +26,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "knot.h" #include "message-stack.h" @@ -131,9 +131,9 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : _makeHandles(); _updateHandles(); - _selection = sp_desktop_selection(desktop); + _selection = desktop->getSelection(); - _norm = sp_canvas_item_new(sp_desktop_controls(desktop), + _norm = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "mode", SP_CTRL_MODE_COLOR, @@ -146,7 +146,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : "pixbuf", handles[12], NULL); - _grip = sp_canvas_item_new(sp_desktop_controls(desktop), + _grip = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "mode", SP_CTRL_MODE_XOR, @@ -163,7 +163,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : sp_canvas_item_hide(_norm); for (int i = 0; i < 4; i++) { - _l[i] = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop)); + _l[i] = ControlManager::getManager().createControlLine(desktop->getControls()); sp_canvas_item_hide(_l[i]); } @@ -252,7 +252,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s { // While dragging a handle, we will either scale, skew, or rotate and the "translating" parameter will be false // When dragging the selected item itself however, we will translate the selection and that parameter will be true - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); g_return_if_fail(!_grabbed); @@ -418,7 +418,7 @@ void Inkscape::SelTrans::ungrab() _desktop->snapindicator->remove_snapsource(); - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); _updateVolatileState(); for (unsigned i = 0; i < _items.size(); i++) { @@ -473,16 +473,16 @@ void Inkscape::SelTrans::ungrab() // when trying to stretch a perfectly vertical line in horizontal direction, which will not be allowed // by the handles; this would be identified as a (zero) translation by isTranslation() if (_current_relative_affine.isTranslation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Move")); } else if (_current_relative_affine.withoutTranslation().isScale()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale")); } else if (_current_relative_affine.withoutTranslation().isRotation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Rotate")); } else { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Skew")); } } @@ -495,7 +495,7 @@ void Inkscape::SelTrans::ungrab() SPItem *it = SP_ITEM(l->data); it->updateRepr(); } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Set center")); } @@ -512,7 +512,7 @@ void Inkscape::SelTrans::ungrab() void Inkscape::SelTrans::stamp() { - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); bool fixup = !_grabbed; if ( fixup && _stamp_cache ) { @@ -549,7 +549,7 @@ void Inkscape::SelTrans::stamp() // move to the saved position copy_repr->setPosition(pos > 0 ? pos : 0); - SPItem *copy_item = (SPItem *) sp_desktop_document(_desktop)->getObjectByRepr(copy_repr); + SPItem *copy_item = (SPItem *) _desktop->getDocument()->getObjectByRepr(copy_repr); Geom::Affine const *new_affine; if (_show == SHOW_OUTLINE) { @@ -570,7 +570,7 @@ void Inkscape::SelTrans::stamp() Inkscape::GC::release(copy_repr); l = l->next; } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Stamp")); } @@ -606,7 +606,7 @@ void Inkscape::SelTrans::_updateHandles() void Inkscape::SelTrans::_updateVolatileState() { - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); _empty = selection->isEmpty(); if (_empty) { @@ -719,7 +719,7 @@ void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHa _center_is_set = false; // center has changed _updateHandles(); } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Reset center")); } break; @@ -1306,8 +1306,8 @@ gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state) // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(pt[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(pt[Geom::Y], "px"); - GString *xs = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); _message_context.setF(Inkscape::NORMAL_MESSAGE, _("Move <b>center</b> to %s, %s"), xs->str, ys->str); g_string_free(xs, FALSE); g_string_free(ys, FALSE); @@ -1460,8 +1460,8 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dxy[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dxy[Geom::Y], "px"); - GString *xs = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); _message_context.setF(Inkscape::NORMAL_MESSAGE, _("<b>Move</b> by %s, %s; with <b>Ctrl</b> to restrict to horizontal/vertical; with <b>Shift</b> to disable snapping"), xs->str, ys->str); g_string_free(xs, TRUE); g_string_free(ys, TRUE); diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index 1e43c98c6..e72c16de0 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -211,7 +211,7 @@ Inkscape::XML::Document *sp_shortcut_create_template_file(char const *filename) void sp_shortcut_get_file_names(std::vector<Glib::ustring> *names, std::vector<Glib::ustring> *paths) { std::list<gchar *> sources; - sources.push_back( profile_path("keys") ); + sources.push_back( Inkscape::Application::profile_path("keys") ); sources.push_back( g_strdup(INKSCAPE_KEYSDIR) ); // loop through possible keyboard shortcut file locations. @@ -229,7 +229,7 @@ void sp_shortcut_get_file_names(std::vector<Glib::ustring> *names, std::vector<G gchar *filename = 0; while ((filename = (gchar *) g_dir_read_name(directory)) != NULL) { gchar* lower = g_ascii_strdown(filename, -1); - if (!strcmp(dirname, profile_path("keys")) && + if (!strcmp(dirname, Inkscape::Application::profile_path("keys")) && !strcmp(lower, "default.xml")) { // Dont add the users custom keys file continue; diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 8e2e7d7a6..5065f25c3 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -103,7 +103,7 @@ void SPClipPath::set(unsigned int key, const gchar* value) { break; default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + this->style->readFromObject( this ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObjectGroup::set(key, value); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index b5c6e4af8..a74d4687d 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -604,7 +604,7 @@ void SPGenericEllipse::update_patheffect(bool write) if (write) { Inkscape::XML::Node *repr = this->getRepr(); - if (this->_curve != NULL) { + if (this->_curve != NULL && type == SP_GENERIC_ELLIPSE_ARC) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); g_free(str); @@ -642,8 +642,8 @@ bool SPGenericEllipse::set_elliptical_path_attribute(Inkscape::XML::Node *repr) // Make sure our pathvector is up to date. this->set_shape(); - if (this->getCurve() != NULL) { - gchar* d = sp_svg_write_path(this->getCurve()->get_pathvector()); + if (_curve != NULL) { + gchar* d = sp_svg_write_path(_curve->get_pathvector()); repr->setAttribute("d", d); diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 9a184952c..9cb33a6f3 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -465,6 +465,10 @@ int sp_filter_set_image_name(SPFilter *filter, gchar const *name) { pair<gchar*,int> new_pair(name_copy, value); pair<map<gchar*,int,ltstr>::iterator,bool> ret = filter->_image_name->insert(new_pair); if (ret.second == false) { + // The element is not inserted (because an element with the same key was already in the map) + // Therefore, free the memory allocated for the new entry: + free(name_copy); + return (*ret.first).second; } return value; diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 32d3b0f60..580945d74 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -85,12 +85,14 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { l = g_slist_reverse(l); while (l) { - SPObject *child = SP_OBJECT(l->data); + SPObject *child = reinterpret_cast<SPObject *>(l->data); + g_assert(child != NULL); l = g_slist_remove(l, child); + SPItem *item = dynamic_cast<SPItem *>(child); if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM (child)) { - SPItem const &chi = *SP_ITEM(child); + if (item) { + SPItem const &chi = *item; cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; child->updateDisplay((SPCtx *)&cctx, childflags); @@ -138,7 +140,8 @@ void SPFlowregion::modified(guint flags) { l = g_slist_reverse(l); while (l) { - SPObject *child = SP_OBJECT(l->data); + SPObject *child = reinterpret_cast<SPObject *>(l->data); + g_assert(child != NULL); l = g_slist_remove(l, child); if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { @@ -157,7 +160,7 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc GSList *l = NULL; for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { + if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); if (crepr) { @@ -174,7 +177,7 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc } else { for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - if ( !SP_IS_TITLE(child) && !SP_IS_DESC(child) ) { + if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { child->updateRepr(flags); } } @@ -240,12 +243,14 @@ void SPFlowregionExclude::update(SPCtx *ctx, unsigned int flags) { l = g_slist_reverse (l); while (l) { - SPObject *child = SP_OBJECT(l->data); + SPObject *child = reinterpret_cast<SPObject *>(l->data); + g_assert(child != NULL); l = g_slist_remove(l, child); if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM (child)) { - SPItem const &chi = *SP_ITEM(child); + SPItem *item = dynamic_cast<SPItem *>(child); + if (item) { + SPItem const &chi = *item; cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; child->updateDisplay((SPCtx *)&cctx, flags); @@ -290,7 +295,8 @@ void SPFlowregionExclude::modified(guint flags) { l = g_slist_reverse (l); while (l) { - SPObject *child = SP_OBJECT(l->data); + SPObject *child = reinterpret_cast<SPObject *>(l->data); + g_assert(child != NULL); l = g_slist_remove(l, child); if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { @@ -363,20 +369,28 @@ static void GetDest(SPObject* child,Shape **computed) SPCurve *curve=NULL; Geom::Affine tr_mat; - SPObject* u_child=child; - if ( SP_IS_USE(u_child) ) { - u_child=SP_USE(u_child)->child; - tr_mat = SP_ITEM(u_child)->getRelativeTransform(child->parent); - } else { - tr_mat = SP_ITEM(u_child)->transform; - } - if ( SP_IS_SHAPE (u_child) ) { - if (!(SP_SHAPE(u_child)->_curve)) - SP_SHAPE (u_child)->set_shape (); - curve = SP_SHAPE (u_child)->getCurve (); - } else if ( SP_IS_TEXT (u_child) ) { - curve = SP_TEXT (u_child)->getNormalizedBpath (); - } + SPObject* u_child = child; + SPItem *item = dynamic_cast<SPItem *>(u_child); + g_assert(item != NULL); + SPUse *use = dynamic_cast<SPUse *>(item); + if ( use ) { + u_child = use->child; + tr_mat = use->getRelativeTransform(child->parent); + } else { + tr_mat = item->transform; + } + SPShape *shape = dynamic_cast<SPShape *>(u_child); + if ( shape ) { + if (!(shape->_curve)) { + shape->set_shape(); + } + curve = shape->getCurve(); + } else { + SPText *text = dynamic_cast<SPText *>(u_child); + if ( text ) { + curve = text->getNormalizedBpath(); + } + } if ( curve ) { Path* temp=new Path; diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 72fe86daf..6d2385aff 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -14,7 +14,7 @@ #include "inkscape.h" #include "document.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop.h" #include "xml/repr.h" @@ -86,12 +86,14 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { l = g_slist_reverse(l); while (l) { - SPObject *child = SP_OBJECT(l->data); + SPObject *child = reinterpret_cast<SPObject *>(l->data); + g_assert(child != NULL); l = g_slist_remove(l, child); if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM(child)) { - SPItem const &chi = *SP_ITEM(child); + SPItem *item = dynamic_cast<SPItem *>(child); + if (item) { + SPItem const &chi = *item; cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; child->updateDisplay((SPCtx *)&cctx, childflags); @@ -129,19 +131,18 @@ void SPFlowtext::modified(unsigned int flags) { // FIXME: the below stanza is copied over from sp_text_modified, consider factoring it out if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) { - SPFlowtext *text = SP_FLOWTEXT(this); - Geom::OptRect pbox = text->geometricBounds(); + Geom::OptRect pbox = geometricBounds(); - for (SPItemView* v = text->display; v != NULL; v = v->next) { + for (SPItemView* v = display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - text->_clearFlow(g); - g->setStyle(this->style); - text->layout.show(g, pbox); + _clearFlow(g); + g->setStyle(style); + layout.show(g, pbox); } } for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { - if (SP_IS_FLOWREGION(o)) { + if (dynamic_cast<SPFlowregion *>(o)) { region = o; break; } @@ -231,7 +232,7 @@ Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::X for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { Inkscape::XML::Node *c_repr = NULL; - if ( SP_IS_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child)) { + if ( dynamic_cast<SPFlowdiv *>(child) || dynamic_cast<SPFlowpara *>(child) || dynamic_cast<SPFlowregion *>(child) || dynamic_cast<SPFlowregionExclude *>(child)) { c_repr = child->updateRepr(doc, NULL, flags); } @@ -247,7 +248,7 @@ Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::X } } else { for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child) ) { + if ( dynamic_cast<SPFlowdiv *>(child) || dynamic_cast<SPFlowpara *>(child) || dynamic_cast<SPFlowregion *>(child) || dynamic_cast<SPFlowregionExclude *>(child)) { child->updateRepr(flags); } } @@ -285,7 +286,7 @@ void SPFlowtext::print(SPPrintContext *ctx) { } const char* SPFlowtext::displayName() const { - if (SP_FLOWTEXT(this)->has_internal_frame()) { + if (has_internal_frame()) { return _("Flowed Text"); } else { return _("Linked Flowed Text"); @@ -293,7 +294,6 @@ const char* SPFlowtext::displayName() const { } gchar* SPFlowtext::description() const { - Inkscape::Text::Layout const &layout = SP_FLOWTEXT(this)->layout; int const nChars = layout.iteratorToCharIndex(layout.end()); char const *trunc = (layout.inputTruncated()) ? _(" [truncated]") : ""; @@ -346,12 +346,17 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, Inkscape::Text::Layout::OptionalTextTagAttrs pi; bool with_indent = false; - if (SP_IS_FLOWPARA(root)) { + if (dynamic_cast<SPFlowpara *>(root)) { // emulate par-indent with the first char's kern SPObject *t = root; - for ( ; t != NULL && !SP_IS_FLOWTEXT(t); t = t->parent){}; - if (SP_IS_FLOWTEXT(t)) { - double indent = SP_FLOWTEXT(t)->par_indent; + SPFlowtext *ft = NULL; + while (t && !ft) { + ft = dynamic_cast<SPFlowtext *>(t); + t = t->parent; + } + + if (ft) { + double indent = ft->par_indent; if (indent != 0) { with_indent = true; SVGLength sl; @@ -363,7 +368,7 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, } if (*pending_line_break_object) { - if (SP_IS_FLOWREGIONBREAK(*pending_line_break_object)) { + if (dynamic_cast<SPFlowregionbreak *>(*pending_line_break_object)) { layout.appendControlCode(Inkscape::Text::Layout::SHAPE_BREAK, *pending_line_break_object); } else { layout.appendControlCode(Inkscape::Text::Layout::PARAGRAPH_BREAK, *pending_line_break_object); @@ -372,9 +377,10 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, } for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_STRING(child)) { + SPString *str = dynamic_cast<SPString *>(child); + if (str) { if (*pending_line_break_object) { - if (SP_IS_FLOWREGIONBREAK(*pending_line_break_object)) + if (dynamic_cast<SPFlowregionbreak *>(*pending_line_break_object)) layout.appendControlCode(Inkscape::Text::Layout::SHAPE_BREAK, *pending_line_break_object); else { layout.appendControlCode(Inkscape::Text::Layout::PARAGRAPH_BREAK, *pending_line_break_object); @@ -382,31 +388,35 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, *pending_line_break_object = NULL; } if (with_indent) { - layout.appendText(SP_STRING(child)->string, root->style, child, &pi); + layout.appendText(str->string, root->style, child, &pi); } else { - layout.appendText(SP_STRING(child)->string, root->style, child); + layout.appendText(str->string, root->style, child); } - } else if (SP_IS_FLOWREGION(child)) { - std::vector<Shape*> const &computed = SP_FLOWREGION(child)->computed; - for (std::vector<Shape*>::const_iterator it = computed.begin() ; it != computed.end() ; ++it) { - shapes->push_back(Shape()); - if (exclusion_shape->hasEdges()) { - shapes->back().Booleen(*it, const_cast<Shape*>(exclusion_shape), bool_op_diff); - } else { - shapes->back().Copy(*it); + } else { + SPFlowregion *region = dynamic_cast<SPFlowregion *>(child); + if (region) { + std::vector<Shape*> const &computed = region->computed; + for (std::vector<Shape*>::const_iterator it = computed.begin() ; it != computed.end() ; ++it) { + shapes->push_back(Shape()); + if (exclusion_shape->hasEdges()) { + shapes->back().Booleen(*it, const_cast<Shape*>(exclusion_shape), bool_op_diff); + } else { + shapes->back().Copy(*it); + } + layout.appendWrapShape(&shapes->back()); } - layout.appendWrapShape(&shapes->back()); } - } - //XML Tree is being directly used while it shouldn't be. - else if (!SP_IS_FLOWREGIONEXCLUDE(child) && !sp_repr_is_meta_element(child->getRepr())) { - _buildLayoutInput(child, exclusion_shape, shapes, pending_line_break_object); + //Xml Tree is being directly used while it shouldn't be. + else if (!dynamic_cast<SPFlowregionExclude *>(child) && !sp_repr_is_meta_element(child->getRepr())) { + _buildLayoutInput(child, exclusion_shape, shapes, pending_line_break_object); + } } } - if (SP_IS_FLOWDIV(root) || SP_IS_FLOWPARA(root) || SP_IS_FLOWREGIONBREAK(root) || SP_IS_FLOWLINE(root)) { - if (!root->hasChildren()) + if (dynamic_cast<SPFlowdiv *>(root) || dynamic_cast<SPFlowpara *>(root) || dynamic_cast<SPFlowregionbreak *>(root) || dynamic_cast<SPFlowline *>(root)) { + if (!root->hasChildren()) { layout.appendText("", root->style, root); + } *pending_line_break_object = root; } } @@ -418,16 +428,13 @@ Shape* SPFlowtext::_buildExclusionShape() const for (SPObject *child = children ; child ; child = child->getNext() ) { // RH: is it right that this shouldn't be recursive? - if ( SP_IS_FLOWREGIONEXCLUDE(child) ) { - SPFlowregionExclude *c_child = SP_FLOWREGIONEXCLUDE(child); - - if ( c_child->computed && c_child->computed->hasEdges() ) { - if (shape->hasEdges()) { - shape_temp->Booleen(shape, c_child->computed, bool_op_union); - std::swap(shape, shape_temp); - } else { - shape->Copy(c_child->computed); - } + SPFlowregionExclude *c_child = dynamic_cast<SPFlowregionExclude *>(child); + if ( c_child && c_child->computed && c_child->computed->hasEdges() ) { + if (shape->hasEdges()) { + shape_temp->Booleen(shape, c_child->computed, bool_op_union); + std::swap(shape, shape_temp); + } else { + shape->Copy(c_child->computed); } } } @@ -514,24 +521,23 @@ Inkscape::XML::Node *SPFlowtext::getAsText() sp_repr_set_svg_double(line_tspan, "y", anchor_point[Geom::Y]); } - SPObject *source_obj = 0; void *rawptr = 0; Glib::ustring::iterator span_text_start_iter; this->layout.getSourceOfCharacter(it, &rawptr, &span_text_start_iter); - source_obj = SP_OBJECT (rawptr); - gchar *style_text = sp_style_write_difference((SP_IS_STRING(source_obj) ? source_obj->parent : source_obj)->style, this->style); - if (style_text && *style_text) { - span_tspan->setAttribute("style", style_text); - g_free(style_text); + SPObject *source_obj = reinterpret_cast<SPObject *>(rawptr); + + Glib::ustring style_text = (dynamic_cast<SPString *>(source_obj) ? source_obj->parent : source_obj)->style->write( SP_STYLE_FLAG_IFDIFF, this->style); + if (!style_text.empty()) { + span_tspan->setAttribute("style", style_text.c_str()); } - if (SP_IS_STRING(source_obj)) { - Glib::ustring *string = &SP_STRING(source_obj)->string; - SPObject *span_end_obj = 0; + SPString *str = dynamic_cast<SPString *>(source_obj); + if (str) { + Glib::ustring *string = &(str->string); // TODO fixme: dangerous, unsafe premature-optimization void *rawptr = 0; Glib::ustring::iterator span_text_end_iter; this->layout.getSourceOfCharacter(it_span_end, &rawptr, &span_text_end_iter); - span_end_obj = SP_OBJECT(rawptr); + SPObject *span_end_obj = reinterpret_cast<SPObject *>(rawptr); if (span_end_obj != source_obj) { if (it_span_end == this->layout.end()) { span_text_end_iter = span_text_start_iter; @@ -562,13 +568,19 @@ Inkscape::XML::Node *SPFlowtext::getAsText() return repr; } -SPItem *SPFlowtext::get_frame(SPItem *after) +SPItem const *SPFlowtext::get_frame(SPItem const *after) const +{ + SPItem *item = const_cast<SPFlowtext *>(this)->get_frame(after); + return item; +} + +SPItem *SPFlowtext::get_frame(SPItem const *after) { SPItem *frame = 0; SPObject *region = 0; for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - if (SP_IS_FLOWREGION(o)) { + if (dynamic_cast<SPFlowregion *>(o)) { region = o; break; } @@ -578,52 +590,56 @@ SPItem *SPFlowtext::get_frame(SPItem *after) bool past = false; for (SPObject *o = region->firstChild() ; o ; o = o->getNext() ) { - if (SP_IS_ITEM(o)) { + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { if ( (after == NULL) || past ) { - frame = SP_ITEM(o); + frame = item; } else { - if (SP_ITEM(o) == after) { + if (item == after) { past = true; } } } } - if ( frame && SP_IS_USE(frame) ) { - frame = SP_USE(frame)->get_original(); + SPUse *use = dynamic_cast<SPUse *>(frame); + if ( use ) { + frame = use->get_original(); } } return frame; } -bool SPFlowtext::has_internal_frame() +bool SPFlowtext::has_internal_frame() const { - SPItem *frame = get_frame(NULL); + SPItem const *frame = get_frame(NULL); - return (frame && this->isAncestorOf(frame) && SP_IS_RECT(frame)); + return (frame && isAncestorOf(frame) && dynamic_cast<SPRect const *>(frame)); } SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0, Geom::Point p1) { - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *root_repr = xml_doc->createElement("svg:flowRoot"); root_repr->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create - SPItem *ft_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(root_repr)); + SPItem *ft_item = dynamic_cast<SPItem *>(desktop->currentLayer()->appendChildRepr(root_repr)); + g_assert(ft_item != NULL); SPObject *root_object = doc->getObjectByRepr(root_repr); - g_assert(SP_IS_FLOWTEXT(root_object)); + g_assert(dynamic_cast<SPFlowtext *>(root_object) != NULL); Inkscape::XML::Node *region_repr = xml_doc->createElement("svg:flowRegion"); root_repr->appendChild(region_repr); SPObject *region_object = doc->getObjectByRepr(region_repr); - g_assert(SP_IS_FLOWREGION(region_object)); + g_assert(dynamic_cast<SPFlowregion *>(region_object) != NULL); Inkscape::XML::Node *rect_repr = xml_doc->createElement("svg:rect"); // FIXME: use path!!! after rects are converted to use path region_repr->appendChild(rect_repr); - SPRect *rect = SP_RECT(doc->getObjectByRepr(rect_repr)); + SPRect *rect = dynamic_cast<SPRect *>(doc->getObjectByRepr(rect_repr)); + g_assert(rect != NULL); p0 *= desktop->dt2doc(); p1 *= desktop->dt2doc(); @@ -642,7 +658,7 @@ SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0, Inkscape::XML::Node *para_repr = xml_doc->createElement("svg:flowPara"); root_repr->appendChild(para_repr); SPObject *para_object = doc->getObjectByRepr(para_repr); - g_assert(SP_IS_FLOWPARA(para_object)); + g_assert(dynamic_cast<SPFlowpara *>(para_object) != NULL); Inkscape::XML::Node *text = xml_doc->createTextNode(""); para_repr->appendChild(text); @@ -652,7 +668,10 @@ SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0, Inkscape::GC::release(para_repr); Inkscape::GC::release(rect_repr); - ft_item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + + SPItem *item = dynamic_cast<SPItem *>(desktop->currentLayer()); + g_assert(item != NULL); + ft_item->transform = item->i2doc_affine().inverse(); return ft_item; } @@ -675,14 +694,14 @@ Geom::Affine SPFlowtext::set_transform (Geom::Affine const &xform) SPObject *region = NULL; for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { - if (SP_IS_FLOWREGION(o)) { + if (dynamic_cast<SPFlowregion *>(o)) { region = o; break; } } if (region) { - if (SP_IS_RECT(region->firstChild())) { - SPRect *rect = SP_RECT(region->firstChild()); + SPRect *rect = dynamic_cast<SPRect *>(region->firstChild()); + if (rect) { rect->set_i2d_affine(xform * rect->i2dt_affine()); rect->doWriteTransform(rect->getRepr(), rect->transform, NULL, true); } diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h index 743d55030..9e6046469 100644 --- a/src/sp-flowtext.h +++ b/src/sp-flowtext.h @@ -31,9 +31,13 @@ public: but losing the automatic wrapping ability. */ Inkscape::XML::Node *getAsText(); - SPItem *get_frame(SPItem *after); + // TODO check if these should return SPRect instead of SPItem - bool has_internal_frame(); + SPItem *get_frame(SPItem const *after); + + SPItem const *get_frame(SPItem const *after) const; + + bool has_internal_frame() const; //semiprivate: (need to be accessed by the C-style functions still) Inkscape::Text::Layout layout; diff --git a/src/sp-gradient.h b/src/sp-gradient.h index fbb48df62..f80d806fc 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -141,7 +141,8 @@ public: /** Composed array (for mesh gradients) */ SPMeshNodeArray array; - + SPMeshNodeArray array_smoothed; // Smoothed version of array + bool hasPatches() const; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 581c8a440..08b055508 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -22,7 +22,7 @@ #include <algorithm> #include <cstring> #include <string> -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/guideline.h" #include "svg/svg.h" @@ -37,6 +37,7 @@ #include <remove-last.h> #include "inkscape.h" #include "desktop.h" +#include "sp-root.h" #include "sp-namedview.h" #include <2geom/angle.h> #include "document.h" @@ -152,6 +153,19 @@ void SPGuide::set(unsigned int key, const gchar *value) { success += sp_svg_number_read_d(strarray[1], &newy); g_strfreev (strarray); if (success == 2) { + // If root viewBox set, interpret guides in terms of viewBox (90/96) + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + if(Geom::are_near((root->width.computed * root->viewBox.height()) / (root->viewBox.width() * root->height.computed), 1.0, Geom::EPSILON)) { + // for uniform scaling, try to reduce numerical error + double vbunit2px = (root->width.computed / root->viewBox.width() + root->height.computed / root->viewBox.height())/2.0; + newx = newx * vbunit2px; + newy = newy * vbunit2px; + } else { + newx = newx * root->width.computed / root->viewBox.width(); + newy = newy * root->height.computed / root->viewBox.height(); + } + } this->point_on_line = Geom::Point(newx, newy); } else if (success == 1) { // before 0.46 style guideline definition. @@ -185,7 +199,24 @@ SPGuide *SPGuide::createSPGuide(SPDocument *doc, Geom::Point const &pt1, Geom::P Geom::Point n = Geom::rot90(pt2 - pt1); - sp_repr_set_point(repr, "position", pt1); + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = pt1.x(); + double newy = pt1.y(); + + SPRoot *root = doc->getRoot(); + if( root->viewBox_set ) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + double px2vbunit = (root->viewBox.width()/root->width.computed + root->viewBox.height()/root->height.computed)/2.0; + newx = newx * px2vbunit; + newy = newy * px2vbunit; + } else { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + } + + sp_repr_set_point(repr, "position", Geom::Point( newx, newy )); sp_repr_set_point(repr, "orientation", n); SPNamedView *namedview = sp_document_namedview(doc, NULL); @@ -207,7 +238,7 @@ void sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list<std::pair<Geom::Poin void sp_guide_create_guides_around_page(SPDesktop *dt) { - SPDocument *doc=sp_desktop_document(dt); + SPDocument *doc=dt->getDocument(); std::list<std::pair<Geom::Point, Geom::Point> > pts; Geom::Point A(0, 0); @@ -227,7 +258,7 @@ void sp_guide_create_guides_around_page(SPDesktop *dt) void sp_guide_delete_all_guides(SPDesktop *dt) { - SPDocument *doc=sp_desktop_document(dt); + SPDocument *doc=dt->getDocument(); const GSList *current; while ( (current = doc->getResourceList("guide")) ) { SPGuide* guide = SP_GUIDE(current->data); @@ -318,8 +349,25 @@ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) /* Calling sp_repr_set_point must precede calling sp_item_notify_moveto in the commit case, so that the guide's new position is available for sp_item_rm_unsatisfied_cns. */ if (commit) { + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = point_on_line.x(); + double newy = point_on_line.y(); + + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + double px2vbunit = (root->viewBox.width()/root->width.computed + root->viewBox.height()/root->height.computed)/2.0; + newx = newx * px2vbunit; + newy = newy * px2vbunit; + } else { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + } + //XML Tree being used here directly while it shouldn't be. - sp_repr_set_point(getRepr(), "position", point_on_line); + sp_repr_set_point(getRepr(), "position", Geom::Point(newx, newy) ); } /* DISABLED CODE BECAUSE SPGuideAttachment IS NOT USE AT THE MOMENT (johan) @@ -410,8 +458,8 @@ char* SPGuide::description(bool const verbose) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(this->point_on_line[X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(this->point_on_line[Y], "px"); - GString *position_string_x = g_string_new(x_q.string(namedview->doc_units).c_str()); - GString *position_string_y = g_string_new(y_q.string(namedview->doc_units).c_str()); + GString *position_string_x = g_string_new(x_q.string(namedview->display_units).c_str()); + GString *position_string_y = g_string_new(y_q.string(namedview->display_units).c_str()); gchar *shortcuts = g_strdup_printf("; %s", _("<b>Shift+drag</b> to rotate, <b>Ctrl+drag</b> to move origin, <b>Del</b> to delete")); diff --git a/src/sp-hatch-path.cpp b/src/sp-hatch-path.cpp index 8558b67f2..bc95c246e 100644 --- a/src/sp-hatch-path.cpp +++ b/src/sp-hatch-path.cpp @@ -128,7 +128,7 @@ void SPHatchPath::set(unsigned int key, const gchar* value) default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(style, this); + style->readFromObject( this ); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObject::set(key, value); diff --git a/src/sp-hatch.cpp b/src/sp-hatch.cpp index 4a8707e08..dfecb2250 100644 --- a/src/sp-hatch.cpp +++ b/src/sp-hatch.cpp @@ -238,7 +238,7 @@ void SPHatch::set(unsigned int key, const gchar* value) default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(style, this); + style->readFromObject( this ); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPPaintServer::set(key, value); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 613ace5c1..b1ba37de2 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -40,7 +40,7 @@ #include "box3d.h" #include "persp3d.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "live_effects/effect.h" #include "live_effects/lpeobject.h" @@ -159,6 +159,7 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol } void SPGroup::update(SPCtx *ctx, unsigned int flags) { + // std::cout << "SPGroup::update(): " << (getId()?getId():"null") << std::endl; SPItemCtx *ictx, cctx; ictx = (SPItemCtx *) ctx; @@ -199,12 +200,16 @@ void SPGroup::update(SPCtx *ctx, unsigned int flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - group->setStyle(this->style); + if( this->parent ) { + this->context_style = this->parent->context_style; + } + group->setStyle(this->style, this->context_style); } } } void SPGroup::modified(guint flags) { + // std::cout << "SPGroup::modified(): " << (getId()?getId():"null") << std::endl; SPLPEItem::modified(flags); SPObject *child; @@ -352,11 +357,15 @@ void SPGroup::set(unsigned int key, gchar const* value) { } Inkscape::DrawingItem *SPGroup::show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + // std::cout << "SPGroup::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingGroup *ai; ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(this->effectiveLayerMode(key) == SPGroup::LAYER); - ai->setStyle(this->style); + if( this->parent ) { + this->context_style = this->parent->context_style; + } + ai->setStyle(this->style, this->context_style); this->_showChildren(drawing, ai, key, flags); return ai; @@ -435,7 +444,7 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // it here _before_ the new transform is set, so as to use the pre-transform bbox citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); - sp_style_merge_from_dying_parent(child->style, group->style); + child->style->merge( group->style ); /* * fixme: We currently make no allowance for the case where child is cloned * and the group has any style settings. @@ -444,9 +453,8 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) * version of inkscape without using the XML editor: we usually apply group * style changes to children rather than to the group itself.) * - * If the group has no style settings, then - * sp_style_merge_from_dying_parent should be a no-op. Otherwise (i.e. if - * we change the child's style to compensate for its parent going away) + * If the group has no style settings, then style->merge() should be a no-op. Otherwise + * (i.e. if we change the child's style to compensate for its parent going away) * then those changes will typically be reflected in any clones of child, * whereas we'd prefer for Ungroup not to affect the visual appearance. * @@ -662,8 +670,13 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo { if ( hasChildren() ) { for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); - if ( item ) { + if ( SPDefs *defs = dynamic_cast<SPDefs *>(o) ) { // select symbols from defs, ignore clips, masks, patterns + for (SPObject *defschild = defs->firstChild() ; defschild ; defschild = defschild->getNext() ) { + SPGroup *defsgroup = dynamic_cast<SPGroup *>(defschild); + if (defsgroup) + defsgroup->scaleChildItemsRec(sc, p, false); + } + } else if ( SPItem *item = dynamic_cast<SPItem *>(o) ) { SPGroup *group = dynamic_cast<SPGroup *>(item); if (group && !dynamic_cast<SPBox3D *>(item)) { /* Using recursion breaks clipping because transforms are applied @@ -714,8 +727,8 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo group->scaleChildItemsRec(sc, p, false); } } else { - Geom::OptRect bbox = item->desktopVisualBounds(); - if (bbox) { +// Geom::OptRect bbox = item->desktopVisualBounds(); +// if (bbox) { // test not needed, this was causing a failure to scale <circle> and <rect> in the clipboard, see LP Bug 1365451 // Scale item Geom::Translate const s(p); Geom::Affine final = s.inverse() * sc * s; @@ -776,7 +789,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled item->updateRepr(); } - } +// } } } } diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 967756055..5d181b80a 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1,6 +1,3 @@ -/** \file - * Base class for visual SVG elements - */ /* * Authors: * Lauris Kaplinski <lauris@kaplinski.com> @@ -15,12 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -/** \class SPItem - * - * SPItem is an abstract base class for all graphic (visible) SVG nodes. It - * is a subclass of SPObject, with great deal of specific functionality. - */ - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -34,7 +25,7 @@ #include "uri.h" #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "style.h" #include <glibmm/i18n.h> @@ -139,7 +130,8 @@ bool SPItem::isVisibleAndUnlocked(unsigned display_key) const { bool SPItem::isLocked() const { for (SPObject const *o = this; o != NULL; o = o->parent) { - if (SP_IS_ITEM(o) && !(SP_ITEM(o)->sensitive)) { + SPItem const *item = dynamic_cast<SPItem const *>(o); + if (item && !(item->sensitive)) { return true; } } @@ -194,14 +186,17 @@ guint32 SPItem::highlight_color() const { { return atoi(_highlightColor) | 0x00000000; } - else if (parent && parent != this && SP_IS_ITEM(parent)) - { - return SP_ITEM(parent)->highlight_color(); - } - else - { - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - return prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) | 0x00000000; + else { + SPItem const *item = dynamic_cast<SPItem const *>(parent); + if (parent && (parent != this) && item) + { + return item->highlight_color(); + } + else + { + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + return prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) | 0x00000000; + } } } @@ -218,8 +213,9 @@ void SPItem::resetEvaluated() { requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } } if ( StatusSet == _evaluated_status ) { - if (SP_IS_SWITCH(parent)) { - SP_SWITCH(parent)->resetChildEvaluated(); + SPSwitch *switchItem = dynamic_cast<SPSwitch *>(parent); + if (switchItem) { + switchItem->resetChildEvaluated(); } } } @@ -232,20 +228,12 @@ bool SPItem::isEvaluated() const { return _is_evaluated; } -/** - * Returns something suitable for the `Hide' checkbox in the Object Properties dialog box. - * Corresponds to setExplicitlyHidden. - */ bool SPItem::isExplicitlyHidden() const { return (style->display.set && style->display.value == SP_CSS_DISPLAY_NONE); } -/** - * Sets the display CSS property to `hidden' if \a val is true, - * otherwise makes it unset - */ void SPItem::setExplicitlyHidden(bool val) { style->display.set = val; style->display.value = ( val ? SP_CSS_DISPLAY_NONE : SP_CSS_DISPLAY_INLINE ); @@ -253,9 +241,6 @@ void SPItem::setExplicitlyHidden(bool val) { updateRepr(); } -/** - * Sets the transform_center_x and transform_center_y properties to retain the rotation center -*/ void SPItem::setCenter(Geom::Point const &object_centre) { document->ensureUpToDate(); @@ -326,7 +311,7 @@ SPItem::scaleCenter(Geom::Scale const &sc) { namespace { bool is_item(SPObject const &object) { - return SP_IS_ITEM(&object); + return dynamic_cast<SPItem const *>(&object) != NULL; } } @@ -389,11 +374,6 @@ void SPItem::lowerToBottom() { } } -/* - * Move this SPItem into or after another SPItem in the doc - * \param target - the SPItem to move into or after - * \param intoafter - move to after the target (false), move inside (sublayer) of the target (true) - */ void SPItem::moveTo(SPItem *target, bool intoafter) { Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL ); @@ -575,7 +555,7 @@ void SPItem::set(unsigned int key, gchar const* value) { } default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(object->style, object); + style->readFromObject( this ); object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObject::set(key, value); @@ -591,20 +571,23 @@ void SPItem::clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item) SPItemView *v; /* Hide clippath */ for (v = item->display; v != NULL; v = v->next) { - SP_CLIPPATH(old_clip)->hide(v->arenaitem->key()); + SPClipPath *oldPath = dynamic_cast<SPClipPath *>(old_clip); + g_assert(oldPath != NULL); + oldPath->hide(v->arenaitem->key()); } } - if (SP_IS_CLIPPATH(clip)) { + SPClipPath *clipPath = dynamic_cast<SPClipPath *>(clip); + if (clipPath) { Geom::OptRect bbox = item->geometricBounds(); for (SPItemView *v = item->display; v != NULL; v = v->next) { if (!v->arenaitem->key()) { v->arenaitem->setKey(SPItem::display_key_new(3)); } - Inkscape::DrawingItem *ai = SP_CLIPPATH(clip)->show( + Inkscape::DrawingItem *ai = clipPath->show( v->arenaitem->drawing(), v->arenaitem->key()); v->arenaitem->setClip(ai); - SP_CLIPPATH(clip)->setBBox(v->arenaitem->key(), bbox); + clipPath->setBBox(v->arenaitem->key(), bbox); clip->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -615,34 +598,37 @@ void SPItem::mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item) if (old_mask) { /* Hide mask */ for (SPItemView *v = item->display; v != NULL; v = v->next) { - SP_MASK(old_mask)->sp_mask_hide(v->arenaitem->key()); + SPMask *maskItem = dynamic_cast<SPMask *>(old_mask); + g_assert(maskItem != NULL); + maskItem->sp_mask_hide(v->arenaitem->key()); } } - if (SP_IS_MASK(mask)) { + SPMask *maskItem = dynamic_cast<SPMask *>(mask); + if (maskItem) { Geom::OptRect bbox = item->geometricBounds(); for (SPItemView *v = item->display; v != NULL; v = v->next) { if (!v->arenaitem->key()) { v->arenaitem->setKey(SPItem::display_key_new(3)); } - Inkscape::DrawingItem *ai = SP_MASK(mask)->sp_mask_show( + Inkscape::DrawingItem *ai = maskItem->sp_mask_show( v->arenaitem->drawing(), v->arenaitem->key()); v->arenaitem->setMask(ai); - SP_MASK(mask)->sp_mask_set_bbox(v->arenaitem->key(), bbox); + maskItem->sp_mask_set_bbox(v->arenaitem->key(), bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } } void SPItem::fill_ps_ref_changed(SPObject *old_ps, SPObject *ps, SPItem *item) { - SPPaintServer *old_fill_ps = SP_PAINT_SERVER(old_ps); + SPPaintServer *old_fill_ps = dynamic_cast<SPPaintServer *>(old_ps); if (old_fill_ps) { for (SPItemView *v =item->display; v != NULL; v = v->next) { old_fill_ps->hide(v->arenaitem->key()); } } - SPPaintServer *new_fill_ps = SP_PAINT_SERVER(ps); + SPPaintServer *new_fill_ps = dynamic_cast<SPPaintServer *>(ps); if (new_fill_ps) { Geom::OptRect bbox = item->geometricBounds(); for (SPItemView *v = item->display; v != NULL; v = v->next) { @@ -660,14 +646,14 @@ void SPItem::fill_ps_ref_changed(SPObject *old_ps, SPObject *ps, SPItem *item) { } void SPItem::stroke_ps_ref_changed(SPObject *old_ps, SPObject *ps, SPItem *item) { - SPPaintServer *old_stroke_ps = SP_PAINT_SERVER(old_ps); + SPPaintServer *old_stroke_ps = dynamic_cast<SPPaintServer *>(old_ps); if (old_stroke_ps) { for (SPItemView *v =item->display; v != NULL; v = v->next) { old_stroke_ps->hide(v->arenaitem->key()); } } - SPPaintServer *new_stroke_ps = SP_PAINT_SERVER(ps); + SPPaintServer *new_stroke_ps = dynamic_cast<SPPaintServer *>(ps); if (new_stroke_ps) { Geom::OptRect bbox = item->geometricBounds(); for (SPItemView *v = item->display; v != NULL; v = v->next) { @@ -756,7 +742,7 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X if (flags & SP_OBJECT_WRITE_BUILD) { GSList *l = NULL; for (SPObject *child = object->firstChild(); child != NULL; child = child->next ) { - if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { + if (dynamic_cast<SPTitle *>(child) || dynamic_cast<SPDesc *>(child)) { Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend (l, crepr); @@ -770,7 +756,7 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X } } else { for (SPObject *child = object->firstChild() ; child != NULL; child = child->next ) { - if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { + if (dynamic_cast<SPTitle *>(child) || dynamic_cast<SPDesc *>(child)) { child->updateRepr(flags); } } @@ -826,11 +812,7 @@ Geom::OptRect SPItem::bbox(Geom::Affine const & /*transform*/, SPItem::BBoxType //throw; return Geom::OptRect(); } -/** - * Get item's geometric bounding box in this item's coordinate system. - * - * The geometric bounding box includes only the path, disregarding all style attributes. - */ + Geom::OptRect SPItem::geometricBounds(Geom::Affine const &transform) const { Geom::OptRect bbox; @@ -843,11 +825,6 @@ Geom::OptRect SPItem::geometricBounds(Geom::Affine const &transform) const return bbox; } -/** - * Get item's visual bounding box in this item's coordinate system. - * - * The visual bounding box includes the stroke and the filter region. - */ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const { using Geom::X; @@ -855,13 +832,14 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const Geom::OptRect bbox; - if ( style && style->filter.href && style->getFilter() && SP_IS_FILTER(style->getFilter())) { + + SPFilter *filter = (style && style->filter.href) ? dynamic_cast<SPFilter *>(style->getFilter()) : NULL; + if ( filter ) { // call the subclass method // CPPIFY //bbox = this->bbox(Geom::identity(), SPItem::VISUAL_BBOX); bbox = const_cast<SPItem*>(this)->bbox(Geom::identity(), SPItem::GEOMETRIC_BBOX); // see LP Bug 1229971 - SPFilter *filter = SP_FILTER(style->getFilter()); // default filer area per the SVG spec: SVGLength x, y, w, h; Geom::Point minp, maxp; @@ -908,8 +886,10 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const bbox = const_cast<SPItem*>(this)->bbox(transform, SPItem::VISUAL_BBOX); } if (clip_ref->getObject()) { - SP_ITEM(clip_ref->getOwner())->bbox_valid = FALSE; // LP Bug 1349018 - bbox.intersectWith(SP_CLIPPATH(clip_ref->getObject())->geometricBounds(transform)); + SPItem *ownerItem = dynamic_cast<SPItem *>(clip_ref->getOwner()); + g_assert(ownerItem != NULL); + ownerItem->bbox_valid = FALSE; // LP Bug 1349018 + bbox.intersectWith(clip_ref->getObject()->geometricBounds(transform)); } return bbox; @@ -924,14 +904,11 @@ Geom::OptRect SPItem::bounds(BBoxType type, Geom::Affine const &transform) const } } -/** Get item's geometric bbox in document coordinate system. - * Document coordinates are the default coordinates of the root element: - * the origin is at the top left, X grows to the right and Y grows downwards. */ Geom::OptRect SPItem::documentGeometricBounds() const { return geometricBounds(i2doc_affine()); } -/// Get item's visual bbox in document coordinate system. + Geom::OptRect SPItem::documentVisualBounds() const { if (!bbox_valid) { @@ -948,14 +925,12 @@ Geom::OptRect SPItem::documentBounds(BBoxType type) const return documentVisualBounds(); } } -/** Get item's geometric bbox in desktop coordinate system. - * Desktop coordinates should be user defined. Currently they are hardcoded: - * origin is at bottom left, X grows to the right and Y grows upwards. */ + Geom::OptRect SPItem::desktopGeometricBounds() const { return geometricBounds(i2dt_affine()); } -/// Get item's visual bbox in desktop coordinate system. + Geom::OptRect SPItem::desktopVisualBounds() const { /// @fixme hardcoded desktop transform @@ -994,7 +969,7 @@ unsigned int SPItem::pos_in_parent() const { return pos; } - if (SP_IS_ITEM(iter)) { + if (dynamic_cast<SPItem *>(iter)) { pos++; } } @@ -1031,15 +1006,16 @@ void SPItem::getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscap clips_and_masks.push_back(clip_ref->getObject()); clips_and_masks.push_back(mask_ref->getObject()); - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; for (std::list<SPObject const *>::const_iterator o = clips_and_masks.begin(); o != clips_and_masks.end(); ++o) { if (*o) { // obj is a group object, the children are the actual clippers for (SPObject *child = (*o)->children ; child ; child = child->next) { - if (SP_IS_ITEM(child)) { + SPItem *item = dynamic_cast<SPItem *>(child); + if (item) { std::vector<Inkscape::SnapCandidatePoint> p_clip_or_mask; // Please note the recursive call here! - SP_ITEM(child)->getSnappoints(p_clip_or_mask, snapprefs); + item->getSnappoints(p_clip_or_mask, snapprefs); // Take into account the transformation of the item being clipped or masked for (std::vector<Inkscape::SnapCandidatePoint>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); ++p_orig) { // All snappoints are in desktop coordinates, but the item's transformation is @@ -1079,11 +1055,6 @@ gchar* SPItem::description() const { return g_strdup(""); } -/** - * Returns a string suitable for status bar, formatted in pango markup language. - * - * Must be freed by caller. - */ gchar *SPItem::detailedDescription() const { gchar* s = g_strdup_printf("<b>%s</b> %s", this->displayName(), this->description()); @@ -1117,20 +1088,10 @@ gchar *SPItem::detailedDescription() const { return s; } -/** - * Returns true if the item is filtered, false otherwise. Used with groups/lists to determine how many, or if any, are filtered - * - */ bool SPItem::isFiltered() const { return (style && style->filter.href && style->filter.href->getObject()); } -/** - * Allocates unique integer keys. - * \param numkeys Number of keys required. - * \return First allocated key; hence if the returned key is n - * you can use n, n + 1, ..., n + (numkeys - 1) - */ unsigned SPItem::display_key_new(unsigned numkeys) { static unsigned dkey = 0; @@ -1176,7 +1137,7 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned ai->setClip(ac); // Update bbox, in case the clip uses bbox units - SP_CLIPPATH(cp)->setBBox(clip_key, item_bbox); + cp->setBBox(clip_key, item_bbox); cp->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } if (mask_ref->getObject()) { @@ -1192,7 +1153,7 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned ai->setMask(ac); // Update bbox, in case the mask uses bbox units - SP_MASK(mask)->sp_mask_set_bbox(mask_key, item_bbox); + mask->sp_mask_set_bbox(mask_key, item_bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -1280,8 +1241,9 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf bool fill = (pt == TRANSFORM_FILL || pt == TRANSFORM_BOTH); if (fill && style && (style->fill.isPaintserver())) { SPObject *server = style->getFillPaintServer(); - if ( SP_IS_PATTERN(server) ) { - SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "fill"); + SPPattern *serverPatt = dynamic_cast<SPPattern *>(server); + if ( serverPatt ) { + SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "fill"); sp_pattern_transform_multiply(pattern, postmul, set); } } @@ -1289,8 +1251,9 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf bool stroke = (pt == TRANSFORM_STROKE || pt == TRANSFORM_BOTH); if (stroke && style && (style->stroke.isPaintserver())) { SPObject *server = style->getStrokePaintServer(); - if ( SP_IS_PATTERN(server) ) { - SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "stroke"); + SPPattern *serverPatt = dynamic_cast<SPPattern *>(server); + if ( serverPatt ) { + SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "stroke"); sp_pattern_transform_multiply(pattern, postmul, set); } } @@ -1300,7 +1263,8 @@ void SPItem::adjust_gradient( Geom::Affine const &postmul, bool set ) { if ( style && style->fill.isPaintserver() ) { SPPaintServer *server = style->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { + SPGradient *serverGrad = dynamic_cast<SPGradient *>(server); + if ( serverGrad ) { /** * \note Bbox units for a gradient are generally a bad idea because @@ -1311,7 +1275,7 @@ void SPItem::adjust_gradient( Geom::Affine const &postmul, bool set ) * \todo FIXME: convert back to bbox units after transforming with * the item, so as to preserve the original units. */ - SPGradient *gradient = sp_gradient_convert_to_userspace( SP_GRADIENT(server), this, "fill" ); + SPGradient *gradient = sp_gradient_convert_to_userspace( serverGrad, this, "fill" ); sp_gradient_transform_multiply( gradient, postmul, set ); } @@ -1319,8 +1283,9 @@ void SPItem::adjust_gradient( Geom::Affine const &postmul, bool set ) if ( style && style->stroke.isPaintserver() ) { SPPaintServer *server = style->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient *gradient = sp_gradient_convert_to_userspace( SP_GRADIENT(server), this, "stroke"); + SPGradient *serverGrad = dynamic_cast<SPGradient *>(server); + if ( serverGrad ) { + SPGradient *gradient = sp_gradient_convert_to_userspace( serverGrad, this, "stroke"); sp_gradient_transform_multiply( gradient, postmul, set ); } } @@ -1334,7 +1299,7 @@ void SPItem::adjust_stroke( gdouble ex ) SPStyle *style = this->style; - if (style && !style->stroke.isNone() && !Geom::are_near(ex, 1.0, Geom::EPSILON)) { + if (style && !Geom::are_near(ex, 1.0, Geom::EPSILON)) { style->stroke_width.computed *= ex; style->stroke_width.set = TRUE; @@ -1367,18 +1332,16 @@ static Geom::Affine sp_item_transform_repr (SPItem *item) } -/** - * Recursively scale stroke width in \a item and its children by \a expansion. - */ void SPItem::adjust_stroke_width_recursive(double expansion) { adjust_stroke (expansion); // A clone's child is the ghost of its original - we must not touch it, skip recursion - if ( !SP_IS_USE(this) ) { + if ( !dynamic_cast<SPUse *>(this) ) { for ( SPObject *o = children; o; o = o->getNext() ) { - if (SP_IS_ITEM(o)) { - SP_ITEM(o)->adjust_stroke_width_recursive(expansion); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + item->adjust_stroke_width_recursive(expansion); } } } @@ -1389,10 +1352,11 @@ void SPItem::freeze_stroke_width_recursive(bool freeze) freeze_stroke_width = freeze; // A clone's child is the ghost of its original - we must not touch it, skip recursion - if ( !SP_IS_USE(this) ) { + if ( !dynamic_cast<SPUse *>(this) ) { for ( SPObject *o = children; o; o = o->getNext() ) { - if (SP_IS_ITEM(o)) { - SP_ITEM(o)->freeze_stroke_width_recursive(freeze); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + item->freeze_stroke_width_recursive(freeze); } } } @@ -1404,19 +1368,19 @@ void SPItem::freeze_stroke_width_recursive(bool freeze) static void sp_item_adjust_rects_recursive(SPItem *item, Geom::Affine advertized_transform) { - if (SP_IS_RECT (item)) { - SP_RECT(item)->compensateRxRy(advertized_transform); + SPRect *rect = dynamic_cast<SPRect *>(item); + if (rect) { + rect->compensateRxRy(advertized_transform); } for (SPObject *o = item->children; o != NULL; o = o->next) { - if (SP_IS_ITEM(o)) - sp_item_adjust_rects_recursive(SP_ITEM(o), advertized_transform); + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { + sp_item_adjust_rects_recursive(item, advertized_transform); + } } } -/** - * Recursively compensate pattern or gradient transform. - */ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Affine t_ancestors, bool is_pattern) { // _Before_ full pattern/gradient transform: t_paint * t_item * t_ancestors @@ -1428,12 +1392,13 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af // Within text, we do not fork gradients, and so must not recurse to avoid double compensation; // also we do not recurse into clones, because a clone's child is the ghost of its original - // we must not touch it - if (!(this && (SP_IS_TEXT(this) || SP_IS_USE(this)))) { + if (!(this && (dynamic_cast<SPText *>(this) || dynamic_cast<SPUse *>(this)))) { for (SPObject *o = children; o != NULL; o = o->next) { - if (SP_IS_ITEM(o)) { + SPItem *item = dynamic_cast<SPItem *>(o); + if (item) { // At the level of the transformed item, t_ancestors is identity; // below it, it is the accmmulated chain of transforms from this level to the top level - SP_ITEM(o)->adjust_paint_recursive (advertized_transform, t_item * t_ancestors, is_pattern); + item->adjust_paint_recursive (advertized_transform, t_item * t_ancestors, is_pattern); } } } @@ -1452,20 +1417,18 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af void SPItem::adjust_livepatheffect (Geom::Affine const &postmul, bool set) { - if ( SP_IS_LPE_ITEM(this) ) { - SPLPEItem *lpeitem = SP_LPE_ITEM (this); - if ( lpeitem->hasPathEffect() ) { - lpeitem->forkPathEffectsIfNecessary(); - - // now that all LPEs are forked_if_necessary, we can apply the transform - PathEffectList effect_list = lpeitem->getEffectList(); - for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); ++it) - { - LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj && lpeobj->get_lpe()) { - Inkscape::LivePathEffect::Effect * effect = lpeobj->get_lpe(); - effect->transform_multiply(postmul, set); - } + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(this); + if ( lpeitem && lpeitem->hasPathEffect() ) { + lpeitem->forkPathEffectsIfNecessary(); + + // now that all LPEs are forked_if_necessary, we can apply the transform + PathEffectList effect_list = lpeitem->getEffectList(); + for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); ++it) + { + LivePathEffectObject *lpeobj = (*it)->lpeobject; + if (lpeobj && lpeobj->get_lpe()) { + Inkscape::LivePathEffect::Effect * effect = lpeobj->get_lpe(); + effect->transform_multiply(postmul, set); } } } @@ -1478,14 +1441,6 @@ Geom::Affine SPItem::set_transform(Geom::Affine const &transform) { return transform; } -/** - * Set a new transform on an object. - * - * Compensate for stroke scaling and gradient/pattern fill transform, if - * necessary. Call the object's set_transform method if transforms are - * stored optimized. Send _transformed_signal. Invoke _write method so that - * the repr is updated with the new transform. - */ void SPItem::doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &transform, Geom::Affine const *adv, bool compensate) { g_return_if_fail(repr != NULL); @@ -1548,7 +1503,7 @@ void SPItem::doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &tra // onSetTransform cannot be pure due to the fact that not all visible Items are transformable. if ( // run the object's set_transform (i.e. embed transform) only if: - SP_IS_TEXT_TEXTPATH(this) || + (dynamic_cast<SPText *>(this) && firstChild() && dynamic_cast<SPTextPath *>(firstChild())) || (!preserve && // user did not chose to preserve all transforms (!clip_ref || !clip_ref->getObject()) && // the object does not have a clippath (!mask_ref || !mask_ref->getObject()) && // the object does not have a mask @@ -1597,10 +1552,6 @@ gint SPItem::emitEvent(SPEvent &event) return this->event(&event); } -/** - * Sets item private transform (not propagated to repr), without compensating stroke widths, - * gradients, patterns as sp_item_write_transform does. - */ void SPItem::set_item_transform(Geom::Affine const &transform_matrix) { if (!Geom::are_near(transform_matrix, transform, 1e-18)) { @@ -1618,21 +1569,19 @@ void SPItem::set_item_transform(Geom::Affine const &transform_matrix) //} -/** - * \pre \a ancestor really is an ancestor (\>=) of \a object, or NULL. - * ("Ancestor (\>=)" here includes as far as \a object itself.) - */ -Geom::Affine -i2anc_affine(SPObject const *object, SPObject const *const ancestor) { +Geom::Affine i2anc_affine(SPObject const *object, SPObject const *const ancestor) { Geom::Affine ret(Geom::identity()); g_return_val_if_fail(object != NULL, ret); /* stop at first non-renderable ancestor */ - while ( object != ancestor && SP_IS_ITEM(object) ) { - if (SP_IS_ROOT(object)) { - ret *= SP_ROOT(object)->c2p; + while ( object != ancestor && dynamic_cast<SPItem const *>(object) ) { + SPRoot const *root = dynamic_cast<SPRoot const *>(object); + if (root) { + ret *= root->c2p; } else { - ret *= SP_ITEM(object)->transform; + SPItem const *item = dynamic_cast<SPItem const *>(object); + g_assert(item != NULL); + ret *= item->transform; } object = object->parent; } @@ -1650,22 +1599,15 @@ Geom::Affine SPItem::getRelativeTransform(SPObject const *dest) const { return i2i_affine(this, dest); } -/** - * Returns the accumulated transformation of the item and all its ancestors, including root's viewport. - * \pre (item != NULL) and SP_IS_ITEM(item). - */ Geom::Affine SPItem::i2doc_affine() const { return i2anc_affine(this, NULL); } -/** - * Returns the transformation from item to desktop coords - */ Geom::Affine SPItem::i2dt_affine() const { Geom::Affine ret; - SPDesktop const *desktop = inkscape_active_desktop(); + SPDesktop const *desktop = SP_ACTIVE_DESKTOP; if ( desktop ) { ret = i2doc_affine() * desktop->doc2dt(); } else { @@ -1683,7 +1625,7 @@ void SPItem::set_i2d_affine(Geom::Affine const &i2dt) if (parent) { dt2p = static_cast<SPItem *>(parent)->i2dt_affine().inverse(); } else { - SPDesktop *dt = inkscape_active_desktop(); + SPDesktop *dt = SP_ACTIVE_DESKTOP; dt2p = dt->dt2doc(); } @@ -1692,9 +1634,6 @@ void SPItem::set_i2d_affine(Geom::Affine const &i2dt) } -/** - * should rather be named "sp_item_d2i_affine" to match "sp_item_i2d_affine" (or vice versa) - */ Geom::Affine SPItem::dt2i_affine() const { /* fixme: Implement the right way (Lauris) */ @@ -1706,7 +1645,7 @@ Geom::Affine SPItem::dt2i_affine() const SPItemView *SPItem::sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, Inkscape::DrawingItem *drawing_item) { g_assert(item != NULL); - g_assert(SP_IS_ITEM(item)); + g_assert(dynamic_cast<SPItem *>(item) != NULL); g_assert(drawing_item != NULL); SPItemView *new_view = g_new(SPItemView, 1); @@ -1738,10 +1677,6 @@ sp_item_view_list_remove(SPItemView *list, SPItemView *view) return ret; } -/** - * Return the arenaitem corresponding to the given item in the display - * with the given key - */ Inkscape::DrawingItem *SPItem::get_arenaitem(unsigned key) { for ( SPItemView *iv = display ; iv ; iv = iv->next ) { @@ -1768,8 +1703,9 @@ SPItem *sp_item_first_item_child(SPObject *obj) { SPItem *child = 0; for ( SPObject *iter = obj->firstChild() ; iter ; iter = iter->next ) { - if ( SP_IS_ITEM(iter) ) { - child = SP_ITEM(iter); + SPItem *tmp = dynamic_cast<SPItem *>(iter); + if ( tmp ) { + child = tmp; break; } } diff --git a/src/sp-item.h b/src/sp-item.h index 1656a0c2b..b9d71c551 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -1,7 +1,8 @@ #ifndef SEEN_SP_ITEM_H #define SEEN_SP_ITEM_H -/** \file +/** + * @file * Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx, SPItemClass, SPEvent. */ @@ -65,7 +66,7 @@ enum PatternTransform { /** * Event structure. * - * \todo This is just placeholder. Plan: + * @todo This is just placeholder. Plan: * We do extensible event structure, that hold applicable (ui, non-ui) * data pointers. So it is up to given object/arena implementation * to process correct ones in meaningful way. @@ -78,7 +79,6 @@ public: void* data; }; -/// SPItemView class SPItemView { public: SPItemView *next; @@ -95,17 +95,21 @@ public: /** * Flag for referenced views (i.e. markers, clippaths, masks and patterns); - currently unused, does the same as DISPLAY + * currently unused, does the same as DISPLAY */ #define SP_ITEM_REFERENCE_FLAGS (1 << 1) -/// Contains transformations to document/viewport and the viewport size. +/** + * Contains transformations to document/viewport and the viewport size. + */ class SPItemCtx : public SPCtx { public: /** Item to document transformation */ Geom::Affine i2doc; + /** Viewport size */ Geom::Rect viewport; + /** Item to viewport transformation */ Geom::Affine i2vp; }; @@ -113,7 +117,11 @@ public: #define SP_ITEM(obj) (dynamic_cast<SPItem*>((SPObject*)obj)) #define SP_IS_ITEM(obj) (dynamic_cast<const SPItem*>((SPObject*)obj) != NULL) -/** Abstract base class for all visible shapes. */ +/** + * Base class for visual SVG elements. + * SPItem is an abstract base class for all graphic (visible) SVG nodes. It + * is a subclass of SPObject, with great deal of specific functionality. + */ class SPItem : public SPObject { public: enum BBoxType { @@ -156,7 +164,7 @@ public: bool isHidden() const; void setHidden(bool hidden); - /* Objects dialogue */ + // Objects dialogue bool isSensitive() const { return sensitive; }; @@ -167,7 +175,7 @@ public: void setHighlightColor(guint32 color); void unsetHighlightColor(); - /********************/ + //==================== bool isEvaluated() const; void setEvaluated(bool visible); @@ -175,11 +183,23 @@ public: bool isHidden(unsigned display_key) const; + /** + * Returns something suitable for the `Hide' checkbox in the Object Properties dialog box. + * Corresponds to setExplicitlyHidden. + */ bool isExplicitlyHidden() const; + /** + * Sets the display CSS property to `hidden' if \a val is true, + * otherwise makes it unset. + */ void setExplicitlyHidden(bool val); + /** + * Sets the transform_center_x and transform_center_y properties to retain the rotation center + */ void setCenter(Geom::Point const &object_centre); + void unsetCenter(); bool isCenterSet() const; Geom::Point getCenter() const; @@ -195,52 +215,155 @@ public: void lowerOne(); void raiseToTop(); void lowerToBottom(); + + /** + * Move this SPItem into or after another SPItem in the doc. + * + * @param target the SPItem to move into or after. + * @param intoafter move to after the target (false), move inside (sublayer) of the target (true). + */ void moveTo(SPItem *target, bool intoafter); sigc::connection connectTransformed(sigc::slot<void, Geom::Affine const *, SPItem *> slot) { return _transformed_signal.connect(slot); } + /** + * Get item's geometric bounding box in this item's coordinate system. + * + * The geometric bounding box includes only the path, disregarding all style attributes. + */ Geom::OptRect geometricBounds(Geom::Affine const &transform = Geom::identity()) const; + + /** + * Get item's visual bounding box in this item's coordinate system. + * + * The visual bounding box includes the stroke and the filter region. + */ Geom::OptRect visualBounds(Geom::Affine const &transform = Geom::identity()) const; + Geom::OptRect bounds(BBoxType type, Geom::Affine const &transform = Geom::identity()) const; + + /** + * Get item's geometric bbox in document coordinate system. + * Document coordinates are the default coordinates of the root element: + * the origin is at the top left, X grows to the right and Y grows downwards. + */ Geom::OptRect documentGeometricBounds() const; + + /** + * Get item's visual bbox in document coordinate system. + */ Geom::OptRect documentVisualBounds() const; + Geom::OptRect documentBounds(BBoxType type) const; + + /** + * Get item's geometric bbox in desktop coordinate system. + * Desktop coordinates should be user defined. Currently they are hardcoded: + * origin is at bottom left, X grows to the right and Y grows upwards. + */ Geom::OptRect desktopGeometricBounds() const; + + /** + * Get item's visual bbox in desktop coordinate system. + */ Geom::OptRect desktopVisualBounds() const; + Geom::OptRect desktopPreferredBounds() const; Geom::OptRect desktopBounds(BBoxType type) const; unsigned int pos_in_parent() const; + /** + * Returns a string suitable for status bar, formatted in pango markup language. + * + * Must be freed by caller. + */ char *detailedDescription() const; + /** + * Returns true if the item is filtered, false otherwise. + * Used with groups/lists to determine how many, or if any, are filtered. + */ bool isFiltered() const; void invoke_print(SPPrintContext *ctx); + + /** + * Allocates unique integer keys. + * + * @param numkeys Number of keys required. + * @return First allocated key; hence if the returned key is n + * you can use n, n + 1, ..., n + (numkeys - 1) + */ static unsigned int display_key_new(unsigned int numkeys); + Inkscape::DrawingItem *invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); void invoke_hide(unsigned int key); void getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs=0) const; void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false, PatternTransform = TRANSFORM_BOTH); void adjust_gradient(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false); void adjust_stroke(double ex); + + /** + * Recursively scale stroke width in \a item and its children by \a expansion. + */ void adjust_stroke_width_recursive(double ex); + void freeze_stroke_width_recursive(bool freeze); + + /** + * Recursively compensate pattern or gradient transform. + */ void adjust_paint_recursive(Geom::Affine advertized_transform, Geom::Affine t_ancestors, bool is_pattern); + void adjust_livepatheffect(Geom::Affine const &postmul, bool set = false); + + /** + * Set a new transform on an object. + * + * Compensate for stroke scaling and gradient/pattern fill transform, if + * necessary. Call the object's set_transform method if transforms are + * stored optimized. Send _transformed_signal. Invoke _write method so that + * the repr is updated with the new transform. + */ void doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &transform, Geom::Affine const *adv = NULL, bool compensate = true); + + /** + * Sets item private transform (not propagated to repr), without compensating stroke widths, + * gradients, patterns as sp_item_write_transform does. + */ void set_item_transform(Geom::Affine const &transform_matrix); + int emitEvent (SPEvent &event); + + /** + * Return the arenaitem corresponding to the given item in the display + * with the given key + */ Inkscape::DrawingItem *get_arenaitem(unsigned int key); + /** + * Returns the accumulated transformation of the item and all its ancestors, including root's viewport. + * @pre (item != NULL) and SP_IS_ITEM(item). + */ Geom::Affine i2doc_affine() const; + + /** + * Returns the transformation from item to desktop coords + */ Geom::Affine i2dt_affine() const; + void set_i2d_affine(Geom::Affine const &transform); + + /** + * should rather be named "sp_item_d2i_affine" to match "sp_item_i2d_affine" (or vice versa). + */ Geom::Affine dt2i_affine() const; char *_highlightColor; + private: enum EvaluatedStatus { @@ -281,17 +404,16 @@ public: // Utility +/** + * @pre \a ancestor really is an ancestor (\>=) of \a object, or NULL. + * ("Ancestor (\>=)" here includes as far as \a object itself.) + */ Geom::Affine i2anc_affine(SPObject const *item, SPObject const *ancestor); + Geom::Affine i2i_affine(SPObject const *src, SPObject const *dest); /* fixme: - these are evil, but OK */ -/* Fill *TRANSFORM with the item-to-desktop transform. See doc/coordinates.txt - * for a description of `Desktop coordinates'; though see also mental's comment - * at the top of that file. - * - * \return TRANSFORM. - */ int sp_item_repr_compare_position(SPItem const *first, SPItem const *second); SPItem *sp_item_first_item_child (SPObject *obj); SPItem const *sp_item_first_item_child (SPObject const *obj); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 019d15162..f059ab531 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -58,8 +58,8 @@ static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); typedef std::list<std::string> HRefList; -static std::string patheffectlist_write_svg(PathEffectList const & list); -static std::string hreflist_write_svg(HRefList const & list); +static std::string patheffectlist_svg_string(PathEffectList const & list); +static std::string hreflist_svg_string(HRefList const & list); SPLPEItem::SPLPEItem() : SPItem() @@ -195,8 +195,7 @@ void SPLPEItem::modified(unsigned int flags) { Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if (flags & SP_OBJECT_WRITE_EXT) { if ( hasPathEffect() ) { - std::string href = patheffectlist_write_svg(*this->path_effect_list); - repr->setAttribute("inkscape:path-effect", href.c_str()); + repr->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); } else { repr->setAttribute("inkscape:path-effect", NULL); } @@ -418,9 +417,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) } } -void SPLPEItem::addPathEffect(gchar *value, bool reset) +void SPLPEItem::addPathEffect(std::string value, bool reset) { - if (value) { + if (!value.empty()) { // Apply the path effects here because in the casse of a group, lpe->resetDefaults // needs that all the subitems have their effects applied sp_lpe_item_update_patheffect(this, false, true); @@ -434,10 +433,9 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) { hreflist.push_back( std::string((*it)->lpeobject_href) ); } - hreflist.push_back( std::string(value) ); - std::string hrefs = hreflist_write_svg(hreflist); + hreflist.push_back(value); // C++11: should be emplace_back std::move'd (also the reason why passed by value to addPathEffect) - this->getRepr()->setAttribute("inkscape:path-effect", hrefs.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); // Make sure that ellipse is stored as <svg:path> if( SP_IS_GENERICELLIPSE(this)) { @@ -501,13 +499,7 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) } PathEffectList new_list = *this->path_effect_list; new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list - std::string r = patheffectlist_write_svg(new_list); - - if (!r.empty()) { - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); - } else { - this->getRepr()->setAttribute("inkscape:path-effect", NULL); - } + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); if (!keep_paths) { // Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible. @@ -551,8 +543,8 @@ void SPLPEItem::downCurrentPathEffect() std::iter_swap(cur_it, down_it); } } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -570,9 +562,8 @@ void SPLPEItem::upCurrentPathEffect() --up_it; std::iter_swap(cur_it, up_it); } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -862,16 +853,16 @@ void SPLPEItem::remove_child(Inkscape::XML::Node * child) { SPItem::remove_child(child); } -static std::string patheffectlist_write_svg(PathEffectList const & list) +static std::string patheffectlist_svg_string(PathEffectList const & list) { HRefList hreflist; for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) { - hreflist.push_back( std::string((*it)->lpeobject_href) ); + hreflist.push_back( std::string((*it)->lpeobject_href) ); // C++11: use emplace_back } - return hreflist_write_svg(hreflist); + return hreflist_svg_string(hreflist); } /** @@ -881,7 +872,7 @@ static std::string patheffectlist_write_svg(PathEffectList const & list) * - populate the templist with the effects from the old list that you want to have and their order * - call this function with temp list as param */ -static std::string hreflist_write_svg(HRefList const & list) +static std::string hreflist_svg_string(HRefList const & list) { std::string r; bool semicolon_first = false; @@ -968,8 +959,7 @@ void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> co } } - std::string r = hreflist_write_svg(hreflist); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); } /** diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9c052b7b1..902271430 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -15,6 +15,7 @@ */ #include <list> +#include <string> #include "sp-item.h" #define SP_LPE_ITEM(obj) (dynamic_cast<SPLPEItem*>((SPObject*)obj)) @@ -88,7 +89,7 @@ public: bool setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef); void removeCurrentPathEffect(bool keep_paths); void removeAllPathEffects(bool keep_paths); - void addPathEffect(char *value, bool reset); + void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); void apply_to_mask(SPItem * item); void apply_to_clippath(SPItem * item); diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp index e955594ab..371a6c35c 100644 --- a/src/sp-marker.cpp +++ b/src/sp-marker.cpp @@ -29,13 +29,19 @@ #include "document-private.h" #include "preferences.h" -struct SPMarkerView { - SPMarkerView *next; - unsigned int key; - std::vector<Inkscape::DrawingItem *> items; -}; +class SPMarkerView { -static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems); +public: + + SPMarkerView() {}; + ~SPMarkerView() { + for (unsigned int i = 0; i < items.size(); ++i) { + delete items[i]; + } + items.clear(); + } + std::vector<Inkscape::DrawingItem *> items; +}; #include "sp-factory.h" @@ -55,8 +61,6 @@ SPMarker::SPMarker() : SPGroup(), SPViewBox() { this->orient_mode = MARKER_ORIENT_ANGLE; this->orient_set = 0; this->orient = 0; - - this->views = NULL; } /** @@ -90,20 +94,6 @@ void SPMarker::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGroup::build(document, repr); } -void SPMarker::release() { - while (this->views) { - // Destroy all DrawingItems etc. - // Parent class ::hide method - //reinterpret_cast<SPItemClass *>(parent_class)->hide(marker, marker->views->key); - // CPPIFY: correct one? - SPGroup::hide(this->views->key); - - - sp_marker_view_remove (this, this->views, TRUE); - } - - SPGroup::release(); -} /** * Removes, releases and unrefs all children of object @@ -117,6 +107,17 @@ void SPMarker::release() { * * \see SPObject::release() */ +void SPMarker::release() { + + std::map<unsigned int, SPMarkerView>::iterator it; + for (it = views_map.begin(); it != views_map.end(); ++it) { + SPGroup::hide( it->first ); + } + views_map.clear(); + + SPGroup::release(); +} + void SPMarker::set(unsigned int key, const gchar* value) { switch (key) { @@ -168,9 +169,12 @@ void SPMarker::set(unsigned int key, const gchar* value) { } else if (!strcmp (value, "auto-start-reverse")) { this->orient_mode = MARKER_ORIENT_AUTO_START_REVERSE; this->orient_set = TRUE; - } else if (sp_svg_number_read_f (value, &this->orient)) { - this->orient_mode = MARKER_ORIENT_ANGLE; - this->orient_set = TRUE; + } else { + orient.readOrUnset(value); + if (orient._set) { + this->orient_mode = MARKER_ORIENT_ANGLE; + this->orient_set = orient._set; + } } } @@ -218,10 +222,11 @@ void SPMarker::update(SPCtx *ctx, guint flags) { SPGroup::update((SPCtx *) &rctx, flags); // As last step set additional transform of drawing group - for (SPMarkerView *v = this->views; v != NULL; v = v->next) { - for (unsigned i = 0 ; i < v->items.size() ; i++) { - if (v->items[i]) { - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[i]); + std::map<unsigned int, SPMarkerView>::iterator it; + for (it = views_map.begin(); it != views_map.end(); ++it) { + for (unsigned i = 0 ; i < it->second.items.size() ; ++i) { + if (it->second.items[i]) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(it->second.items[i]); g->setChildTransform(this->c2p); } } @@ -273,7 +278,7 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: } else if (this->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { repr->setAttribute("orient", "auto-start-reverse"); } else { - sp_repr_set_css_double(repr, "orient", this->orient); + sp_repr_set_css_double(repr, "orient", this->orient.computed); } } else { repr->setAttribute("orient", NULL); @@ -325,31 +330,26 @@ void SPMarker::print(SPPrintContext* /*ctx*/) { * \param key Key to give each SPMarkerView. * \param size Number of DrawingItems to put in the SPMarkerView. */ +// If marker views are always created in order, then this function could be eliminated +// by doing the push_back in sp_marker_show_instance. void sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size) { - SPMarkerView *view; - - for (view = marker->views; view != NULL; view = view->next) { - if (view->key == key) break; - } - if (view && (view->items.size() != size)) { - /* Free old view and allocate new */ - /* Parent class ::hide method */ - marker->hide(key); - - sp_marker_view_remove (marker, view, TRUE); - view = NULL; - } - if (!view) { - view = new SPMarkerView(); - view->items.clear(); - for (unsigned int i = 0; i < size; i++) { - view->items.push_back(NULL); + std::map<unsigned int, SPMarkerView>::iterator it = marker->views_map.find(key); + if (it != marker->views_map.end()) { + if (it->second.items.size() != size ) { + // Need to change size of vector! (We should not really need to do this.) + marker->hide(key); + it->second.items.clear(); + for (unsigned int i = 0; i < size; ++i) { + it->second.items.push_back(NULL); + } + } + } else { + marker->views_map[key] = SPMarkerView(); + for (unsigned int i = 0; i < size; ++i) { + marker->views_map[key].items.push_back(NULL); } - view->next = marker->views; - marker->views = view; - view->key = key; } } @@ -362,51 +362,58 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, unsigned int key, unsigned int pos, Geom::Affine const &base, float linewidth) { - // do not show marker if linewidth == 0 and markerUnits == strokeWidth + // Do not show marker if linewidth == 0 and markerUnits == strokeWidth // otherwise Cairo will fail to render anything on the tile - // that contains the "degenerate" marker + // that contains the "degenerate" marker. if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH && linewidth == 0) { return NULL; } - for (SPMarkerView *v = marker->views; v != NULL; v = v->next) { - if (v->key == key) { - if (pos >= v->items.size()) { - return NULL; - } - if (!v->items[pos]) { - /* Parent class ::show method */ - v->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); - - if (v->items[pos]) { - /* fixme: Position (Lauris) */ - parent->prependChild(v->items[pos]); - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[pos]); - if (g) g->setChildTransform(marker->c2p); - } - } - if (v->items[pos]) { - Geom::Affine m; - if (marker->orient_mode == MARKER_ORIENT_AUTO) { - m = base; - } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { - m = Geom::Rotate::from_degrees( 180.0 ) * base; - m = base; - } else { - /* fixme: Orient units (Lauris) */ - m = Geom::Rotate::from_degrees(marker->orient); - m *= Geom::Translate(base.translation()); - } - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { - m = Geom::Scale(linewidth) * m; - } - v->items[pos]->setTransform(m); - } - return v->items[pos]; + std::map<unsigned int, SPMarkerView>::iterator it = marker->views_map.find(key); + if (it == marker->views_map.end()) { + // Key not found + return NULL; + } + + SPMarkerView *view = &(it->second); + if (pos >= view->items.size() ) { + // Position index too large, doesn't exist. + return NULL; + } + + // If not already created + if (view->items[pos] == NULL) { + + /* Parent class ::show method */ + view->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); + + if (view->items[pos]) { + /* fixme: Position (Lauris) */ + parent->prependChild(view->items[pos]); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(view->items[pos]); + if (g) g->setChildTransform(marker->c2p); + } + } + + if (view->items[pos]) { + Geom::Affine m; + if (marker->orient_mode == MARKER_ORIENT_AUTO) { + m = base; + } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + m = Geom::Rotate::from_degrees( 180.0 ) * base; + m = base; + } else { + /* fixme: Orient units (Lauris) */ + m = Geom::Rotate::from_degrees(marker->orient.computed); + m *= Geom::Translate(base.translation()); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + m = Geom::Scale(linewidth) * m; + } + view->items[pos]->setTransform(m); } - return NULL; + return view->items[pos]; } /** @@ -417,46 +424,10 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, void sp_marker_hide (SPMarker *marker, unsigned int key) { - SPMarkerView *v; - - v = marker->views; - while (v != NULL) { - SPMarkerView *next; - next = v->next; - if (v->key == key) { - /* Parent class ::hide method */ - marker->hide(key); - - sp_marker_view_remove (marker, v, TRUE); - return; - } - v = next; - } + marker->hide(key); + marker->views_map.erase(key); } -/** - * Removes a given view. Also will destroy sub-items in the view if destroyitems - * is set to a non-zero value. - */ -static void -sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems) -{ - if (view == marker->views) { - marker->views = view->next; - } else { - SPMarkerView *v; - for (v = marker->views; v->next != view; v = v->next) if (!v->next) return; - v->next = view->next; - } - if (destroyitems) { - for (unsigned int i = 0; i < view->items.size(); i++) { - /* We have to walk through the whole array because there may be hidden items */ - delete view->items[i]; - } - } - view->items.clear(); - delete view; -} const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move) { diff --git a/src/sp-marker.h b/src/sp-marker.h index b58523251..e804fd7dc 100644 --- a/src/sp-marker.h +++ b/src/sp-marker.h @@ -21,13 +21,16 @@ #define SP_MARKER(obj) (dynamic_cast<SPMarker*>((SPObject*)obj)) #define SP_IS_MARKER(obj) (dynamic_cast<const SPMarker*>((SPObject*)obj) != NULL) -struct SPMarkerView; +class SPMarkerView; + +#include <map> #include <2geom/rect.h> #include <2geom/affine.h> #include "enums.h" #include "svg/svg-length.h" +#include "svg/svg-angle.h" #include "sp-item-group.h" #include "uri-references.h" #include "viewbox.h" @@ -58,10 +61,15 @@ public: /* orient */ unsigned int orient_set : 1; markerOrient orient_mode : 2; - float orient; - - /* Private views */ - SPMarkerView *views; + SVGAngle orient; + + /* Private views indexed by key that corresponds to a + * particular marker type (start, mid, end) on a particular + * path. SPMarkerView is a wrapper for a vector of pointers to + * Inkscape::DrawingItem instances, one pointer for each + * rendered marker. + */ + std::map<unsigned int, SPMarkerView> views_map; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 8bfe23656..c1ead565f 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -32,7 +32,7 @@ * Authors: * Tavmjong Bah <tavmjong@free.fr> * - * Copyrigt (C) 2012 Tavmjong Bah + * Copyright (C) 2012, 2015 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -580,6 +580,47 @@ SPMeshNodeArray::SPMeshNodeArray( SPMeshGradient *mg ) { }; + +// Copy constructor +SPMeshNodeArray::SPMeshNodeArray( const SPMeshNodeArray& rhs ) { + + built = false; + mg = NULL; + drag_valid = false; + + nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. + + for( unsigned i=0; i < nodes.size(); ++i ) { + for( unsigned j=0; j < nodes[i].size(); ++j ) { + nodes[i][j] = new SPMeshNode( *rhs.nodes[i][j] ); // Copy data. + } + } +}; + + +// Copy assignment operator +SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { + + if( this == &rhs ) return *this; + + clear(); // Clear any existing array. + + built = false; + mg = NULL; + drag_valid = false; + + nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. + + for( unsigned i=0; i < nodes.size(); ++i ) { + for( unsigned j=0; j < nodes[i].size(); ++j ) { + nodes[i][j] = new SPMeshNode( *rhs.nodes[i][j] ); // Copy data. + } + } + + return *this; +}; + + void SPMeshNodeArray::read( SPMeshGradient *mg_in ) { mg = mg_in; @@ -1382,6 +1423,543 @@ void SPMeshNodeArray::print() { }; + +// Find the slopes at start and end for Hermite interpolation. +// Smooth using Hermite interpolation. +// Inputs are: +// pb: color value before patch +// p0: color value start of patch +// p1: color value end of patch +// pa: color value after patch +// is_first: If first patch in row/column +// is_last: If last patch in row/column +// type: Type smoothing +// Output: +// m0: slope of Hermite function at start. +// m1: slope of Hermite function at end. +void find_slopes( const double &pb, const double &p0, const double &p1, const double &pa, + const bool &is_first, const bool &is_last, const SPMeshSmooth type, + double &m0, double &m1 ) { + + // We use Hermite interpolation. We have end points, we need tangents. + + // Try various ways of finding tangents m0, m1 + + // Default to Catmul-Rom (assumes pb and pa already calculatedd) + m0 = (p1 - pb)/2.0; + m1 = (pa - p0)/2.0; + + bool parabolic = false; // Require end patches to be parabolic + switch (type) { + case SP_MESH_SMOOTH_SMOOTH1: + // Flat + m0 = 0.0; + m1 = 0.0; + break; + case SP_MESH_SMOOTH_SMOOTH2: + // Catmul-Rom, standard end treatment. Double first/last point. + if( is_first ) { + m0 = (p1-p0)/2.0; + } + if( is_last ) { + m1 = (p1-p0)/2.0; + } + break; + case SP_MESH_SMOOTH_SMOOTH3: + // Catmul-Rom, standard end treatment. Reflect first/last point. + if( is_first ) { + m0 = (p1-p0); + } + if( is_last ) { + m1 = (p1-p0); + } + break; + case SP_MESH_SMOOTH_SMOOTH4: + // Catmul-Rom, Parabolic ends + parabolic = true; + break; + case SP_MESH_SMOOTH_SMOOTH: + case SP_MESH_SMOOTH_SMOOTH5: + // Catmul-Rom, Parabolic ends, no color min/max in middle of patch. + parabolic = true; + + if( (pb > p0 && p1 > p0) || + (pb < p0 && p1 < p0) ) { + // tangents flat at min/max + m0 = 0; + } else { + // ensure we don't overshoot + if( fabs(m0) > fabs(3*(p1-p0)) ) { + m0 = 3*(p1-p0); + } + if( fabs(m0) > fabs(3*(p0-pb)) ) { + m0 = 3*(p0-pb); + } + } + if( (p0 > p1 && pa > p1) || + (p0 < p1 && pa < p1) ) { + // tangents flat at min/max + m1 = 0; + } else { + // ensure we don't overshoot + if( fabs(m1) > fabs(3*(pa-p1)) ) { + m1 = 3*(pa-p1); + } + if( fabs(m1) > fabs(3*(p1-p0)) ) { + m1 = 3*(p1-p0); + } + } + break; + case SP_MESH_SMOOTH_NONE: + default: + std::cerr << "find_slopes() Invalid smoothing type." << std::endl; + break; + } + + // Force end patches to be parabolic + if( parabolic ) { + if( is_first ) { + // Constraint for parabola + m0 = 2.0*(p1-p0) - m1; + if ( ((p1-p0) < 0 && m0 > 0) || ((p1-p0) > 0 && m0 < 0 ) ) { + m0 = 0; // Prevent overshooting start value; + } + } else if( is_last ) { + // Constraint for parabola + m1 = 2.0*(p1-p0) - m0; + if ( ((p1-p0) < 0 && m1 > 0) || ((p1-p0) > 0 && m1 < 0 ) ) { + m1 = 0; // Prevent overshooting end value; + } + } + } + + // std::cout << " pb: " << pb + // << " p0: " << p0 + // << " p1: " << p1 + // << " pa: " << pa + // << " m0: " << m0 + // << " m1: " << m1 << std::endl; +} + +double hermite( const double p0, const double p1, const double m0, const double m1, const double t ) { + double t2 = t*t; + double t3 = t2*t; + + double result = (2.0*t3 - 3.0*t2 +1.0) * p0 + + (t3 - 2.0*t2 + t) * m0 + + (-2.0*t3 + 3.0*t2) * p1 + + (t3 -t2) * m1; + + return result; +} + + +/** + Fill 'smooth' with a smoothed version of the array by subdividing each patch into smaller patches. +*/ +void SPMeshNodeArray::smooth( SPMeshNodeArray* smooth, SPMeshSmooth type ) { + + *smooth = *this; // Deep copy via copy assignment constructor, smooth cleared before copy + // std::cout << "SPMeshNodeArray::smooth(): " << this->patch_rows() << " " << smooth->patch_rows() << std::endl; + // std::cout << " " << smooth << " " << this << std::endl; + // Next split each patch into 8x8 smaller patches. + + // Do rows first. + + // Split each row into eight rows. + // Must do it from end so inserted rows don't mess up indexing + for( int i = smooth->patch_rows() - 1; i >= 0; --i ) { + smooth->split_row( i, unsigned(8) ); + } + + // Update color values (every third node is a corner) + for( unsigned i = 0; i < this->patch_rows(); ++i ) { // i is orignal patch index + + bool is_first_row = (i == 0); + bool is_last_row = (i == this->patch_rows() - 1 ); + //std::cout << " last row: " << smooth->patch_rows()/8 - 1 << " " << is_last_row << std::endl; + for( unsigned j = 0; j < smooth->patch_columns()+1; ++j ) { // j is smooth patch index + + // Can't use guint32 since delta can be negative + float pb[3]; // Point before patch + float p0[3]; // Point at start of patch + float p1[3]; // Point at end of patch + float pa[3]; // Point after patch + float result[3][8]; + sp_color_get_rgb_floatv( &this->nodes[ i *3 ][ j*3 ]->color, p0 ); + sp_color_get_rgb_floatv( &this->nodes[ (i+1)*3 ][ j*3 ]->color, p1 ); + if( !is_first_row ) { + sp_color_get_rgb_floatv( &this->nodes[ (i-1)*3 ][ j*3 ]->color, pb ); + } else { + pb[0] = 2.0*p0[0] - p1[0]; + pb[1] = 2.0*p0[1] - p1[1]; + pb[2] = 2.0*p0[2] - p1[2]; + } + if( !is_last_row ) { + sp_color_get_rgb_floatv( &this->nodes[ (i+2)*3 ][ j*3 ]->color, pa ); + } else { + pa[0] = 2.0*p1[0] - p0[0]; + pa[1] = 2.0*p1[1] - p0[1]; + pa[2] = 2.0*p1[2] - p0[2]; + } + + for( unsigned n = 0; n < 3; ++n ) { // Loop over colors + + // We use Hermite interpolation. We have end points, we need tangents. + double m0 = 0; + double m1 = 0; + find_slopes( pb[n], p0[n], p1[n], pa[n], is_first_row, is_last_row, type, m0, m1 ); + + for( unsigned k = 1; k < 8; ++k ) { + double t = k/8.0; + // Cubic Hermite (four constraints) + result[n][k] = hermite( p0[n], p1[n], m0, m1, t ); + // Clamp to allowed values + if( result[n][k] > 1.0 ) + result[n][k] = 1.0; + if( result[n][k] < 0.0 ) + result[n][k] = 0.0; + } + } + + for( unsigned k = 1; k < 8; ++k ) { + smooth->nodes[ (i*8+k)*3 ][ j*3 ]->color.set( result[0][k], result[1][k], result[2][k] ); + } + } + } + + // Split each column into eight columns. + // Must do it from end so inserted columns don't mess up indexing + for( int i = smooth->patch_columns() - 1; i >= 0; --i ) { + smooth->split_column( i, (unsigned)8 ); + } + + // Update color values (every third node is a corner) + for( unsigned i = 0; i < this->patch_columns(); ++i ) { // i is orignal patch index + + bool is_first_column = (i == 0); + bool is_last_column = (i == this->patch_columns() - 1 ); + //std::cout << " last column: " << smooth->patch_columns()/8 - 1 << " " << is_last_column << std::endl; + for( unsigned j = 0; j < smooth->patch_rows()+1; ++j ) { // j is smooth patch index + + // Can't use guint32 since delta can be negative + float pb[3]; // Point before patch + float p0[3]; // Point at start of patch + float p1[3]; // Point at end of patch + float pa[3]; // Point after patch + float result[3][8]; + sp_color_get_rgb_floatv( &smooth->nodes[ j*3 ][ i *3*8 ]->color, p0 ); + sp_color_get_rgb_floatv( &smooth->nodes[ j*3 ][ (i+1)*3*8 ]->color, p1 ); + if( !is_first_column ) { + sp_color_get_rgb_floatv( &smooth->nodes[ j*3 ][ (i-1)*3*8 ]->color, pb ); + } else { + pb[0] = 2.0*p0[0] - p1[0]; + pb[1] = 2.0*p0[1] - p1[1]; + pb[2] = 2.0*p0[2] - p1[2]; + } + if( !is_last_column ) { + sp_color_get_rgb_floatv( &smooth->nodes[ j*3 ][ (i+2)*3*8 ]->color, pa ); + } else { + pa[0] = 2.0*p1[0] - p0[0]; + pa[1] = 2.0*p1[1] - p0[1]; + pa[2] = 2.0*p1[2] - p0[2]; + } + + for( unsigned n = 0; n < 3; ++n ) { // Loop over colors + + // We use Hermite interpolation. We have end points, we need tangents. + double m0 = 0; + double m1 = 0; + find_slopes( pb[n], p0[n], p1[n], pa[n], is_first_column, is_last_column, type, m0, m1 ); + + for( unsigned k = 1; k < 8; ++k ) { + double t = k/8.0; + // Cubic Hermite (four constraints) + result[n][k] = hermite( p0[n], p1[n], m0, m1, t ); + // Clamp to allowed values + if( result[n][k] > 1.0 ) + result[n][k] = 1.0; + if( result[n][k] < 0.0 ) + result[n][k] = 0.0; + } + } + + for( unsigned k = 1; k < 8; ++k ) { + smooth->nodes[ j*3 ][ (i*8+k)*3 ]->color.set( result[0][k], result[1][k], result[2][k] ); + } + } + } +} + +class SPMeshSmoothCorner { + +public: + SPMeshSmoothCorner() { + for( unsigned i = 0; i < 3; ++i ) { + for( unsigned j = 0; j < 4; ++j ) { + g[i][j] = 0; + } + } + } + + double g[3][4]; // 3 colors, 4 parameters: f, f_x, f_y, f_xy + // double x[4]; // Lengths between neigboring points x, y, xy, yx +}; + +// Find slope at point 1 given values at previous and next points +double find_slope1( double p0, double p1, double p2 ) { + + double slope = (p2 - p0)/2.0; // Simple Catmul-Rom condition + if( ( p0 > p1 && p1 < p2 ) || + ( p0 < p1 && p1 > p2 ) ) { + // At minimum or maximum, use slope of zero + slope = 0; + } else { + // Ensure we don't overshoot + if( fabs(slope) > fabs(3*(p1-p0)) ) { + slope = 3*(p1-p0); + } + if( fabs(slope) > fabs(3*(p2-p1)) ) { + slope = 3*(p2-p1); + } + } + return slope; +}; + + +// Find slope at point 0 given values at previous and next points +double find_slope2( double pmm, double ppm, double pmp, double ppp, double p0 ) { + + // pmm == d[i-1][j-1], ... 'm' is minus, 'p' is plus + double slope = (ppp - ppm - pmp + pmm)/2.0; + if( (ppp > p0 && ppm > p0 && pmp > p0 && pmm > 0) || + (ppp < p0 && ppm < p0 && pmp < p0 && pmm < 0) ) { + // At minimum or maximum, use slope of zero + slope = 0; + } else { + // Don't really know what to do here + if( fabs(slope) > fabs(3*(ppp-p0)) ) { + slope = 3*(ppp-p0); + } + if( fabs(slope) > fabs(3*(pmp-p0)) ) { + slope = 3*(pmp-p0); + } + if( fabs(slope) > fabs(3*(ppm-p0)) ) { + slope = 3*(ppm-p0); + } + if( fabs(slope) > fabs(3*(pmm-p0)) ) { + slope = 3*(pmm-p0); + } + } + return slope; +} + +// https://en.wikipedia.org/wiki/Bicubic_interpolation +void invert( const double v[16], double alpha[16] ) { + + const double A[16][16] = { + + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + {-3, 3, 0, 0, -2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2,-2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, -2,-1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0 }, + {-3, 0, 3, 0, 0, 0, 0, 0, -2, 0,-1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0, -2, 0,-1, 0 }, + { 9,-9,-9, 9, 6, 3,-6,-3, 6,-6, 3,-3, 4, 2, 2, 1 }, + {-6, 6, 6,-6, -3,-3, 3, 3, -4, 4,-2, 2, -2,-2,-1,-1 }, + { 2, 0,-2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, + {-6, 6, 6,-6, -4,-2, 4, 2, -3, 3,-3, 3, -2,-1,-2,-1 }, + { 4,-4,-4, 4, 2, 2,-2,-2, 2,-2, 2,-2, 1, 1, 1, 1 } + }; + + for( unsigned i = 0; i < 16; ++i ) { + alpha[i] = 0; + for( unsigned j = 0; j < 16; ++j ) { + alpha[i] += A[i][j]*v[j]; + } + } +} + +double sum( const double alpha[16], const double& x, const double& y ) { + + double result = 0; + + double xx = x*x; + double xxx = xx * x; + double yy = y*y; + double yyy = yy * y; + + result += alpha[ 0 ]; + result += alpha[ 1 ] * x; + result += alpha[ 2 ] * xx; + result += alpha[ 3 ] * xxx; + result += alpha[ 4 ] * y; + result += alpha[ 5 ] * y * x; + result += alpha[ 6 ] * y * xx; + result += alpha[ 7 ] * y * xxx; + result += alpha[ 8 ] * yy; + result += alpha[ 9 ] * yy * x; + result += alpha[ 10 ] * yy * xx; + result += alpha[ 11 ] * yy * xxx; + result += alpha[ 12 ] * yyy; + result += alpha[ 13 ] * yyy * x; + result += alpha[ 14 ] * yyy * xx; + result += alpha[ 15 ] * yyy * xxx; + + return result; +} + +/** + Fill 'smooth' with a smoothed version of the array by subdividing each patch into smaller patches. +*/ +void SPMeshNodeArray::smooth2( SPMeshNodeArray* smooth, SPMeshSmooth type ) { + + + *smooth = *this; // Deep copy via copy assignment constructor, smooth cleared before copy + // std::cout << "SPMeshNodeArray::smooth2(): " << this->patch_rows() << " " << smooth->patch_columns() << std::endl; + // std::cout << " " << smooth << " " << this << std::endl; + + // Find derivatives at corners + + // Create array of corner points + std::vector< std::vector <SPMeshSmoothCorner> > d; + d.resize( smooth->patch_rows() + 1 ); + for( unsigned i = 0; i < d.size(); ++i ) { + d[i].resize( smooth->patch_columns() + 1 ); + for( unsigned j = 0; j < d[i].size(); ++j ) { + float rgb_color[3]; + sp_color_get_rgb_floatv( &this->nodes[ i*3 ][ j*3 ]->color, rgb_color ); + d[i][j].g[0][0] = rgb_color[ 0 ]; + d[i][j].g[1][0] = rgb_color[ 1 ]; + d[i][j].g[2][0] = rgb_color[ 2 ]; + } + } + + // Calculate interior derivatives + for( unsigned i = 1; i < d.size()-1; ++i ) { + for( unsigned j = 1; j < d[i].size()-1; ++j ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + if( type == SP_MESH_SMOOTH_SMOOTH7 || type == SP_MESH_SMOOTH_SMOOTH ) { + d[i][j].g[k][1] = find_slope1( d[i-1][j].g[k][0], d[i][j].g[k][0], d[i+1][j].g[k][0] ); + d[i][j].g[k][2] = find_slope1( d[i][j-1].g[k][0], d[i][j].g[k][0], d[i][j+1].g[k][0] ); + d[i][j].g[k][3] = find_slope2( d[i-1][j-1].g[k][0], d[i+1][j-1].g[k][0], + d[i-1][j+1].g[k][0], d[i-1][j-1].g[k][0], + d[i][j].g[k][0] ); + } else { + // Catmul-Rom + d[i][j].g[k][1] = (d[i+1][j].g[k][0] - d[i-1][j].g[k][0])/2.0; + d[i][j].g[k][2] = (d[i][j+1].g[k][0] - d[i][j-1].g[k][0])/2.0; + } + } + } + } + + // Calculate exterior derivatives + for( unsigned j = 1; j< d[0].size()-1; ++j ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + unsigned z = d.size()-1; + if( type == SP_MESH_SMOOTH_SMOOTH7 || type == SP_MESH_SMOOTH_SMOOTH ) { + // Parabolic + d[0][j].g[k][1] = 2.0*(d[1][j].g[k][0] - d[0 ][j].g[k][0]) - d[1][j].g[k][1]; + d[z][j].g[k][1] = 2.0*(d[z][j].g[k][0] - d[z-1][j].g[k][0]) - d[z][j].g[k][1]; + } else { + // Catmul-Rom + d[0][j].g[k][1] = (d[1][j].g[k][0] - d[0 ][j].g[k][0])/2.0; + d[z][j].g[k][1] = (d[z][j].g[k][0] - d[z-1][j].g[k][0])/2.0; + } + } + } + + for( unsigned i = 1; i< d.size()-1; ++i ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + unsigned z = d[0].size()-1; + if( type == SP_MESH_SMOOTH_SMOOTH7 || type == SP_MESH_SMOOTH_SMOOTH ) { + // Parabolic + d[i][0].g[k][2] = 2.0*(d[i][1].g[k][0] - d[i][0 ].g[k][0]) - d[i][0].g[k][1]; + d[i][z].g[k][2] = 2.0*(d[i][z].g[k][0] - d[i][z-1].g[k][0]) - d[i][z].g[k][1]; + } else { + // Catmul-Rom + d[i][0].g[k][2] = (d[i][1].g[k][0] - d[i][0 ].g[k][0])/2.0; + d[i][z].g[k][2] = (d[i][z].g[k][0] - d[i][z-1].g[k][0])/2.0; + } + } + } + + // Leave outside corner derivatives at zero. + + // Next split each patch into 8x8 smaller patches. + + // Split each row into eight rows. + // Must do it from end so inserted rows don't mess up indexing + for( int i = smooth->patch_rows() - 1; i >= 0; --i ) { + smooth->split_row( i, unsigned(8) ); + } + + // Split each column into eight columns. + // Must do it from end so inserted columns don't mess up indexing + for( int i = smooth->patch_columns() - 1; i >= 0; --i ) { + smooth->split_column( i, (unsigned)8 ); + } + + // Fill new patches + for( unsigned i = 0; i < this->patch_rows(); ++i ) { + for( unsigned j = 0; j < this->patch_columns(); ++j ) { + + // Temp loop over 0..8 to get last column/row edges + float r[3][9][9]; // result + for( unsigned m = 0; m < 3; ++m ) { + + double v[16]; + v[ 0] = d[i ][j ].g[m][0]; + v[ 1] = d[i+1][j ].g[m][0]; + v[ 2] = d[i ][j+1].g[m][0]; + v[ 3] = d[i+1][j+1].g[m][0]; + v[ 4] = d[i ][j ].g[m][1]; + v[ 5] = d[i+1][j ].g[m][1]; + v[ 6] = d[i ][j+1].g[m][1]; + v[ 7] = d[i+1][j+1].g[m][1]; + v[ 8] = d[i ][j ].g[m][2]; + v[ 9] = d[i+1][j ].g[m][2]; + v[10] = d[i ][j+1].g[m][2]; + v[11] = d[i+1][j+1].g[m][2]; + v[12] = d[i ][j ].g[m][3]; + v[13] = d[i+1][j ].g[m][3]; + v[14] = d[i ][j+1].g[m][3]; + v[15] = d[i+1][j+1].g[m][3]; + + double alpha[16]; + invert( v, alpha ); + + for( unsigned k = 0; k < 9; ++k ) { + for( unsigned l = 0; l < 9; ++l ) { + double x = k/8.0; + double y = l/8.0; + r[m][k][l] = sum( alpha, x, y ); + // Clamp to allowed values + if( r[m][k][l] > 1.0 ) + r[m][k][l] = 1.0; + if( r[m][k][l] < 0.0 ) + r[m][k][l] = 0.0; + } + } + + } // Loop over colors + + for( unsigned k = 0; k < 9; ++k ) { + for( unsigned l = 0; l < 9; ++l ) { + // Every third node is a corner node + smooth->nodes[ (i*8+k)*3 ][(j*8+l)*3 ]->color.set( r[0][k][l], r[1][k][l], r[2][k][l] ); + } + } + } + } +} + /** Number of patch rows. */ diff --git a/src/sp-mesh-array.h b/src/sp-mesh-array.h index 330f6d87b..19f8634f8 100644 --- a/src/sp-mesh-array.h +++ b/src/sp-mesh-array.h @@ -45,6 +45,18 @@ // For color picking #include "sp-item.h" +enum SPMeshSmooth { + SP_MESH_SMOOTH_NONE, + SP_MESH_SMOOTH_SMOOTH, + SP_MESH_SMOOTH_SMOOTH1, + SP_MESH_SMOOTH_SMOOTH2, + SP_MESH_SMOOTH_SMOOTH3, + SP_MESH_SMOOTH_SMOOTH4, + SP_MESH_SMOOTH_SMOOTH5, + SP_MESH_SMOOTH_SMOOTH6, + SP_MESH_SMOOTH_SMOOTH7 +}; + enum NodeType { MG_NODE_TYPE_UNKNOWN, MG_NODE_TYPE_CORNER, @@ -148,6 +160,9 @@ public: SPMeshNodeArray() { built = false; mg = NULL; drag_valid = false; }; SPMeshNodeArray( SPMeshGradient *mg ); + SPMeshNodeArray( const SPMeshNodeArray& rhs ); + SPMeshNodeArray& operator=(const SPMeshNodeArray& rhs); + ~SPMeshNodeArray() { clear(); }; bool built; @@ -157,6 +172,10 @@ public: void clear(); void print(); + // Fill 'smooth' with a smoothed version by subdividing each patch. + void smooth( SPMeshNodeArray* smooth, SPMeshSmooth type); + void smooth2( SPMeshNodeArray* smooth, SPMeshSmooth type); + // Get size of patch unsigned int patch_rows(); unsigned int patch_columns(); diff --git a/src/sp-mesh-gradient.cpp b/src/sp-mesh-gradient.cpp index bf28164a9..65fbe2e46 100644 --- a/src/sp-mesh-gradient.cpp +++ b/src/sp-mesh-gradient.cpp @@ -21,7 +21,7 @@ namespace { * Mesh Gradient */ //#define MESH_DEBUG -SPMeshGradient::SPMeshGradient() : SPGradient() { +SPMeshGradient::SPMeshGradient() : SPGradient(), smooth(SP_MESH_SMOOTH_NONE), smooth_set(false) { // Start coordinate of mesh this->x.unset(SVGLength::NONE, 0.0, 0.0); this->y.unset(SVGLength::NONE, 0.0, 0.0); @@ -36,6 +36,8 @@ void SPMeshGradient::build(SPDocument *document, Inkscape::XML::Node *repr) { // Start coordinate of mesh this->readAttr( "x" ); this->readAttr( "y" ); + + this->readAttr( "smooth" ); } @@ -57,6 +59,39 @@ void SPMeshGradient::set(unsigned key, gchar const *value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_SMOOTH: + if (value) { + if (!strcmp(value, "none")) { + this->smooth = SP_MESH_SMOOTH_NONE; + } else if (!strcmp(value, "smooth")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH; + } else if (!strcmp(value, "smooth1")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH1; + } else if (!strcmp(value, "smooth2")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH2; + } else if (!strcmp(value, "smooth3")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH3; + } else if (!strcmp(value, "smooth4")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH4; + } else if (!strcmp(value, "smooth5")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH5; + } else if (!strcmp(value, "smooth6")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH6; + } else if (!strcmp(value, "smooth7")) { + this->smooth = SP_MESH_SMOOTH_SMOOTH7; + } else { + std::cout << "SPMeshGradient::set(): invalid value " << value << std::endl; + } + this->smooth_set = TRUE; + } else { + std::cout << "SPMeshGradient::set() No value " << std::endl; + this->smooth = SP_MESH_SMOOTH_NONE; + this->smooth_set = FALSE; + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + default: SPGradient::set(key, value); break; @@ -83,6 +118,41 @@ Inkscape::XML::Node* SPMeshGradient::write(Inkscape::XML::Document *xml_doc, Ink sp_repr_set_svg_double(repr, "y", this->y.computed); } + if ((flags & SP_OBJECT_WRITE_ALL) || this->smooth_set) { + switch (this->smooth) { + case SP_MESH_SMOOTH_SMOOTH: + repr->setAttribute("smooth", "smooth"); + break; + case SP_MESH_SMOOTH_SMOOTH1: + repr->setAttribute("smooth", "smooth1"); + break; + case SP_MESH_SMOOTH_SMOOTH2: + repr->setAttribute("smooth", "smooth2"); + break; + case SP_MESH_SMOOTH_SMOOTH3: + repr->setAttribute("smooth", "smooth3"); + break; + case SP_MESH_SMOOTH_SMOOTH4: + repr->setAttribute("smooth", "smooth4"); + break; + case SP_MESH_SMOOTH_SMOOTH5: + repr->setAttribute("smooth", "smooth5"); + break; + case SP_MESH_SMOOTH_SMOOTH6: + repr->setAttribute("smooth", "smooth6"); + break; + case SP_MESH_SMOOTH_SMOOTH7: + repr->setAttribute("smooth", "smooth7"); + break; + case SP_MESH_SMOOTH_NONE: + repr->setAttribute("smooth", "none"); + break; + default: + // Do nothing + break; + } + } + SPGradient::write(xml_doc, repr, flags); return repr; @@ -117,14 +187,38 @@ cairo_pattern_t* SPMeshGradient::pattern_new(cairo_t * /*ct*/, cairo_pattern_t *cp = NULL; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4) - SPMeshNodeArray* array = &(this->array); + SPMeshNodeArray* my_array = &array; + + if( smooth_set ) { + switch (smooth) { + case SP_MESH_SMOOTH_NONE: + // std::cout << "SPMeshGradient::pattern_new: no smoothing" << std::endl; + break; + case SP_MESH_SMOOTH_SMOOTH1: + case SP_MESH_SMOOTH_SMOOTH2: + case SP_MESH_SMOOTH_SMOOTH3: + case SP_MESH_SMOOTH_SMOOTH4: + case SP_MESH_SMOOTH_SMOOTH5: + // std::cout << "SPMeshGradient::pattern_new: calling array.smooth" << std::endl; + array.smooth( &array_smoothed, smooth ); + my_array = &array_smoothed; + break; + case SP_MESH_SMOOTH_SMOOTH: + case SP_MESH_SMOOTH_SMOOTH6: + case SP_MESH_SMOOTH_SMOOTH7: + // std::cout << "SPMeshGradient::pattern_new: calling array.smooth2" << std::endl; + array.smooth2( &array_smoothed, smooth ); + my_array = &array_smoothed; + break; + } + } cp = cairo_pattern_create_mesh(); - for( unsigned int i = 0; i < array->patch_rows(); ++i ) { - for( unsigned int j = 0; j < array->patch_columns(); ++j ) { + for( unsigned int i = 0; i < my_array->patch_rows(); ++i ) { + for( unsigned int j = 0; j < my_array->patch_columns(); ++j ) { - SPMeshPatchI patch( &(array->nodes), i, j ); + SPMeshPatchI patch( &(my_array->nodes), i, j ); cairo_mesh_pattern_begin_patch( cp ); cairo_mesh_pattern_move_to( cp, patch.getPoint( 0, 0 )[X], patch.getPoint( 0, 0 )[Y] ); diff --git a/src/sp-mesh-gradient.h b/src/sp-mesh-gradient.h index 4df753f62..343cae840 100644 --- a/src/sp-mesh-gradient.h +++ b/src/sp-mesh-gradient.h @@ -19,7 +19,8 @@ public: SVGLength x; // Upper left corner of mesh SVGLength y; // Upper right corner of mesh - + SPMeshSmooth smooth; + bool smooth_set; virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); protected: diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 8b28347f1..dc36e68b9 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -29,7 +29,7 @@ #include "document.h" #include "document-undo.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "sp-guide.h" #include "sp-item-group.h" #include "sp-namedview.h" @@ -72,11 +72,13 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->guidehicolor = 0; this->views = NULL; this->borderlayer = 0; - this->units = NULL; + this->page_size_units = NULL; this->window_x = 0; this->cy = 0; this->window_y = 0; - this->doc_units = NULL; + this->svg_units = unit_table.getUnit("px"); // legacy behavior: if no viewbox present, default to 'px' units + this->display_units = NULL; + this->page_size_units = NULL; this->pagecolor = 0; this->cx = 0; this->pageshadow = 0; @@ -262,6 +264,14 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { // backwards compatibility with grid settings (pre 0.46) sp_namedview_generate_old_grid(this, document, repr); + + // If viewbox defined: try to calculate the SVG unit from document width and viewbox + if (document->getRoot()->viewBox_set) { + Inkscape::Util::Quantity svgwidth = document->getWidth(); + Geom::Rect viewbox = document->getRoot()->viewBox; + double factor = svgwidth.value(unit_table.primary(Inkscape::Util::UNIT_TYPE_LINEAR)) / viewbox.width(); + svg_units = unit_table.findUnit(factor, Inkscape::Util::UNIT_TYPE_LINEAR); + } } void SPNamedView::release() { @@ -540,22 +550,13 @@ void SPNamedView::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_INKSCAPE_DOCUMENT_UNITS: { - /* The default unit if the document doesn't override this: e.g. for files saved as + /* The default display unit if the document doesn't override this: e.g. for files saved as * `plain SVG', or non-inkscape files, or files created by an inkscape 0.40 & * earlier. * - * Here we choose `px': useful for screen-destined SVGs, and fewer bug reports - * about "not the same numbers as what's in the SVG file" (at least for documents - * without a viewBox attribute on the root <svg> element). Similarly, it's also - * the most reliable unit (i.e. least likely to be wrong in different viewing - * conditions) for viewBox-less SVG files given that it's the unit that inkscape - * uses for all coordinates. + * Note that these units are not the same as the units used for the values in SVG! * - * For documents that do have a viewBox attribute on the root <svg> element, it - * might be better if we used either viewBox coordinates or if we used the unit of - * say the width attribute of the root <svg> element. However, these pose problems - * in that they aren't in general absolute units as currently required by - * doc_units. + * We default to `px'. */ static Inkscape::Util::Unit const *px = unit_table.getUnit("px"); Inkscape::Util::Unit const *new_unit = px; @@ -576,11 +577,12 @@ void SPNamedView::set(unsigned int key, const gchar* value) { /* fixme: Don't use g_log (see above). */ } } - this->doc_units = new_unit; + this->display_units = new_unit; this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } case SP_ATTR_UNITS: { + // Only used in "Custom size" section of Document Properties dialog Inkscape::Util::Unit const *new_unit = NULL; if (value) { @@ -599,7 +601,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { /* fixme: Don't use g_log (see above). */ } } - this->units = new_unit; + this->page_size_units = new_unit; this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } @@ -674,7 +676,7 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r g->SPGuide::showSPGuide(static_cast<SPDesktop*>(l->data)->guides, (GCallback) sp_dt_guide_event); if (static_cast<SPDesktop*>(l->data)->guides_active) { - g->sensitize(sp_desktop_canvas(static_cast<SPDesktop*> (l->data)), TRUE); + g->sensitize((static_cast<SPDesktop*> (l->data))->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides); @@ -732,7 +734,7 @@ void SPNamedView::show(SPDesktop *desktop) for (GSList *l = guides; l != NULL; l = l->next) { SP_GUIDE(l->data)->showSPGuide( desktop->guides, (GCallback) sp_dt_guide_event); if (desktop->guides_active) { - SP_GUIDE(l->data)->sensitize(sp_desktop_canvas(desktop), TRUE); + SP_GUIDE(l->data)->sensitize(desktop->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(l->data), showguides); } @@ -838,7 +840,7 @@ void sp_namedview_window_from_document(SPDesktop *desktop) && nv->cx != HUGE_VAL && !IS_NAN(nv->cx) && nv->cy != HUGE_VAL && !IS_NAN(nv->cy)) { desktop->zoom_absolute(nv->cx, nv->cy, nv->zoom); - } else if (sp_desktop_document(desktop)) { // document without saved zoom, zoom to its page + } else if (desktop->getDocument()) { // document without saved zoom, zoom to its page desktop->zoom_page(); } @@ -898,8 +900,8 @@ void sp_namedview_document_from_window(SPDesktop *desktop) Geom::Rect const r = desktop->get_display_area(); // saving window geometry is not undoable - bool saved = DocumentUndo::getUndoSensitive(sp_desktop_document(desktop)); - DocumentUndo::setUndoSensitive(sp_desktop_document(desktop), false); + bool saved = DocumentUndo::getUndoSensitive(desktop->getDocument()); + DocumentUndo::setUndoSensitive(desktop->getDocument(), false); if (save_viewport_in_file) { sp_repr_set_svg_double(view, "inkscape:zoom", desktop->current_zoom()); @@ -920,7 +922,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop) view->setAttribute("inkscape:current-layer", desktop->currentLayer()->getId()); // restore undoability - DocumentUndo::setUndoSensitive(sp_desktop_document(desktop), saved); + DocumentUndo::setUndoSensitive(desktop->getDocument(), saved); } void SPNamedView::hide(SPDesktop const *desktop) @@ -929,7 +931,7 @@ void SPNamedView::hide(SPDesktop const *desktop) g_assert(g_slist_find(views, desktop)); for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->hideSPGuide(sp_desktop_canvas(desktop)); + SP_GUIDE(l->data)->hideSPGuide(desktop->getCanvas()); } views = g_slist_remove(views, desktop); @@ -943,7 +945,7 @@ void SPNamedView::activateGuides(void* desktop, bool active) SPDesktop *dt = static_cast<SPDesktop*>(desktop); for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->sensitize( sp_desktop_canvas(dt), active); + SP_GUIDE(l->data)->sensitize(dt->getCanvas(), active); } } @@ -1128,11 +1130,17 @@ double SPNamedView::getMarginLength(gchar const * const key, /** * Returns namedview's default unit. - * If no default unit is set, "pt" is returned + * If no default unit is set, "px" is returned */ -Inkscape::Util::Unit const * SPNamedView::getDefaultUnit() const +Inkscape::Util::Unit const * SPNamedView::getDisplayUnit() const +{ + return display_units ? display_units : unit_table.getUnit("px"); +} + +Inkscape::Util::Unit const & SPNamedView::getSVGUnit() const { - return doc_units ? doc_units : unit_table.getUnit("pt"); + assert(svg_units); + return *svg_units; } /** diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 37310dc76..f1ecc12d3 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -61,8 +61,9 @@ public: GSList * grids; bool grids_visible; - Inkscape::Util::Unit const *doc_units; - Inkscape::Util::Unit const *units; + Inkscape::Util::Unit const *svg_units; // Units used for the values in SVG + Inkscape::Util::Unit const *display_units; // Units used for the UI (*not* the same as units of SVG coordinates) + Inkscape::Util::Unit const *page_size_units; // Only used in "Custom size" part of Document Properties dialog GQuark default_layer_id; @@ -85,7 +86,8 @@ public: char const *getName() const; unsigned int getViewCount(); GSList const *getViewList() const; - Inkscape::Util::Unit const * getDefaultUnit() const; + Inkscape::Util::Unit const * getDisplayUnit() const; + Inkscape::Util::Unit const & getSVGUnit() const; void translateGuides(Geom::Translate const &translation); void translateGrids(Geom::Translate const &translation); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index fcff43aa5..7d24a978e 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -130,7 +130,8 @@ SPObject::SPObject() // vg, g, defs, desc, title, symbol, use, image, switch, path, rect, circle, ellipse, line, polyline, // polygon, text, tspan, tref, textPath, altGlyph, glyphRef, marker, linearGradient, radialGradient, // stop, pattern, clipPath, mask, filter, feImage, a, font, glyph, missing-glyph, foreignObject - this->style = sp_style_new_from_object(this); + this->style = new SPStyle( NULL, this ); // Is it necessary to call with "this"? + this->context_style = NULL; } SPObject::~SPObject() { @@ -144,6 +145,24 @@ SPObject::~SPObject() { sp_object_unref(this->_successor, NULL); this->_successor = NULL; } + + if( style == NULL ) { + // style pointer could be NULL if unreffed too many times. + // Conjecture: style pointer is never NULL. + std::cerr << "SPObject::~SPObject(): style pointer is NULL" << std::endl; + } else if( style->refCount() > 1 ) { + // Conjecture: style pointer should be unreffed by other classes before reaching here. + // Conjecture is false for SPTSpan where ref is held by InputStreamTextSource. + // As an additional note: + // The outer tspan of a nested tspan will result in a ref count of five: one for the + // TSpan itself, one for the InputStreamTextSource instance before the inner tspan and + // one for the one after, along with one for each corresponding DrawingText instance. + // std::cerr << "SPObject::~SPObject(): someone else still holding ref to style" << std::endl; + // + sp_style_unref( this->style ); + } else { + delete this->style; + } } // CPPIFY: make pure virtual @@ -406,9 +425,9 @@ void SPObject::requestOrphanCollection() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // do not remove style or script elements (Bug #276244) - if (SP_IS_STYLE_ELEM(this)) { + if (dynamic_cast<SPStyleElem *>(this)) { // leave it - } else if (SP_IS_SCRIPT(this)) { + } else if (dynamic_cast<SPScript *>(this)) { // leave it } else if ((! prefs->getBool("/options/cleanupswatches/value", false)) && SP_IS_PAINT_SERVER(this) && static_cast<SPPaintServer*>(this)->isSwatch() ) { @@ -795,9 +814,10 @@ void SPObject::releaseReferences() { g_assert(!this->id); } - if (this->style) { - this->style = sp_style_unref(this->style); - } + // style belongs to SPObject, we should not need to unref here. + // if (this->style) { + // this->style = sp_style_unref(this->style); + // } this->document = NULL; this->repr = NULL; @@ -914,7 +934,7 @@ void SPObject::set(unsigned int key, gchar const* value) { object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); break; case SP_ATTR_STYLE: - sp_style_read_from_object(object->style, object); + object->style->readFromObject( object ); object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); break; default: @@ -1006,9 +1026,8 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML repr->setAttribute("inkscape:collect", NULL); } - SPStyle const *const obj_style = this->style; - if (obj_style) { - gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET); + if (style) { + Glib::ustring s = style->write(SP_STYLE_FLAG_IFSET); // Check for valid attributes. This may be time consuming. // It is useful, though, for debugging Inkscape code. @@ -1016,17 +1035,14 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML if( prefs->getBool("/options/svgoutput/check_on_editing") ) { unsigned int flags = sp_attribute_clean_get_prefs(); - Glib::ustring s_cleaned = sp_attribute_clean_style( repr, s, flags ); - g_free( s ); - s = (s_cleaned.empty() ? NULL : g_strdup (s_cleaned.c_str())); + Glib::ustring s_cleaned = sp_attribute_clean_style( repr, s.c_str(), flags ); } - if( s == NULL || strcmp(s,"") == 0 ) { + if( s.empty() ) { repr->setAttribute("style", NULL); } else { - repr->setAttribute("style", s); + repr->setAttribute("style", s.c_str()); } - g_free(s); } else { /** \todo I'm not sure what to do in this case. Bug #1165868 @@ -1148,7 +1164,7 @@ void SPObject::updateDisplay(SPCtx *ctx, unsigned int flags) */ if ((flags & SP_OBJECT_STYLE_MODIFIED_FLAG) && (flags & SP_OBJECT_PARENT_MODIFIED_FLAG)) { if (this->style && this->parent) { - sp_style_merge_from_parent(this->style, this->parent->style); + style->cascade( this->parent->style ); } } @@ -1254,6 +1270,16 @@ void SPObject::setAttribute(gchar const *key, gchar const *value, SPException *e //XML Tree being used here. getRepr()->setAttribute(key, value, false); } +void SPObject::setAttribute(char const *key, Glib::ustring const &value, SPException *ex) +{ + setAttribute(key, value.empty() ? NULL : value.c_str(), ex); +} +void SPObject::setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex) +{ + setAttribute( key.empty() ? NULL : key.c_str(), + value.empty() ? NULL : value.c_str(), ex); +} + void SPObject::removeAttribute(gchar const *key, SPException *ex) { @@ -1513,6 +1539,22 @@ char* SPObject::textualContent() const return g_string_free(text, FALSE); } +// For debugging: Print SP tree structure. +void SPObject::recursivePrintTree( unsigned level ) +{ + if (level == 0) { + std::cout << "SP Object Tree" << std::endl; + } + std::cout << "SP: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + std::cout << (getId()?getId():"No object id") << std::endl; + for (SPObject *child = children; child; child = child->next) { + child->recursivePrintTree( level+1 ); + } +} + /* Local Variables: mode:c++ diff --git a/src/sp-object.h b/src/sp-object.h index 575198f36..ff80eaefc 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -67,6 +67,9 @@ struct Document; } } +namespace Glib { + class ustring; +} typedef enum { SP_NO_EXCEPTION, @@ -264,6 +267,11 @@ public: */ SPStyle *style; + /** + * Represents the style that should be used to resolve 'context-fill' and 'context-stroke' + */ + SPStyle *context_style; + /// Switch containing next() method. struct ParentIteratorStrategy { static SPObject const *next(SPObject const *object) { @@ -703,7 +711,9 @@ public: */ void setKeyValue(unsigned int key, char const *value); - void setAttribute(char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, Glib::ustring const &value, SPException *ex=NULL); + void setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex=NULL); /** * Read value of key attribute from XML node into object. @@ -849,6 +859,8 @@ protected: public: virtual void read_content(); + + void recursivePrintTree(unsigned level = 0); // For debugging }; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 5c076b7cb..0fef57698 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -41,7 +41,7 @@ #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "ui/tools/tool-base.h" #include "inkscape.h" diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 12570e03e..85582e209 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -375,6 +375,15 @@ Inkscape::DrawingItem *SPRoot::show(Inkscape::Drawing &drawing, unsigned int key g->setChildTransform(this->c2p); } + // Uncomment to print out XML tree + // getRepr()->recursivePrintTree(0); + + // Uncomment to print out SP Object tree + // recursivePrintTree(0); + + // Uncomment to print out Display Item tree + // ai->recursivePrintTree(0); + return ai; } diff --git a/src/sp-script.h b/src/sp-script.h index b71f86720..cdacb8493 100644 --- a/src/sp-script.h +++ b/src/sp-script.h @@ -6,6 +6,7 @@ * * Author: * Felipe C. da S. Sanches <juca@members.fsf.org> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2008 Author * @@ -15,9 +16,6 @@ #include "sp-object.h" #include "document.h" -#define SP_SCRIPT(obj) (dynamic_cast<SPScript*>((SPObject*)obj)) -#define SP_IS_SCRIPT(obj) (dynamic_cast<const SPScript*>((SPObject*)obj) != NULL) - /* SPScript */ class SPScript : public SPObject { public: diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 8b7e735e0..16f9ec13b 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -126,6 +126,7 @@ Inkscape::XML::Node* SPShape::write(Inkscape::XML::Document *xml_doc, Inkscape:: } void SPShape::update(SPCtx* ctx, guint flags) { + // std::cout << "SPShape::update(): " << (getId()?getId():"null") << std::endl; SPLPEItem::update(ctx, flags); /* This stanza checks that an object's marker style agrees with @@ -145,7 +146,15 @@ void SPShape::update(SPCtx* ctx, guint flags) { for (SPItemView *v = ((SPItem *) (this))->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); - sh->setStyle(this->style); + if (hasMarkers()) { + this->context_style = this->style; + sh->setStyle(this->style, this->context_style); + // Done at end: + // sh->setChildrenStyle(this->context_style); //Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + sh->setStyle(this->style, this->context_style); + } } } } @@ -163,6 +172,7 @@ void SPShape::update(SPCtx* ctx, guint flags) { } if (this->hasMarkers ()) { + /* Dimension marker views */ for (SPItemView *v = this->display; v != NULL; v = v->next) { if (!v->arenaitem->key()) { @@ -182,6 +192,13 @@ void SPShape::update(SPCtx* ctx, guint flags) { for (SPItemView *v = this->display; v != NULL; v = v->next) { sp_shape_update_marker_view (this, v->arenaitem); } + + // Marker selector needs this here or marker previews are not rendered. + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); + + sh->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } } } @@ -382,12 +399,23 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) } void SPShape::modified(unsigned int flags) { + // std::cout << "SPShape::modified(): " << (getId()?getId():"null") << std::endl; SPLPEItem::modified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); - sh->setStyle(this->style); + if (hasMarkers()) { + this->context_style = this->style; + sh->setStyle(this->style, this->context_style); + // Note: marker selector preview does not trigger SP_OBJECT_STYLE_MODIFIED_FLAG so + // this is not called when marker previews are generated, however there is code in + // SPShape::update() that calls this routine so we don't worry about it here. + sh->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + sh->setStyle(this->style, this->context_style); + } } } } @@ -434,7 +462,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox tr = Geom::Rotate::from_degrees( 180.0 ) * tr; } else if (_marker[i]->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(_marker[i]->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(_marker[i]->orient.computed) * Geom::Translate(transl); } if (_marker[i]->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -472,7 +500,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -502,7 +530,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -525,7 +553,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -560,7 +588,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -718,8 +746,11 @@ void SPShape::print(SPPrintContext* ctx) { } Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { + // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); - s->setStyle(this->style); + + bool has_markers = this->hasMarkers(); + s->setPath(this->_curve); /* This stanza checks that an object's marker style agrees with @@ -731,7 +762,7 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* sp_shape_set_marker (this, i, this->style->marker_ptrs[i]->value); } - if (this->hasMarkers ()) { + if (has_markers) { /* provide key and dimension the marker views */ if (!s->key()) { s->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); @@ -747,8 +778,14 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* /* Update marker views */ sp_shape_update_marker_view (this, s); - } + this->context_style = this->style; + s->setStyle(this->style, this->context_style); + s->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + s->setStyle(this->style, this->context_style); + } return s; } diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp index 0d6b96b62..72569d8c0 100644 --- a/src/sp-solid-color.cpp +++ b/src/sp-solid-color.cpp @@ -53,7 +53,7 @@ void SPSolidColor::build(SPDocument* doc, Inkscape::XML::Node* repr) { void SPSolidColor::set(unsigned int key, const gchar* value) { if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + style->readFromObject( this ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPPaintServer::set(key, value); diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp index d644a9b4b..3ee467322 100644 --- a/src/sp-stop.cpp +++ b/src/sp-stop.cpp @@ -210,16 +210,14 @@ SPStop* SPStop::getPrevStop() { SPColor SPStop::readStopColor(Glib::ustring const &styleStr, guint32 dfl) { SPColor color(dfl); - SPStyle* style = sp_style_new(0); SPIPaint paint; - paint.read( styleStr.c_str(), *style ); + + paint.read( styleStr.c_str() ); if ( paint.isColor() ) { color = paint.value.color; } - sp_style_unref(style); - return color; } diff --git a/src/sp-style-elem.cpp b/src/sp-style-elem.cpp index 84f110134..668780272 100644 --- a/src/sp-style-elem.cpp +++ b/src/sp-style-elem.cpp @@ -26,23 +26,18 @@ SPStyleElem::~SPStyleElem() { } void SPStyleElem::set(unsigned int key, const gchar* value) { - SPStyleElem* object = this; - - g_return_if_fail(object); - SPStyleElem &style_elem = *SP_STYLE_ELEM(object); - switch (key) { case SP_ATTR_TYPE: { if (!value) { /* TODO: `type' attribute is required. Give error message as per http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. */ - style_elem.is_css = false; + is_css = false; } else { /* fixme: determine what whitespace is allowed. Will probably need to ask on SVG - * list; though the relevant RFC may give info on its lexer. */ - style_elem.is_css = ( g_ascii_strncasecmp(value, "text/css", 8) == 0 - && ( value[8] == '\0' || - value[8] == ';' ) ); + list; though the relevant RFC may give info on its lexer. */ + is_css = ( g_ascii_strncasecmp(value, "text/css", 8) == 0 + && ( value[8] == '\0' || + value[8] == ';' ) ); } break; } @@ -67,14 +62,18 @@ static void child_add_rm_cb(Inkscape::XML::Node *, Inkscape::XML::Node *, Inkscape::XML::Node *, void *const data) { - static_cast<SPObject *>(data)->read_content(); + SPObject *obj = reinterpret_cast<SPObject *>(data); + g_assert(data != NULL); + obj->read_content(); } static void content_changed_cb(Inkscape::XML::Node *, gchar const *, gchar const *, void *const data) { - static_cast<SPObject *>(data)->read_content(); + SPObject *obj = reinterpret_cast<SPObject *>(data); + g_assert(data != NULL); + obj->read_content(); } static void @@ -82,24 +81,22 @@ child_order_changed_cb(Inkscape::XML::Node *, Inkscape::XML::Node *, Inkscape::XML::Node *, Inkscape::XML::Node *, void *const data) { - static_cast<SPObject *>(data)->read_content(); + SPObject *obj = reinterpret_cast<SPObject *>(data); + g_assert(data != NULL); + obj->read_content(); } Inkscape::XML::Node* SPStyleElem::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { - SPStyleElem* object = this; - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:style"); } - g_return_val_if_fail(object, repr); - SPStyleElem &style_elem = *SP_STYLE_ELEM(object); if (flags & SP_OBJECT_WRITE_BUILD) { g_warning("nyi: Forming <style> content for SP_OBJECT_WRITE_BUILD."); /* fixme: Consider having the CRStyleSheet be a member of SPStyleElem, and then pretty-print to a string s, then repr->addChild(xml_doc->createTextNode(s), NULL). */ } - if (style_elem.is_css) { + if (is_css) { repr->setAttribute("type", "text/css"); } /* todo: media */ @@ -263,10 +260,6 @@ property_cb(CRDocHandler *const a_handler, } void SPStyleElem::read_content() { - SPStyleElem* object = this; - - SPStyleElem &style_elem = *SP_STYLE_ELEM(object); - /* fixme: If there's more than one <style> element in a document, then the document stylesheet * will be set to a random one of them, even switching between them. * @@ -283,7 +276,7 @@ void SPStyleElem::read_content() { */ //XML Tree being used directly here while it shouldn't be. - GString *const text = concat_children(*style_elem.getRepr()); + GString *const text = concat_children(*getRepr()); CRParser *parser = cr_parser_new_from_buf(reinterpret_cast<guchar *>(text->str), text->len, CR_UTF_8, FALSE); @@ -312,7 +305,7 @@ void SPStyleElem::read_content() { CRStatus const parse_status = cr_parser_parse(parser); g_assert(sac_handler->app_data == &parse_tmp); if (parse_status == CR_OK) { - cr_cascade_set_sheet(style_elem.document->style_cascade, stylesheet, ORIGIN_AUTHOR); + cr_cascade_set_sheet(document->style_cascade, stylesheet, ORIGIN_AUTHOR); } else { if (parse_status != CR_PARSING_ERROR) { g_printerr("parsing error code=%u\n", unsigned(parse_status)); @@ -323,17 +316,17 @@ void SPStyleElem::read_content() { } } cr_parser_destroy(parser); - //object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + //requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); // Style references via class= do not, and actually cannot, use autoupdating URIReferences. - // Therefore, if an object refers to a stylesheet which has not yet loaded when the object is being loaded - // (e.g. if the stylesheet is below or inside the object in XML), its class= has no effect (bug 1491639). - // Below is a partial hack that fixes this for a single case: when the <style> is a child of the object - // that uses a style from it. It just forces the parent of <style> to reread its style as soon as the stylesheet - // is fully loaded. Naturally, this won't work if the user of the stylesheet is its grandparent or precedent. - SPObject *parent = object->parent; + // Therefore, if an object refers to a stylesheet which has not yet loaded when the object is + // being loaded (e.g. if the stylesheet is below or inside the object in XML), its class= has + // no effect (bug 1491639). Below is a partial hack that fixes this for a single case: when + // the <style> is a child of the object that uses a style from it. It just forces the parent of + // <style> to reread its style as soon as the stylesheet is fully loaded. Naturally, this won't + // work if the user of the stylesheet is its grandparent or precedent. if ( parent ) { - sp_style_read_from_object(parent->style, parent); + parent->style->readFromObject( parent ); } } @@ -351,12 +344,10 @@ rec_add_listener(Inkscape::XML::Node &repr, } void SPStyleElem::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPStyleElem* object = this; - - object->read_content(); + read_content(); - object->readAttr( "type" ); - object->readAttr( "media" ); + readAttr( "type" ); + readAttr( "media" ); static Inkscape::XML::NodeEventVector const nodeEventVector = { child_add_rm_cb, // child_added @@ -365,7 +356,7 @@ void SPStyleElem::build(SPDocument *document, Inkscape::XML::Node *repr) { content_changed_cb, // content_changed child_order_changed_cb, // order_changed }; - rec_add_listener(*repr, &nodeEventVector, object); + rec_add_listener(*repr, &nodeEventVector, this); SPObject::build(document, repr); } diff --git a/src/sp-style-elem.h b/src/sp-style-elem.h index 766770216..a3f4bdc70 100644 --- a/src/sp-style-elem.h +++ b/src/sp-style-elem.h @@ -4,9 +4,6 @@ #include "sp-object.h" #include "media.h" -#define SP_STYLE_ELEM(obj) (dynamic_cast<SPStyleElem*>((SPObject*)obj)) -#define SP_IS_STYLE_ELEM(obj) (dynamic_cast<const SPStyleElem*>((SPObject*)obj) != NULL) - class SPStyleElem : public SPObject { public: SPStyleElem(); diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 93d81e47b..e40661824 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -38,7 +38,7 @@ #include "attributes.h" #include "document.h" #include "preferences.h" -#include "desktop-handles.h" +#include "desktop.h" #include "sp-namedview.h" #include "style.h" #include "inkscape.h" @@ -57,6 +57,12 @@ #include "sp-factory.h" +// For SVG 2 text flow +#include "livarot/Path.h" +#include "livarot/Shape.h" +#include "sp-shape.h" +#include "display/curve.h" + namespace { SPObject* createText() { return new SPText(); @@ -81,6 +87,10 @@ void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "dy" ); this->readAttr( "rotate" ); + // textLength and friends + this->readAttr( "textLength" ); + this->readAttr( "lengthAdjust" ); + // SVG 2 Auto wrapped text this->readAttr( "width" ); this->readAttr( "height" ); @@ -195,7 +205,7 @@ void SPText::update(SPCtx *ctx, guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); // pass the bbox of the this this as paintbox (used for paintserver fills) this->layout.show(g, paintbox); } @@ -221,7 +231,7 @@ void SPText::modified(guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); this->layout.show(g, paintbox); } } @@ -333,7 +343,7 @@ Geom::OptRect SPText::bbox(Geom::Affine const &transform, SPItem::BBoxType type) Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned /*key*/, unsigned /*flags*/) { Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing); flowed->setPickChildren(false); - flowed->setStyle(this->style); + flowed->setStyle(this->style, this->parent->style); // pass the bbox of the text object as paintbox (used for paintserver fills) this->layout.show(flowed, this->geometricBounds()); @@ -362,7 +372,7 @@ gchar* SPText::description() const { char *n = xml_quote_strdup( style->font_family.value ); Inkscape::Util::Quantity q = Inkscape::Util::Quantity(style->font_size.computed, "px"); - GString *xs = g_string_new(q.string(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units).c_str()); + GString *xs = g_string_new(q.string(SP_ACTIVE_DESKTOP->getNamedView()->display_units).c_str()); char const *trunc = ""; Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); @@ -403,6 +413,10 @@ Geom::Affine SPText::set_transform(Geom::Affine const &xform) { } } + // we cannot optimize text with textLength because it may show different size than specified + if (this->attributes.getTextLength()->_set) + return xform; + /* This function takes care of scaling & translation only, we return whatever parts we can't handle. */ @@ -464,8 +478,71 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio int child_attrs_offset = 0; Inkscape::Text::Layout::OptionalTextTagAttrs optional_attrs; + // Test SVG 2 text in shape implementation + // To do: follow SPItem clip_ref/mask_ref code + if (style->shape_inside.set ) { + + // Extract out id + Glib::ustring shape_url = style->shape_inside.value; + if ( shape_url.compare(0,5,"url(#") != 0 || shape_url.compare(shape_url.size()-1,1,")") != 0 ){ + std::cerr << "SPText::_buildLayoutInput(): Invalid shape-inside value: " << shape_url << std::endl; + } else { + shape_url.erase(0,5); + shape_url.erase(shape_url.size()-1,1); + // std::cout << "SPText::_buildLayoutInput(): shape-inside: " << shape_url << std::endl; + SPShape *shape = dynamic_cast<SPShape *>(document->getObjectById( shape_url )); + if ( shape ) { + + // This code adapted from sp-flowregion.cpp: GetDest() + if (!(shape->_curve)) { + shape->set_shape(); + } + SPCurve *curve = shape->getCurve(); + + if ( curve ) { + Path *temp = new Path; + Path *padded = new Path; + temp->LoadPathVector( curve->get_pathvector(), shape->transform, true ); + if( style->shape_padding.set ) { + // std::cout << " padding: " << style->shape_padding.computed << std::endl; + temp->OutsideOutline ( padded, style->shape_padding.computed, join_round, butt_straight, 20.0 ); + } else { + // std::cout << " no padding" << std::endl; + padded->Copy( temp ); + } + padded->Convert( 0.25 ); // Convert to polyline + Shape* sh = new Shape; + padded->Fill( sh, 0 ); + // for( unsigned i = 0; i < temp->pts.size(); ++i ) { + // std::cout << " ........ " << temp->pts[i].p << std::endl; + // } + // std::cout << " ...... shape: " << sh->numberOfPoints() << std::endl; + Shape *uncross = new Shape; + uncross->ConvertToShape( sh ); + layout.appendWrapShape( uncross ); + + delete temp; + delete padded; + delete sh; + // delete uncross; + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to get curve." << std::endl; + } + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to find shape." << std::endl; + } + } + } + if (SP_IS_TEXT(root)) { SP_TEXT(root)->attributes.mergeInto(&optional_attrs, parent_optional_attrs, parent_attrs_offset, true, true); + if (SP_TEXT(root)->attributes.getTextLength()->_set) { // set textLength on the entire layout, see note in TNG-Layout.h + layout.textLength._set = true; + layout.textLength.value = SP_TEXT(root)->attributes.getTextLength()->value; + layout.textLength.computed = SP_TEXT(root)->attributes.getTextLength()->computed; + layout.textLength.unit = SP_TEXT(root)->attributes.getTextLength()->unit; + layout.lengthAdjust = (Inkscape::Text::Layout::LengthAdjust) SP_TEXT(root)->attributes.getLengthAdjust(); + } } else if (SP_IS_TSPAN(root)) { SPTSpan *tspan = SP_TSPAN(root); @@ -488,7 +565,7 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio child_attrs_offset = parent_attrs_offset; } - if (SP_IS_TSPAN(root)) + if (SP_IS_TSPAN(root)) { if (SP_TSPAN(root)->role != SP_TSPAN_ROLE_UNSPECIFIED) { // we need to allow the first line not to have role=line, but still set the source_cookie to the right value SPObject *prev_object = root->getPrev(); @@ -507,13 +584,17 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio // start position. Very confusing. child_attrs_offset--; } - + } + for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_STRING(child)) { - Glib::ustring const &string = SP_STRING(child)->string; + SPString *str = dynamic_cast<SPString *>(child); + if (str) { + Glib::ustring const &string = str->string; + // std::cout << " Appending: " << string << std::endl; layout.appendText(string, root->style, child, &optional_attrs, child_attrs_offset + length); length += string.length(); - } /*XML Tree being directly used here while it shouldn't be.*/ else if (!sp_repr_is_meta_element(child->getRepr())) { + } else if (!sp_repr_is_meta_element(child->getRepr())) { + /* ^^^^ XML Tree being directly used here while it shouldn't be.*/ length += _buildLayoutInput(child, optional_attrs, child_attrs_offset + length, in_textpath); } } @@ -611,6 +692,8 @@ void TextTagAttributes::readFrom(Inkscape::XML::Node const *node) readSingleAttribute(SP_ATTR_DX, node->attribute("dx")); readSingleAttribute(SP_ATTR_DY, node->attribute("dy")); readSingleAttribute(SP_ATTR_ROTATE, node->attribute("rotate")); + readSingleAttribute(SP_ATTR_TEXTLENGTH, node->attribute("textLength")); + readSingleAttribute(SP_ATTR_LENGTHADJUST, node->attribute("lengthAdjust")); } bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) @@ -622,6 +705,16 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) case SP_ATTR_DX: attr_vector = &attributes.dx; break; case SP_ATTR_DY: attr_vector = &attributes.dy; break; case SP_ATTR_ROTATE: attr_vector = &attributes.rotate; break; + case SP_ATTR_TEXTLENGTH: + attributes.textLength.readOrUnset(value); + return true; + break; + case SP_ATTR_LENGTHADJUST: + attributes.lengthAdjust = (value && !strcmp(value, "spacingAndGlyphs")? + Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS : + Inkscape::Text::Layout::LENGTHADJUST_SPACING); // default is "spacing" + return true; + break; default: return false; } @@ -632,14 +725,34 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) void TextTagAttributes::writeTo(Inkscape::XML::Node *node) const { - writeSingleAttribute(node, "x", attributes.x); - writeSingleAttribute(node, "y", attributes.y); - writeSingleAttribute(node, "dx", attributes.dx); - writeSingleAttribute(node, "dy", attributes.dy); - writeSingleAttribute(node, "rotate", attributes.rotate); + writeSingleAttributeVector(node, "x", attributes.x); + writeSingleAttributeVector(node, "y", attributes.y); + writeSingleAttributeVector(node, "dx", attributes.dx); + writeSingleAttributeVector(node, "dy", attributes.dy); + writeSingleAttributeVector(node, "rotate", attributes.rotate); + + writeSingleAttributeLength(node, "textLength", attributes.textLength); + + if (attributes.textLength._set) { + if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACING) { + node->setAttribute("lengthAdjust", "spacing"); + } else if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS) { + node->setAttribute("lengthAdjust", "spacingAndGlyphs"); + } + } +} + +void TextTagAttributes::writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length) +{ + if (length._set) { + gchar single_value_string[32]; + g_ascii_formatd(single_value_string, sizeof (single_value_string), "%.8g", length.computed); + node->setAttribute(key, single_value_string); + } else + node->setAttribute(key, NULL); } -void TextTagAttributes::writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector) +void TextTagAttributes::writeSingleAttributeVector(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector) { if (attr_vector.empty()) node->setAttribute(key, NULL); @@ -697,6 +810,13 @@ void TextTagAttributes::mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs * mergeSingleAttribute(&output->dx, parent_attrs.dx, parent_attrs_offset, copy_dxdyrotate ? &attributes.dx : NULL); mergeSingleAttribute(&output->dy, parent_attrs.dy, parent_attrs_offset, copy_dxdyrotate ? &attributes.dy : NULL); mergeSingleAttribute(&output->rotate, parent_attrs.rotate, parent_attrs_offset, copy_dxdyrotate ? &attributes.rotate : NULL); + if (attributes.textLength._set) { // only from current node, this is not inherited from parent + output->textLength.value = attributes.textLength.value; + output->textLength.computed = attributes.textLength.computed; + output->textLength.unit = attributes.textLength.unit; + output->textLength._set = attributes.textLength._set; + output->lengthAdjust = attributes.lengthAdjust; + } } void TextTagAttributes::mergeSingleAttribute(std::vector<SVGLength> *output_list, std::vector<SVGLength> const &parent_list, unsigned parent_offset, std::vector<SVGLength> const *overlay_list) diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 0f6eb106f..6a229e170 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -492,12 +492,8 @@ sp_tref_convert_to_tspan(SPObject *obj) //SPObject * new_string_child = document->getObjectByRepr(new_string_repr); // Merge style from the tref - SPStyle *new_tspan_sty = new_tspan->style; - SPStyle const *tref_sty = tref->style; - sp_style_merge_from_dying_parent(new_tspan_sty, tref_sty); - sp_style_merge_from_parent(new_tspan_sty, new_tspan->parent->style); - - + new_tspan->style->merge( tref->style ); + new_tspan->style->cascade( new_tspan->parent->style ); new_tspan->updateRepr(); // Hold onto our SPObject and repr for now. diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index c3f7689e7..147efff33 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -42,6 +42,7 @@ #include "style.h" #include "xml/repr.h" #include "document.h" +#include "2geom/transforms.h" #include "sp-factory.h" @@ -447,7 +448,8 @@ void sp_textpath_to_text(SPObject *tp) } Geom::Point xy = bbox->min(); - + xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. + // make a list of textpath children GSList *tp_reprs = NULL; @@ -468,7 +470,7 @@ void sp_textpath_to_text(SPObject *tp) tp->deleteObject(); g_slist_free(tp_reprs); - // set x/y on text + // set x/y on text (to be near where it was when on path) /* fixme: Yuck, is this really the right test? */ if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { sp_repr_set_svg_double(text->getRepr(), "x", xy[Geom::X]); diff --git a/src/sp-use.cpp b/src/sp-use.cpp index e3fcd252a..7e02de3c1 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -35,6 +35,7 @@ #include "preferences.h" #include "style.h" #include "sp-symbol.h" +#include "sp-root.h" #include "sp-use.h" #include "sp-use-reference.h" #include "sp-shape.h" @@ -50,10 +51,17 @@ namespace { } SPUse::SPUse() - : SPItem() - , child(NULL) - , href(NULL) - , ref(new SPUseReference(this)) + : SPItem(), + child(NULL), + x(), + y(), + width(), + height(), + href(NULL), + ref(new SPUseReference(this)), + _delete_connection(), + _changed_connection(), + _transformed_connection() { this->x.unset(); this->y.unset(); @@ -87,7 +95,7 @@ void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, - // which will call sp_use_href_changed, and that will take care of the child + // which will call SPUse::href_changed, and that will take care of the child } void SPUse::release() { @@ -138,7 +146,7 @@ void SPUse::set(unsigned int key, const gchar* value) { this->href = NULL; if (value) { - // First, set the href field, because sp_use_href_changed will need it. + // First, set the href field, because SPUse::href_changed will need it. this->href = g_strdup(value); // Now do the attaching, which emits the changed signal. @@ -179,14 +187,23 @@ Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XM g_free(uri_string); } - if (SP_IS_SHAPE(this->child)) { - SP_SHAPE(this->child)->set_shape(); // evaluate SPCurve of child - } else if (SP_IS_TEXT(this->child)) { - SP_TEXT(this->child)->rebuildLayout(); // refresh Layout, LP Bug 1339305 - } else if (SP_IS_FLOWTEXT(this->child)) { - if (SP_IS_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())) - SP_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())->UpdateComputed(); - SP_FLOWTEXT(this->child)->rebuildLayout(); + SPShape *shape = dynamic_cast<SPShape *>(child); + if (shape) { + shape->set_shape(); // evaluate SPCurve of child + } else { + SPText *text = dynamic_cast<SPText *>(child); + if (text) { + text->rebuildLayout(); // refresh Layout, LP Bug 1339305 + } else { + SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(child); + if (flowtext) { + SPFlowregion *flowregion = dynamic_cast<SPFlowregion *>(flowtext->firstChild()); + if (flowregion) { + flowregion->UpdateComputed(); + } + flowtext->rebuildLayout(); + } + } } return repr; @@ -223,18 +240,20 @@ void SPUse::print(SPPrintContext* ctx) { } const char* SPUse::displayName() const { - if (this->child && SP_IS_SYMBOL( this->child )) { + if (dynamic_cast<SPSymbol *>(child)) { return _("Symbol"); + } else { + return _("Clone"); } - - return _("Clone"); } gchar* SPUse::description() const { - if (this->child) { - if( SP_IS_SYMBOL( this->child ) ) { - if (this->child->title()) { - return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", this->child->title()))).c_str()); + if (child) { + if ( dynamic_cast<SPSymbol *>(child) ) { + if (child->title()) { + return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", child->title()))).c_str()); + } else if (child->getAttribute("id")) { + return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", child->getAttribute("id")))).c_str()); } else { return g_strdup_printf(_("called %s"), _("Unnamed Symbol")); } @@ -264,10 +283,13 @@ gchar* SPUse::description() const { } Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + + // std::cout << "SPUse::show: " << (getId()?getId():"null") << std::endl; Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); - ai->setStyle(this->style); - + this->context_style = this->style; + ai->setStyle(this->style, this->context_style); + if (this->child) { Inkscape::DrawingItem *ac = this->child->invoke_show(drawing, key, flags); @@ -302,12 +324,10 @@ void SPUse::hide(unsigned int key) { SPItem *SPUse::root() { SPItem *orig = this->child; - while (orig && SP_IS_USE(orig)) { - orig = SP_USE(orig)->child; - } - - if (!orig) { - return NULL; + SPUse *use = dynamic_cast<SPUse *>(orig); + while (orig && use) { + orig = use->child; + use = dynamic_cast<SPUse *>(orig); } return orig; @@ -325,13 +345,16 @@ int SPUse::cloneDepth() const { unsigned depth = 1; SPItem *orig = this->child; - while (orig && SP_IS_USE(orig)) { + while (orig && dynamic_cast<SPUse *>(orig)) { ++depth; - orig = SP_USE(orig)->child; + orig = dynamic_cast<SPUse *>(orig)->child; } - if (!orig) return -1; - return depth; + if (!orig) { + return -1; + } else { + return depth; + } } /** @@ -345,9 +368,9 @@ Geom::Affine SPUse::get_root_transform() { GSList *chain = NULL; chain = g_slist_prepend(chain, this); - while (SP_IS_USE(orig)) { + while (dynamic_cast<SPUse *>(orig)) { chain = g_slist_prepend(chain, orig); - orig = SP_USE(orig)->child; + orig = dynamic_cast<SPUse *>(orig)->child; } chain = g_slist_prepend(chain, orig); @@ -357,14 +380,13 @@ Geom::Affine SPUse::get_root_transform() { Geom::Affine t(Geom::identity()); for (GSList *i = chain; i != NULL; i = i->next) { - SPItem *i_tem = SP_ITEM(i->data); + SPItem *i_tem = reinterpret_cast<SPItem *>(i->data); // "An additional transformation translate(x,y) is appended to the end (i.e., // right-side) of the transform attribute on the generated 'g', where x and y // represent the values of the x and y attributes on the 'use' element." - http://www.w3.org/TR/SVG11/struct.html#UseElement - if (SP_IS_USE(i_tem)) { - SPUse *i_use = SP_USE(i_tem); - + SPUse *i_use = dynamic_cast<SPUse *>(i_tem); + if (i_use) { if ((i_use->x._set && i_use->x.computed != 0) || (i_use->y._set && i_use->y.computed != 0)) { t = t * Geom::Translate(i_use->x._set ? i_use->x.computed : 0, i_use->y._set ? i_use->y.computed : 0); } @@ -405,7 +427,7 @@ void SPUse::move_compensate(Geom::Affine const *mp) { } // never compensate uses which are used in flowtext - if (this->parent && SP_IS_FLOWREGION(this->parent)) { + if (parent && dynamic_cast<SPFlowregion *>(parent)) { return; } @@ -462,8 +484,9 @@ void SPUse::href_changed() { SPObject* obj = SPFactory::instance().createObject(NodeTraits::get_type_string(*childrepr)); - if (SP_IS_ITEM(obj)) { - this->child = SP_ITEM(obj); + SPItem *item = dynamic_cast<SPItem *>(obj); + if (item) { + child = item; this->attach(this->child, this->lastChild()); sp_object_unref(this->child, this); @@ -495,8 +518,8 @@ void SPUse::href_changed() { void SPUse::delete_self() { // always delete uses which are used in flowtext - if (this->parent && SP_IS_FLOWREGION(this->parent)) { - this->deleteObject(); + if (parent && dynamic_cast<SPFlowregion *>(parent)) { + deleteObject(); return; } @@ -512,6 +535,7 @@ void SPUse::delete_self() { } void SPUse::update(SPCtx *ctx, unsigned flags) { + // std::cout << "SPUse::update: " << (getId()?getId():"null") << std::endl; SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; @@ -539,17 +563,22 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { this->height.computed = this->height.value * ictx->viewport.height(); } - cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); - cctx.i2vp = Geom::identity(); childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); + // viewport is only changed if referencing a symbol or svg element + if( SP_IS_SYMBOL(this->child) || SP_IS_ROOT(this->child) ) { + cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); + cctx.i2vp = Geom::identity(); + } + if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - SPItem const &chi = *SP_ITEM(this->child); - cctx.i2doc = chi.transform * ictx->i2doc; - cctx.i2vp = chi.transform * ictx->i2vp; + SPItem const *chi = dynamic_cast<SPItem const *>(child); + g_assert(chi != NULL); + cctx.i2doc = chi->transform * ictx->i2doc; + cctx.i2vp = chi->transform * ictx->i2vp; this->child->updateDisplay((SPCtx *)&cctx, childflags); } @@ -561,7 +590,8 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(this->style); + this->context_style = this->style; + g->setStyle(this->style, this->context_style); } } @@ -574,6 +604,7 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { } void SPUse::modified(unsigned int flags) { + // std::cout << "SPUse::modified: " << (getId()?getId():"null") << std::endl; if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } @@ -583,7 +614,8 @@ void SPUse::modified(unsigned int flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(this->style); + this->context_style = this->style; + g->setStyle(this->style, this->context_style); } } @@ -621,7 +653,7 @@ SPItem *SPUse::unlink() { Inkscape::XML::Node *copy = NULL; - if (SP_IS_SYMBOL(orig)) { // make a group, copy children + if (dynamic_cast<SPSymbol *>(orig)) { // make a group, copy children copy = xml_doc->createElement("svg:g"); for (Inkscape::XML::Node *child = orig->getRepr()->firstChild() ; child != NULL; child = child->next()) { @@ -639,11 +671,8 @@ SPItem *SPUse::unlink() { SPObject *unlinked = document->getObjectByRepr(copy); // Merge style from the use. - SPStyle *unli_sty = unlinked->style; - SPStyle const *use_sty = this->style; - sp_style_merge_from_dying_parent(unli_sty, use_sty); - sp_style_merge_from_parent(unli_sty, unlinked->parent->style); - + unlinked->style->merge( this->style ); + unlinked->style->cascade( unlinked->parent->style ); unlinked->updateRepr(); // Hold onto our SPObject and repr for now. @@ -669,7 +698,8 @@ SPItem *SPUse::unlink() { this->setSuccessor(unlinked); sp_object_unref(this, NULL); - SPItem *item = SP_ITEM(unlinked); + SPItem *item = dynamic_cast<SPItem *>(unlinked); + g_assert(item != NULL); // Set the accummulated transform. { diff --git a/src/sp-use.h b/src/sp-use.h index 97385b986..81e4391aa 100644 --- a/src/sp-use.h +++ b/src/sp-use.h @@ -6,7 +6,9 @@ * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> + * Jon A. Cruz <jon@joncruz.org> * + * Copyright (C) 1999-2014 Authors * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. * @@ -20,9 +22,6 @@ #include "sp-item.h" #include "enums.h" -#define SP_USE(obj) (dynamic_cast<SPUse*>((SPObject*)obj)) -#define SP_IS_USE(obj) (dynamic_cast<const SPUse*>((SPObject*)obj) != NULL) - class SPUseReference; class SPUse : public SPItem { diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 1a75a6f29..8bb3e9897 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -37,7 +37,7 @@ #include "layer-model.h" #include "message-stack.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/canvas-bpath.h" #include "display/curve.h" @@ -1151,7 +1151,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) void sp_selected_path_outline(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>stroked path(s)</b> to convert stroke to path.")); @@ -1343,7 +1343,7 @@ sp_selected_path_outline(SPDesktop *desktop) if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether - SPDocument * doc = sp_desktop_document(desktop); + SPDocument * doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); @@ -1482,7 +1482,7 @@ sp_selected_path_outline(SPDesktop *desktop) // restore title, description, id, transform repr->setAttribute("id", id); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); newitem->doWriteTransform(repr, transform); if (title) { newitem->setTitle(title); @@ -1512,7 +1512,7 @@ sp_selected_path_outline(SPDesktop *desktop) } if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_OUTLINE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_OUTLINE, _("Convert stroke to path")); } else { // TRANSLATORS: "to outline" means "to convert stroke to path" @@ -1583,7 +1583,7 @@ void sp_selected_path_create_updating_inset(SPDesktop *desktop) void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating) { SPCurve *curve = NULL; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *item = selection->singleItem(); if (item == NULL || ( !SP_IS_SHAPE(item) && !SP_IS_TEXT(item) ) ) { @@ -1675,7 +1675,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool { // pas vraiment de points sur le resultat // donc il ne reste rien - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (updating ? SP_VERB_SELECTION_LINKED_OFFSET : SP_VERB_SELECTION_DYNAMIC_OFFSET), (updating ? _("Create linked offset") @@ -1723,7 +1723,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *nitem = reinterpret_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *nitem = reinterpret_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); if ( !updating ) { // delete original, apply the transform to the offset @@ -1740,7 +1740,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool selection->set(nitem); } - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (updating ? SP_VERB_SELECTION_LINKED_OFFSET : SP_VERB_SELECTION_DYNAMIC_OFFSET), (updating ? _("Create linked offset") @@ -1766,7 +1766,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool void sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to inset/outset.")); @@ -1946,7 +1946,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); // reapply the transform newitem->doWriteTransform(repr, transform); @@ -1963,7 +1963,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) } if (did) { - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (expand ? SP_VERB_SELECTION_OFFSET : SP_VERB_SELECTION_INSET), (expand ? _("Outset path") : _("Inset path"))); } else { @@ -2089,7 +2089,7 @@ sp_selected_path_simplify_item(SPDesktop *desktop, // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); // reapply the transform newitem->doWriteTransform(repr, transform); @@ -2191,7 +2191,7 @@ static void sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool justCoalesce, float angleLimit, bool breakableAngles) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, @@ -2208,7 +2208,7 @@ sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool ju breakableAngles, true); if (didSomething) - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_SIMPLIFY, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_SIMPLIFY, _("Simplify")); else desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to simplify in the selection.")); diff --git a/src/style-internal.cpp b/src/style-internal.cpp index b858e5cb6..915282301 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -984,7 +984,7 @@ SPIPaint::read( gchar const *str ) { if (streq(str, "currentColor")) { set = true; - currentcolor = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; if (style) { setColor( style->color.value.color ); } else { @@ -995,6 +995,12 @@ SPIPaint::read( gchar const *str ) { std::cerr << "SPIPaint::read(): value is 'currentColor' but 'color' not available." << std::endl; setColor( 0 ); } + } else if (streq(str, "context-fill")) { + set = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_FILL; + } else if (streq(str, "context-stroke")) { + set = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE; } else if (streq(str, "none")) { set = true; noneSet = true; @@ -1058,14 +1064,28 @@ SPIPaint::write( guint const flags, SPIBase const *const base) const { css << "none"; } - if ( this->currentcolor ) { + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { if ( !css.str().empty() ) { css << " "; } css << "currentColor"; } - if ( this->colorSet && !this->currentcolor ) { + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "context-fill"; + } + + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "context-stroke"; + } + + if ( this->colorSet && this->paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL ) { if ( !css.str().empty() ) { css << " "; } @@ -1074,7 +1094,7 @@ SPIPaint::write( guint const flags, SPIBase const *const base) const { css << color_buf; } - if (this->value.color.icc && !this->currentcolor) { + if ( this->value.color.icc && this->paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL ) { if ( !css.str().empty() ) { css << " "; } @@ -1107,7 +1127,7 @@ SPIPaint::reset( bool init ) { // std::cout << "SPIPaint::reset(): " << name << " " << init << std::endl; SPIBase::clear(); - currentcolor = false; + paintOrigin = SP_CSS_PAINT_ORIGIN_NORMAL; colorSet = false; noneSet = false; value.color.set( false ); @@ -1147,8 +1167,8 @@ SPIPaint::cascade( const SPIBase* const parent ) { setColor( p->value.color ); } else if( p->isNoneSet() ) { noneSet = true; - } else if( p->currentcolor ) { - currentcolor = true; + } else if( p->paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { + paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; setColor( style->color.value.color ); } else if( isNone() ) { // @@ -1156,7 +1176,7 @@ SPIPaint::cascade( const SPIBase* const parent ) { g_assert_not_reached(); } } else { - if( currentcolor ) { + if( paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { // Update in case color value changed. setColor( style->color.value.color ); } @@ -1187,7 +1207,7 @@ SPIPaint::operator==(const SPIBase& rhs) { if ( (this->isColor() != r->isColor() ) || (this->isPaintserver() != r->isPaintserver() ) || - (this->currentcolor != r->currentcolor ) ) { + (this->paintOrigin != r->paintOrigin ) ) { return false; } diff --git a/src/style-internal.h b/src/style-internal.h index 32792827a..a8f0c5096 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -36,6 +36,12 @@ static const unsigned SP_STYLE_FLAG_ALWAYS (1 << 2); static const unsigned SP_STYLE_FLAG_IFSET (1 << 0); static const unsigned SP_STYLE_FLAG_IFDIFF (1 << 1); +enum SPStyleSrc { + SP_STYLE_SRC_UNSET, + SP_STYLE_SRC_STYLE_PROP, + SP_STYLE_SRC_STYLE_SHEET, + SP_STYLE_SRC_ATTRIBUTE +}; /* General comments: * @@ -113,7 +119,7 @@ public: inherits(inherits), set(false), inherit(false), - style_att(false), + style_src(SP_STYLE_SRC_UNSET), style(NULL) {} @@ -150,7 +156,7 @@ public: inherits = rhs.inherits; set = rhs.set; inherit = rhs.inherit; - style_att = rhs.style_att; + style_src = rhs.style_src; style = rhs.style; return *this; } @@ -170,7 +176,7 @@ public: unsigned inherits : 1; // Property inherits by default from parent. unsigned set : 1; // Property has been explicitly set (vs. inherited). unsigned inherit : 1; // Property value set to 'inherit'. - unsigned style_att : 2; // Source (attribute, style attribute, style-sheet). NOT USED YET FIX ME + SPStyleSrc style_src : 2; // Source (attribute, style attribute, style-sheet). NOT USED YET FIX ME // To do: make private after g_asserts removed public: @@ -622,6 +628,15 @@ public: #define SP_STYLE_FILL_SERVER(s) ((const_cast<SPStyle *> (s))->getFillPaintServer()) #define SP_STYLE_STROKE_SERVER(s) ((const_cast<SPStyle *> (s))->getStrokePaintServer()) +// SVG 2 +enum SPPaintOrigin { + SP_CSS_PAINT_ORIGIN_NORMAL, + SP_CSS_PAINT_ORIGIN_CURRENT_COLOR, + SP_CSS_PAINT_ORIGIN_CONTEXT_FILL, + SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE +}; + + /// Paint type internal to SPStyle. class SPIPaint : public SPIBase { @@ -629,7 +644,7 @@ class SPIPaint : public SPIBase public: SPIPaint() : SPIBase( "anonymous_paint" ), - currentcolor(false), + paintOrigin( SP_CSS_PAINT_ORIGIN_NORMAL ), colorSet(false), noneSet(false) { value.href = NULL; @@ -638,7 +653,6 @@ public: SPIPaint( Glib::ustring const &name ) : SPIBase( name ), - currentcolor(false), colorSet(false), noneSet(false) { value.href = NULL; @@ -657,7 +671,7 @@ public: SPIPaint& operator=(const SPIPaint& rhs) { SPIBase::operator=(rhs); - currentcolor = rhs.currentcolor; + paintOrigin = rhs.paintOrigin; colorSet = rhs.colorSet; noneSet = rhs.noneSet; value.color = rhs.value.color; @@ -671,7 +685,7 @@ public: } bool isSameType( SPIPaint const & other ) const { - return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (currentcolor == other.currentcolor); + return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (paintOrigin == other.paintOrigin); } bool isNoneSet() const { @@ -679,7 +693,7 @@ public: } bool isNone() const { - return !currentcolor && !colorSet && !isPaintserver(); + return (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL) && !colorSet && !isPaintserver(); } // TODO refine bool isColor() const { @@ -706,7 +720,7 @@ public: // To do: make private public: - bool currentcolor : 1; + SPPaintOrigin paintOrigin : 2; bool colorSet : 1; bool noneSet : 1; struct { diff --git a/src/style-test.h b/src/style-test.h index 2fe270336..cd6769b24 100644 --- a/src/style-test.h +++ b/src/style-test.h @@ -104,30 +104,30 @@ public: TestCase("font:bold 12px Arial", "font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:normal;font-family:Arial"), TestCase("font:bold 12px/24px 'Times New Roman'", - "font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:24px;font-family:\'\"Times New Roman\"\'"), + "font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:24px;font-family:\'Times New Roman\'"), // From CSS 3 Fonts (examples): - TestCase("font: 12pt/14pt sans-serif", - "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:14pt;font-family:sans-serif"), + TestCase("font: 12pt/15pt sans-serif", + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:15pt;font-family:sans-serif"), TestCase("font: 80% sans-serif", "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80.00000119%;line-height:normal;font-family:sans-serif"), TestCase("font: x-large/110% 'new century schoolbook', serif", - "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110.00000238%;font-family:\'\"new century schoolbook\", serif\'"), + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110.00000238%;font-family:\'new century schoolbook\', serif"), TestCase("font: bold italic large Palatino, serif", - "font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:large;line-height:normal;font-family:\'Palatino, serif\'"), + "font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:large;line-height:normal;font-family:Palatino, serif"), TestCase("font: normal small-caps 120%/120% fantasy", "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120.00000477%;line-height:120.00000477%;font-family:fantasy"), TestCase("font: condensed oblique 12pt 'Helvetica Neue', serif;", - "font-style:oblique;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:normal;font-family:\'\"Helvetica Neue\", serif\'"), + "font-style:oblique;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:16px;line-height:normal;font-family:\'Helvetica Neue\', serif"), TestCase("font-family:sans-serif"), // SPIString, text_private TestCase("font-family:Arial"), - TestCase("font-variant:normal;font-stretch:normal;-inkscape-font-specification:Nimbus Roman No9 L Bold Italic"), + // TestCase("font-variant:normal;font-stretch:normal;-inkscape-font-specification:Nimbus Roman No9 L Bold Italic"), // Needs to be fixed (quotes should be around each font-family): - TestCase("font-family:Georgia, 'Minion Web'","font-family:'Georgia, \"Minion Web\"'"), + TestCase("font-family:Georgia, 'Minion Web'","font-family:Georgia, \'Minion Web\'"), TestCase("font-size:12", "font-size:12px"), // SPIFontSize TestCase("font-size:12px"), - TestCase("font-size:12pt", "font-size:15px"), + TestCase("font-size:12pt", "font-size:16px"), TestCase("font-size:medium"), TestCase("font-size:smaller"), TestCase("font-style:italic"), // SPIEnum @@ -145,10 +145,10 @@ public: // The default value for 'text-decoration-color' is 'currentColor', but // we cannot set the default to that value yet. (We need to switch // SPIPaint to SPIColor and then add the ability to set default.) - TestCase("text-decoration: underline", - "text-decoration: underline;text-decoration-line: underline;text-decoration-color:currentColor"), - TestCase("text-decoration: overline underline", - "text-decoration: underline overline;text-decoration-line: underline overline;text-decoration-color:currentColor"), + // TestCase("text-decoration: underline", + // "text-decoration: underline;text-decoration-line: underline;text-decoration-color:currentColor"), + // TestCase("text-decoration: overline underline", + // "text-decoration: underline overline;text-decoration-line: underline overline;text-decoration-color:currentColor"), TestCase("text-decoration: underline wavy #0000ff", "text-decoration: underline;text-decoration-line: underline;text-decoration-style:wavy;text-decoration-color:#0000ff"), @@ -214,32 +214,25 @@ public: for ( gint i = 0; cases[i].src; i++ ) { // std::cout << "Test one: " << i << std::endl; - SPStyle *style = sp_style_new(_doc); - TS_ASSERT(style); - if ( style ) { - sp_style_merge_from_style_string( style, cases[i].src ); - - if ( cases[i].uri ) { - TSM_ASSERT( cases[i].src, style->fill.value.href ); - if ( style->fill.value.href ) { - TS_ASSERT_EQUALS( style->fill.value.href->getURI()->toString(), std::string(cases[i].uri) ); - } - } else { - TS_ASSERT( !style->fill.value.href || !style->fill.value.href->getObject() ); + SPStyle style(_doc); + style.mergeString( cases[i].src ); + if ( cases[i].uri ) { + TSM_ASSERT( cases[i].src, style.fill.value.href ); + if ( style.fill.value.href ) { + TS_ASSERT_EQUALS( style.fill.value.href->getURI()->toString(), std::string(cases[i].uri) ); } + } else { + TS_ASSERT( !style.fill.value.href || !style.fill.value.href->getObject() ); + } - gchar *str0_set = sp_style_write_string( style, SP_STYLE_FLAG_IFSET ); - //printf("<<%s>>\n", str0_set); - if ( cases[i].dst ) { - // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].dst) << std::endl; - TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].dst) ); - } else { - // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].src) << std::endl; - TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].src) ); - } + std::string str0_set = style.write(SP_STYLE_FLAG_IFSET ); - g_free(str0_set); - sp_style_unref(style); + if ( cases[i].dst ) { + // std::cout << " " << str0_set << " " << std::string(cases[i].dst) << std::endl; + TS_ASSERT_EQUALS( str0_set, std::string(cases[i].dst) ); + } else { + // std::cout << " " << str0_set << " " << std::string(cases[i].src) << std::endl; + TS_ASSERT_EQUALS( str0_set, std::string(cases[i].src) ); } } } @@ -358,7 +351,7 @@ public: TestCase("text-decoration:underline", "text-decoration:overline", false), TestCase("text-decoration:underline overline","text-decoration:underline overline",true ), TestCase("text-decoration:overline underline","text-decoration:underline overline",true ), - TestCase("text-decoration:none", "text-decoration-color:currentColor", true ), // Default + // TestCase("text-decoration:none", "text-decoration-color:currentColor", true ), // Default // Terminate @@ -366,26 +359,22 @@ public: }; for ( gint i = 0; cases[i].src; i++ ) { // std::cout << "Test two: " << i << std::endl; - SPStyle *style_src = sp_style_new(_doc); - TS_ASSERT(style_src); - SPStyle *style_dst = sp_style_new(_doc); - TS_ASSERT(style_dst); - - if ( style_src && style_dst ) { - sp_style_merge_from_style_string( style_src, cases[i].src ); - sp_style_merge_from_style_string( style_dst, cases[i].dst ); - // std::cout << "Test:" << std::endl; - // std::cout << " C: |" << cases[i].src << "| |" << cases[i].dst << "|" << std::endl; - // std::cout << " S: |" << style_src->write( SP_STYLE_FLAG_IFSET, NULL ) << "| |" - // << style_dst->write( SP_STYLE_FLAG_IFSET, NULL ) << "|" <<std::endl; - TS_ASSERT( (*style_src == *style_dst) == cases[i].match ); - sp_style_unref(style_src); - sp_style_unref(style_dst); - // std::cout << "End Test\n" << std::endl; - } + SPStyle style_src(_doc); + SPStyle style_dst(_doc); + + style_src.mergeString( cases[i].src ); + style_dst.mergeString( cases[i].dst ); + + // std::cout << "Test:" << std::endl; + // std::cout << " C: |" << cases[i].src << "| |" << cases[i].dst << "|" << std::endl; + // std::cout << " S: |" << style_src.write( SP_STYLE_FLAG_IFSET, NULL ) << "| |" + // << style_dst.write( SP_STYLE_FLAG_IFSET, NULL ) << "|" <<std::endl; + TS_ASSERT( (style_src == style_dst) == cases[i].match ); + // std::cout << "End Test\n" << std::endl; } } + // Test of cascade void testThree() { @@ -477,37 +466,29 @@ public: }; for ( gint i = 0; cases[i].parent; i++ ) { // std::cout << "Test three: " << i << std::endl; - SPStyle *style_parent = sp_style_new(_doc); - TS_ASSERT(style_parent); - SPStyle *style_child = sp_style_new(_doc); - TS_ASSERT(style_child); - SPStyle *style_result = sp_style_new(_doc); - TS_ASSERT(style_result); - - if ( style_parent && style_child && style_result ) { - sp_style_merge_from_style_string( style_parent, cases[i].parent ); - sp_style_merge_from_style_string( style_child, cases[i].child ); - sp_style_merge_from_style_string( style_result, cases[i].result ); - // std::cout << "Test:" << std::endl; - // std::cout << " Input: "; - // std::cout << " Parent: " << cases[i].parent - // << " Child: " << cases[i].child - // << " Result: " << cases[i].result << std::endl; - // std::cout << " Write: "; - // std::cout << " Parent: " << style_parent->write( SP_STYLE_FLAG_IFSET ) - // << " Child: " << style_child->write( SP_STYLE_FLAG_IFSET ) - // << " Result: " << style_result->write( SP_STYLE_FLAG_IFSET ) << std::endl; - - //sp_style_merge_from_parent( style_child, style_parent ); - style_child->cascade( style_parent ); - - TS_ASSERT(*style_child == *style_result ); - - sp_style_unref(style_child); - sp_style_unref(style_parent); - sp_style_unref(style_result); - // std::cout << "End Test: *************\n" << std::endl; - } + SPStyle style_parent(_doc); + SPStyle style_child( _doc); + SPStyle style_result(_doc); + + style_parent.mergeString( cases[i].parent ); + style_child.mergeString( cases[i].child ); + style_result.mergeString( cases[i].result ); + + // std::cout << "Test:" << std::endl; + // std::cout << " Input: "; + // std::cout << " Parent: " << cases[i].parent + // << " Child: " << cases[i].child + // << " Result: " << cases[i].result << std::endl; + // std::cout << " Write: "; + // std::cout << " Parent: " << style_parent.write( SP_STYLE_FLAG_IFSET ) + // << " Child: " << style_child.write( SP_STYLE_FLAG_IFSET ) + // << " Result: " << style_result.write( SP_STYLE_FLAG_IFSET ) << std::endl; + + style_child.cascade( &style_parent ); + + TS_ASSERT(style_child == style_result ); + + // std::cout << "End Test: *************\n" << std::endl; } } diff --git a/src/style.cpp b/src/style.cpp index e0c8536fc..b65bff53f 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -133,6 +133,12 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), + // SVG 2 Text Wrapping + shape_inside( "shape-inside" ), // SPIString + //shape_outside( "shape-outside" ), // SPIString + shape_padding( "shape-padding", 0.0 ), // SPILength for now + //shape_margin( "shape-margin", 0.0 ), // SPILength for now + text_decoration(), text_decoration_line(), text_decoration_style(), @@ -243,6 +249,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : word_spacing.setStylePointer( this ); stroke_width.setStylePointer( this ); stroke_dashoffset.setStylePointer( this ); + shape_padding.setStylePointer( this ); // Properties that depend on 'color' text_decoration_color.setStylePointer( this ); @@ -300,6 +307,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &text_anchor ); _properties.push_back( &white_space ); + _properties.push_back( &shape_inside ); + _properties.push_back( &shape_padding ); + _properties.push_back( &clip_rule ); _properties.push_back( &display ); _properties.push_back( &overflow ); @@ -383,6 +393,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_anchor ) ) ); // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast<SPIBasePtr>(&SPStyle::white_space ) ) ); + + // _propmap.insert( std::make_pair( shape_inside.name, reinterpret_cast<SPIBasePtr>(&SPStyle::shape_inside ) ) ); + // _propmap.insert( std::make_pair( shape_padding.name, reinterpret_cast<SPIBasePtr>(&SPStyle::shape_padding ) ) ); + // _propmap.insert( std::make_pair( clip_rule.name, reinterpret_cast<SPIBasePtr>(&SPStyle::clip_rule ) ) ); // _propmap.insert( std::make_pair( display.name, reinterpret_cast<SPIBasePtr>(&SPStyle::display ) ) ); // _propmap.insert( std::make_pair( overflow.name, reinterpret_cast<SPIBasePtr>(&SPStyle::overflow ) ) ); @@ -458,7 +472,14 @@ SPStyle::~SPStyle() { _properties.clear(); - // std::cout << "SPStyle::~SPstyle(): Exit\n" << std::endl; + // Conjecture: all this SPStyle ref counting is not needed. SPObject creates an instance of + // SPStyle when it is constructed and deletes it when it is destructed. The refcount is + // incremented and decremented only in the files: display/drawing-item.cpp, + // display/nr-filter-primitive.cpp, and libnrtype/Layout-TNG-Input.cpp. + if( _refcount > 1 ) { + std::cerr << "SPStyle::~SPStyle: ref count greater than 1! " << _refcount << std::endl; + } + // std::cout << "SPStyle::~SPStyle(): Exit\n" << std::endl; } // Used in SPStyle::clear() @@ -476,7 +497,7 @@ SPStyle::clear() { // (this->*(i->second)).clear(); // } - // Release connection to object, created in sp_style_new_from_object() + // Release connection to object, created in constructor. release_connection.disconnect(); // href->detach() called in fill->clear()... @@ -576,7 +597,13 @@ SPStyle::read( SPObject *object, Inkscape::XML::Node *repr ) { } } -// Matches void sp_style_read_from_object(SPStyle *style, SPObject *object); +/** + * Read style properties from object's repr. + * + * 1. Reset existing object style + * 2. Load current effective object style + * 3. Load i attributes from immediate parent (which has to be up-to-date) + */ void SPStyle::readFromObject( SPObject *object ) { @@ -591,6 +618,34 @@ SPStyle::readFromObject( SPObject *object ) { read( object, repr ); } +/** + * Read style properties from preferences. + * @param path Preferences directory from which the style should be read + */ +void +SPStyle::readFromPrefs(Glib::ustring const &path) { + + g_return_if_fail(!path.empty()); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // not optimal: we reconstruct the node based on the prefs, then pass it to + // sp_style_read for actual processing. + Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; + Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs"); + + std::vector<Inkscape::Preferences::Entry> attrs = prefs->getAllEntries(path); + for (std::vector<Inkscape::Preferences::Entry>::iterator i = attrs.begin(); i != attrs.end(); ++i) { + tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); + } + + read( NULL, tempnode ); + + Inkscape::GC::release(tempnode); + Inkscape::GC::release(tempdoc); + delete tempdoc; +} + // Matches sp_style_merge_property(SPStyle *style, gint id, gchar const *val) void SPStyle::readIfUnset( gint id, gchar const *val ) { @@ -678,6 +733,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_WHITE_SPACE: white_space.readIfUnset( val ); break; + case SP_PROP_SHAPE_INSIDE: + shape_inside.readIfUnset( val ); + break; + case SP_PROP_SHAPE_PADDING: + shape_padding.readIfUnset( val ); + break; case SP_PROP_BASELINE_SHIFT: baseline_shift.readIfUnset( val ); break; @@ -868,6 +929,19 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { } } +/** + * Outputs the style to a CSS string. + * + * Use with SP_STYLE_FLAG_ALWAYS for copying an object's complete cascaded style to + * style_clipboard. + * + * Use with SP_STYLE_FLAG_IFDIFF and a pointer to the parent class when you need a CSS string for + * an object in the document tree. + * + * \pre flags in {IFSET, ALWAYS, IFDIFF}. + * \pre base. + * \post ret != NULL. + */ Glib::ustring SPStyle::write( guint const flags, SPStyle const *const base ) const { @@ -897,9 +971,20 @@ SPStyle::write( guint const flags, SPStyle const *const base ) const { } // Corresponds to sp_style_merge_from_parent() +/** + * Sets computed values in \a style, which may involve inheriting from (or in some other way + * calculating from) corresponding computed values of \a parent. + * + * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. + * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to + * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise + * about what the computed value is (not obvious for lengths). + * + * \pre \a parent's computed values are already up-to-date. + */ void SPStyle::cascade( SPStyle const *const parent ) { - // std::cout << "SPStyle::cascade" << std::endl; + // std::cout << "SPStyle::cascade: " << (object->getId()?object->getId():"null") << std::endl; for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) { _properties[i]->cascade( parent->_properties[i] ); } @@ -909,6 +994,23 @@ SPStyle::cascade( SPStyle const *const parent ) { } // Corresponds to sp_style_merge_from_dying_parent() +/** + * Combine \a style and \a parent style specifications into a single style specification that + * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. + * + * Called when the parent repr is to be removed (e.g. the parent is a \<use\> element that is being + * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, + * trying to retain the same visual appearance once the parent is removed. Interesting cases are + * when there is unusual interaction with the parent's value (opacity, display) or when the value + * can be specified as relative to the parent computed value (font-size, font-weight etc.). + * + * Doesn't update computed values of \a style. For correctness, you should subsequently call + * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a + * style was previously up-to-date wrt \a parent. + * + * \pre \a parent's computed values are already up-to-date. + * (\a style's computed values needn't be up-to-date.) + */ void SPStyle::merge( SPStyle const *const parent ) { // std::cout << "SPStyle::merge" << std::endl; @@ -920,6 +1022,14 @@ SPStyle::merge( SPStyle const *const parent ) { // } } +/** + * Parses a style="..." string and merges it with an existing SPStyle. + */ +void +SPStyle::mergeString( gchar const *const p ) { + _mergeString( p ); +} + // Mostly for unit testing bool SPStyle::operator==(const SPStyle& rhs) { @@ -1142,35 +1252,6 @@ sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPSty sp_style_paint_server_ref_modified(ref, 0, style); } -// Called in: desktop-style.cpp, gradient-chemistry.cpp, sp-object.cpp, sp-stop.cpp, style.cpp -// text-editing.cpp, libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/fill-style.cpp, -// widgets/stroke-style.cpp, widgets/text-toolbar.cpp, ui/dialog/glyphs.cpp, ui/dialog/swatches.cpp, -// ui/dialog/swatches.cpp, ui/dialog/text-edit.cpp. ui/tools/freehand-base.cpp, -// ui/widget/object-composite-settings.cpp, ui/widget/selected-style.cpp, ui/widget/style-swatch.cpp -/** - * Returns a new SPStyle object with default settings. - */ -SPStyle * -sp_style_new(SPDocument *document) -{ - SPStyle *const style = new SPStyle( document ); - return style; -} - -// Called in: sp-object.cpp -/** - * Creates a new SPStyle object, and attaches it to the specified SPObject. - */ -SPStyle * -sp_style_new_from_object(SPObject *object) -{ - g_return_val_if_fail(object != NULL, NULL); - g_return_val_if_fail(SP_IS_OBJECT(object), NULL); - - SPStyle *const style = new SPStyle( NULL, object ); - return style; -} - // Called in display/drawing-item.cpp, display/nr-filter-primitive.cpp, libnrtype/Layout-TNG-Input.cpp /** * Increase refcount of style. @@ -1180,13 +1261,12 @@ sp_style_ref(SPStyle *style) { g_return_val_if_fail(style != NULL, NULL); - style->ref(); // Increase ref count + style->style_ref(); // Increase ref count return style; } -// Called in style.cpp, desktop-style.cpp, sp-object.cpp, sp-stop.cpp, text-editing.cpp -// display/drawing-group.cpp, ... +// Called in display/drawing-item.cpp, display/nr-filter-primitive.cpp, libnrtype/Layout-TNG-Input.cpp /** * Decrease refcount of style with possible destruction. */ @@ -1194,71 +1274,13 @@ SPStyle * sp_style_unref(SPStyle *style) { g_return_val_if_fail(style != NULL, NULL); - if (style->unref() < 1) { + if (style->style_unref() < 1) { delete style; return NULL; } return style; } - - -// Called in: sp-clippath.cpp, sp-item.cpp (suspicious), sp-object.cpp, sp-style-elem.cpp -/** - * Read style properties from object's repr. - * - * 1. Reset existing object style - * 2. Load current effective object style - * 3. Load i attributes from immediate parent (which has to be up-to-date) - */ -void -sp_style_read_from_object(SPStyle *style, SPObject *object) -{ - // std::cout << "sp_style_read_from_object: " << (object->getId()?object->getId():"null") << std::endl; - g_return_if_fail(style != NULL); - g_return_if_fail(object != NULL); - g_return_if_fail(SP_IS_OBJECT(object)); - - Inkscape::XML::Node *repr = object->getRepr(); - g_return_if_fail(repr != NULL); - - style->read( object, repr ); -} - -// Called in: libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/text-toolbar.cpp, -// ui/dialog/text-edit.cpp -// Why is this called when draging a gradient handle? -/** - * Read style properties from preferences. - * @param style The style to write to - * @param path Preferences directory from which the style should be read - */ -void -sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path) -{ - g_return_if_fail(style != NULL); - g_return_if_fail(path != ""); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // not optimal: we reconstruct the node based on the prefs, then pass it to - // sp_style_read for actual processing. - Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; - Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs"); - - std::vector<Inkscape::Preferences::Entry> attrs = prefs->getAllEntries(path); - for (std::vector<Inkscape::Preferences::Entry>::iterator i = attrs.begin(); i != attrs.end(); ++i) { - tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); - } - - style->read( NULL, tempnode ); - - Inkscape::GC::release(tempnode); - Inkscape::GC::release(tempdoc); - delete tempdoc; -} - - static CRSelEng * sp_repr_sel_eng() { @@ -1282,81 +1304,9 @@ sp_repr_sel_eng() return ret; } - -// Called in text-editting.cpp, ui/tools/frehand-base.cpp, ui/widget/style-swatch.cpp -/** - * Parses a style="..." string and merges it with an existing SPStyle. - */ -void -sp_style_merge_from_style_string(SPStyle *const style, gchar const *const p) -{ - // std::cout << "sp_style_merge_from_style_string: " << (p?p:"null") <<std::endl; - /* - * Reference: http://www.w3.org/TR/SVG11/styling.html#StyleAttribute: - * ``When CSS styling is used, CSS inline style is specified by including - * semicolon-separated property declarations of the form "name : value" - * within the style attribute''. - * - * That's fairly ambiguous. Is a `value' allowed to contain semicolons? - * Why does it say "including", what else is allowed in the style - * attribute value? - */ - style->_mergeString( p ); -} - /** Indexed by SP_CSS_FONT_SIZE_blah. These seem a bit small */ static float const font_size_table[] = {6.0, 8.0, 10.0, 12.0, 14.0, 18.0, 24.0}; -// Called in sp-object.cpp, sp-tref.cpp, sp-use.cpp -/** - * Sets computed values in \a style, which may involve inheriting from (or in some other way - * calculating from) corresponding computed values of \a parent. - * - * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. - * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to - * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise - * about what the computed value is (not obvious for lengths). - * - * \pre \a parent's computed values are already up-to-date. - */ -void -sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent) -{ - // std::cout << "sp_style_merge_from_parent" << std::endl; - g_return_if_fail(style != NULL); - - if (!parent) - return; - - style->cascade( parent ); - return; -} - -// Called in: sp-use.cpp, sp-tref.cpp, sp-item.cpp -/** - * Combine \a style and \a parent style specifications into a single style specification that - * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. - * - * Called when the parent repr is to be removed (e.g. the parent is a \<use\> element that is being - * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, - * trying to retain the same visual appearance once the parent is removed. Interesting cases are - * when there is unusual interaction with the parent's value (opacity, display) or when the value - * can be specified as relative to the parent computed value (font-size, font-weight etc.). - * - * Doesn't update computed values of \a style. For correctness, you should subsequently call - * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a - * style was previously up-to-date wrt \a parent. - * - * \pre \a parent's computed values are already up-to-date. - * (\a style's computed values needn't be up-to-date.) - */ -void -sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const parent) -{ - // std::cout << "sp_style_merge_from_dying_parent" << std::endl; - style->merge( parent ); -} - // The following functions should be incorporated into SPIPaint. FIXME // Called in: style.cpp, style-internal.cpp void @@ -1473,50 +1423,6 @@ sp_style_css_size_units_to_px(double size, int unit) return size * (size / sp_style_css_size_px_to_units(size, unit));; } -// Called in style.cpp, text-editing.cpp -/** - * Dumps the style to a CSS string, with either SP_STYLE_FLAG_IFSET or - * SP_STYLE_FLAG_ALWAYS flags. Used with Always for copying an object's - * complete cascaded style to style_clipboard. When you need a CSS string - * for an object in the document tree, you normally call - * sp_style_write_difference instead to take into account the object's parent. - * - * \pre style != NULL. - * \pre flags in {IFSET, ALWAYS}. - * \post ret != NULL. - */ -gchar * -sp_style_write_string(SPStyle const *const style, guint const flags) -{ - /** \todo - * Merge with write_difference, much duplicate code! - */ - g_return_val_if_fail(style != NULL, NULL); - g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || - (flags == SP_STYLE_FLAG_ALWAYS) ), - NULL); - - return g_strdup( style->write( flags ).c_str() ); -} - - -// Called in style.cpp, path-chemistry, NOT in text-editting.cpp (because of bug) -/** - * Dumps style to CSS string, see sp_style_write_string() - * - * \pre from != NULL. - * \pre to != NULL. - * \post ret != NULL. - */ -gchar * -sp_style_write_difference(SPStyle const *const from, SPStyle const *const to) -{ - g_return_val_if_fail(from != NULL, NULL); - g_return_val_if_fail(to != NULL, NULL); - - return g_strdup( from->write( SP_STYLE_FLAG_IFDIFF, to ).c_str() ); -} - // FIXME: Everything below this line belongs in a different file - css-chemistry? @@ -1640,6 +1546,12 @@ sp_style_unset_property_attrs(SPObject *o) if (style->white_space.set) { repr->setAttribute("white_space", NULL); } + if (style->shape_inside.set) { + repr->setAttribute("shape_inside", NULL); + } + if (style->shape_padding.set) { + repr->setAttribute("shape_padding", NULL); + } if (style->writing_mode.set) { repr->setAttribute("writing_mode", NULL); } @@ -1677,10 +1589,9 @@ sp_css_attr_from_style(SPStyle const *const style, guint const flags) g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || (flags == SP_STYLE_FLAG_ALWAYS) ), NULL); - gchar *style_str = sp_style_write_string(style, flags); + Glib::ustring style_str = style->write(flags); SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, style_str); - g_free(style_str); + sp_repr_css_attr_add_from_string(css, style_str.c_str()); return css; } @@ -1720,7 +1631,6 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "font-family", NULL); sp_repr_css_set_property(css, "text-indent", NULL); sp_repr_css_set_property(css, "text-align", NULL); - sp_repr_css_set_property(css, "text-decoration", NULL); sp_repr_css_set_property(css, "line-height", NULL); sp_repr_css_set_property(css, "letter-spacing", NULL); sp_repr_css_set_property(css, "word-spacing", NULL); @@ -1729,12 +1639,50 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "block-progression", NULL); sp_repr_css_set_property(css, "writing-mode", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); - sp_repr_css_set_property(css, "white_space", NULL); + sp_repr_css_set_property(css, "white-space", NULL); + sp_repr_css_set_property(css, "shape-inside", NULL); + sp_repr_css_set_property(css, "shape-padding", NULL); sp_repr_css_set_property(css, "kerning", NULL); // not implemented yet sp_repr_css_set_property(css, "dominant-baseline", NULL); // not implemented yet sp_repr_css_set_property(css, "alignment-baseline", NULL); // not implemented yet sp_repr_css_set_property(css, "baseline-shift", NULL); + sp_repr_css_set_property(css, "text-decoration", NULL); + sp_repr_css_set_property(css, "text-decoration-line", NULL); + sp_repr_css_set_property(css, "text-decoration-color", NULL); + sp_repr_css_set_property(css, "text-decoration-style", NULL); + + return css; +} + +// ui/dialog/inkscape-preferences.cpp +/** + * Unset properties that should not be set for default tool style. + * This list needs to be reviewed. + */ +SPCSSAttr * +sp_css_attr_unset_blacklist(SPCSSAttr *css) +{ + sp_repr_css_set_property(css, "color", NULL); + sp_repr_css_set_property(css, "clip-rule", NULL); + sp_repr_css_set_property(css, "display", NULL); + sp_repr_css_set_property(css, "overflow", NULL); + sp_repr_css_set_property(css, "visibility", NULL); + sp_repr_css_set_property(css, "isolation", NULL); + sp_repr_css_set_property(css, "mix-blend-mode", NULL); + sp_repr_css_set_property(css, "color-interpolation", NULL); + sp_repr_css_set_property(css, "color-interpolation-filters", NULL); + sp_repr_css_set_property(css, "solid-color", NULL); + sp_repr_css_set_property(css, "solid-opacity", NULL); + sp_repr_css_set_property(css, "fill-rule", NULL); + sp_repr_css_set_property(css, "filter-blend-mode", NULL); + sp_repr_css_set_property(css, "filter-gaussianBlur-deviation", NULL); + sp_repr_css_set_property(css, "color-rendering", NULL); + sp_repr_css_set_property(css, "image-rendering", NULL); + sp_repr_css_set_property(css, "shape-rendering", NULL); + sp_repr_css_set_property(css, "text-rendering", NULL); + sp_repr_css_set_property(css, "enable-background", NULL); + return css; } diff --git a/src/style.h b/src/style.h index a4c2b3043..ab34476b3 100644 --- a/src/style.h +++ b/src/style.h @@ -51,18 +51,19 @@ public: void readFromObject(SPObject *object); void readFromPrefs(Glib::ustring const &path); void readIfUnset( int id, char const *val ); - Glib::ustring write( unsigned int const flags, SPStyle const *const base = NULL ) const; + Glib::ustring write( unsigned int const flags = SP_STYLE_FLAG_IFSET, + SPStyle const *const base = NULL ) const; void cascade( SPStyle const *const parent ); void merge( SPStyle const *const parent ); + void mergeString( char const *const p ); bool operator==(const SPStyle& rhs); - int ref() { ++_refcount; return _refcount; } - int unref() { --_refcount; return _refcount; } + int style_ref() { ++_refcount; return _refcount; } + int style_unref() { --_refcount; return _refcount; } + int refCount() { return _refcount; } -//FIXME: Make private -public: - void _mergeString( char const *const p ); // Rename to readFromString? private: + void _mergeString( char const *const p ); void _mergeDeclList( CRDeclaration const *const decl_list ); void _mergeDecl( CRDeclaration const *const decl ); void _mergeProps( CRPropList *const props ); @@ -141,6 +142,12 @@ public: /** white space (svg2) */ SPIEnum white_space; + /** SVG2 Text Wrapping */ + SPIString shape_inside; + // SPIString shape_outside; + SPILength shape_padding; + // SPILength shape_margin; + /* Text Decoration ----------------------- */ /** text decoration (css2 16.3.1) */ @@ -282,28 +289,10 @@ public: char const *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI()->toString() : NULL; } }; -SPStyle *sp_style_new(SPDocument *document); // SPStyle::SPStyle( SPDocument *document = NULL ); - -SPStyle *sp_style_new_from_object(SPObject *object); // SPStyle::SPStyle( SPObject *object ); - SPStyle *sp_style_ref(SPStyle *style); // SPStyle::ref(); SPStyle *sp_style_unref(SPStyle *style); // SPStyle::unref(); -void sp_style_read_from_object(SPStyle *style, SPObject *object); //SPStyle::read( SPObject * object); - -void sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path); // SPStyle::read( ... ); - -void sp_style_merge_from_style_string(SPStyle *style, char const *p); // SPStyle::merge( ... );? - -void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent); // SPStyle::cascade( ... ); - -void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent); // SPStyle::merge( ... ) - -char *sp_style_write_string(SPStyle const *style, unsigned int flags = SP_STYLE_FLAG_IFSET);//SPStyle::write - -char *sp_style_write_difference(SPStyle const *from, SPStyle const *to); // SPStyle::write - void sp_style_set_to_uri_string (SPStyle *style, bool isfill, const char *uri); // ? char const *sp_style_get_css_unit_string(int unit); // No change? @@ -314,6 +303,7 @@ double sp_style_css_size_units_to_px(double size, int unit); // No change? SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, unsigned int flags); SPCSSAttr *sp_css_attr_from_object(SPObject *object, unsigned int flags = SP_STYLE_FLAG_IFSET); SPCSSAttr *sp_css_attr_unset_text(SPCSSAttr *css); +SPCSSAttr *sp_css_attr_unset_blacklist(SPCSSAttr *css); SPCSSAttr *sp_css_attr_unset_uris(SPCSSAttr *css); SPCSSAttr *sp_css_attr_scale(SPCSSAttr *css, double ex); diff --git a/src/svg/stringstream-test.h b/src/svg/stringstream-test.h index ce32683f8..305cf6b8d 100644 --- a/src/svg/stringstream-test.h +++ b/src/svg/stringstream-test.h @@ -37,9 +37,9 @@ public: svg_test_float(-0.0625, "-0.0625"); svg_test_float(30.0, "30"); svg_test_float(12345678.0, "12345678"); - svg_test_float(3e9, "3e+09"); - svg_test_float(-3.5e9, "-3.5e+09"); - svg_test_float(32768e9, "3.2768e+13"); + svg_test_float(3e9, "3e+009"); + svg_test_float(-3.5e9, "-3.5e+009"); + svg_test_float(32768e9, "3.2768e+013"); svg_test_float(-10.5, "-10.5"); } diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h index 11b9012a8..af670a3a8 100644 --- a/src/svg/svg-affine-test.h +++ b/src/svg/svg-affine-test.h @@ -34,8 +34,8 @@ private: static char const * const read_fail_tests[25]; static test_t const write_matrix_tests[2]; static test_t const write_translate_tests[3]; - static test_t const write_scale_tests[2]; - static test_t const write_rotate_tests[2]; + static test_t const write_scale_tests[3]; + static test_t const write_rotate_tests[3]; static test_t const write_skew_tests[3]; public: SvgAffineTest() { @@ -238,16 +238,18 @@ SvgAffineTest::test_t const SvgAffineTest::write_translate_tests[3] = { {"translate(1,1)",Geom::Affine(1,0,0,1,1,1)}, {"translate(1)",Geom::Affine(1,0,0,1,1,0)}, {"translate(-1345,0.123)",Geom::Affine(1,0,0,1,-1.345e3,.123)}}; -SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[2] = { +SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[3] = { {"scale(0)",Geom::Affine(0,0,0,0,0,0)}, + {"scale(7)",Geom::Affine(7,0,0,7,0,0)}, {"scale(2,3)",Geom::Affine(2,0,0,3,0,0)}}; -SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[2] = { +SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[3] = { {"rotate(13)",Geom::Affine(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)}, - {"rotate(-13,7,11)",Geom::Affine(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),(1-cos(-13.*DEGREE))*7+sin(-13.*DEGREE)*11,(1-cos(-13.*DEGREE))*11-sin(-13.*DEGREE)*7)}}; + {"rotate(-13,7,11)",Geom::Affine(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),(1-cos(-13.*DEGREE))*7+sin(-13.*DEGREE)*11,(1-cos(-13.*DEGREE))*11-sin(-13.*DEGREE)*7)}, + {"rotate(-34.5,6.7,89)",Geom::Affine(cos(-34.5*DEGREE),sin(-34.5*DEGREE),-sin(-34.5*DEGREE),cos(-34.5*DEGREE),(1-cos(-34.5*DEGREE))*6.7+sin(-34.5*DEGREE)*89,(1-cos(-34.5*DEGREE))*89-sin(-34.5*DEGREE)*6.7)}}; SvgAffineTest::test_t const SvgAffineTest::write_skew_tests[3] = { {"skewX(30)",Geom::Affine(1,0,tan(30.*DEGREE),1,0,0)}, {"skewX(-30)",Geom::Affine(1,0,tan(-30.*DEGREE),1,0,0)}, - {"skewY(390)",Geom::Affine(1,tan(30.*DEGREE),0,1,0,0)}}; + {"skewY(30)",Geom::Affine(1,tan(30.*DEGREE),0,1,0,0)}}; /* Local Variables: diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index 44567a2bd..c853f9930 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -162,65 +162,105 @@ sp_svg_transform_write(Geom::Affine const &transform) int prec = prefs->getInt("/options/svgoutput/numericprecision", 8); int min_exp = prefs->getInt("/options/svgoutput/minimumexponent", -8); - /* fixme: We could use t1 * t1 + t2 * t2 here instead */ - if ( Geom::are_near(transform[1], 0.0, e) && Geom::are_near (transform[2], 0.0, e)) { - if (Geom::are_near (transform[4], 0.0, e) && Geom::are_near (transform[5], 0.0, e)) { - if (Geom::are_near (transform[0], 1.0, e) && Geom::are_near (transform[3], 1.0, e)) { - /* We are more or less identity */ - return NULL; - } else { - /* We are more or less scale */ - gchar c[256]; - unsigned p = 0; - strcpy (c + p, "scale("); - p += 6; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp ); - c[p++] = ')'; - c[p] = '\000'; - g_assert( p <= sizeof(c) ); - return g_strdup(c); - } + // Special case: when all fields of the affine are zero, + // the optimized transformation is scale(0) + if (transform[0] == 0 && transform[1] == 0 && transform[2] == 0 && + transform[3] == 0 && transform[4] == 0 && transform[5] == 0) + { + return g_strdup("scale(0)"); + } + + // FIXME legacy C code! + // the function sp_svg_number_write_de is stopping me from using a proper C++ string + + gchar c[256]; // string buffer + unsigned p = 0; // position in the buffer + + if (transform.isIdentity()) { + // We are more or less identity, so no transform attribute needed: + return NULL; + } else if (transform.isScale()) { + // We are more or less a uniform scale + strcpy (c + p, "scale("); + p += 6; + p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp ); + if (Geom::are_near(transform[0], transform[3], e)) { + c[p++] = ')'; + c[p] = '\000'; } else { - if (Geom::are_near (transform[0], 1.0, e) && Geom::are_near (transform[3], 1.0, e)) { - /* We are more or less translate */ - gchar c[256]; - unsigned p = 0; - strcpy (c + p, "translate("); - p += 10; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp ); - c[p++] = ')'; - c[p] = '\000'; - g_assert( p <= sizeof(c) ); - return g_strdup(c); - } else { - gchar c[256]; - unsigned p = 0; - strcpy (c + p, "matrix("); - p += 7; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[1], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[2], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp ); - c[p++] = ','; - p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp ); - c[p++] = ')'; - c[p] = '\000'; - g_assert( p <= sizeof(c) ); - return g_strdup(c); - } + c[p++] = ','; + p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp ); + c[p++] = ')'; + c[p] = '\000'; } + } else if (transform.isTranslation()) { + // We are more or less a pure translation + strcpy (c + p, "translate("); + p += 10; + p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp ); + if (Geom::are_near(transform[5], 0.0, e)) { + c[p++] = ')'; + c[p] = '\000'; + } else { + c[p++] = ','; + p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp ); + c[p++] = ')'; + c[p] = '\000'; + } + } else if (transform.isRotation()) { + // We are more or less a pure rotation + strcpy(c + p, "rotate("); + p += 7; + + double angle = std::atan2(transform[1], transform[0]) * (180 / M_PI); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp); + + c[p++] = ')'; + c[p] = '\000'; + } else if (transform.withoutTranslation().isRotation()) { + // Solution found by Johan Engelen + // Refer to the matrix in svg-affine-test.h + + // We are a rotation about a special axis + strcpy(c + p, "rotate("); + p += 7; + + double angle = std::atan2(transform[1], transform[0]) * (180 / M_PI); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp); + c[p++] = ','; + + Geom::Affine const& m = transform; + double tx = (m[2]*m[5]+m[4]-m[4]*m[3]) / (1-m[3]-m[0]+m[0]*m[3]-m[2]*m[1]); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, tx, prec, min_exp); + + c[p++] = ','; + + double ty = (m[1]*tx + m[5]) / (1 - m[3]); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, ty, prec, min_exp); + + c[p++] = ')'; + c[p] = '\000'; + } else if (transform.isHShear()) { + // We are more or less a pure skewX + strcpy(c + p, "skewX("); + p += 6; + + double angle = atan(transform[2]) * (180 / M_PI); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp); + + c[p++] = ')'; + c[p] = '\000'; + } else if (transform.isVShear()) { + // We are more or less a pure skewY + strcpy(c + p, "skewY("); + p += 6; + + double angle = atan(transform[1]) * (180 / M_PI); + p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp); + + c[p++] = ')'; + c[p] = '\000'; } else { - gchar c[256]; - unsigned p = 0; strcpy (c + p, "matrix("); p += 7; p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp ); @@ -236,9 +276,10 @@ sp_svg_transform_write(Geom::Affine const &transform) p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp ); c[p++] = ')'; c[p] = '\000'; - g_assert( p <= sizeof(c) ); - return g_strdup(c); } + + assert(p <= sizeof(c)); + return g_strdup(c); } diff --git a/src/svg/svg-angle.cpp b/src/svg/svg-angle.cpp index 63152368e..ed5ccd45e 100644 --- a/src/svg/svg-angle.cpp +++ b/src/svg/svg-angle.cpp @@ -104,15 +104,19 @@ static bool sp_svg_angle_read_lff(gchar const *str, SVGAngle::Unit &unit, float } else { if (strncmp(e, "deg", 3) == 0) { unit = SVGAngle::DEG; + val = v; computed = v; } else if (strncmp(e, "grad", 4) == 0) { unit = SVGAngle::GRAD; + val = v; computed = Inkscape::Util::Quantity::convert(v, "grad", "°"); } else if (strncmp(e, "rad", 3) == 0) { unit = SVGAngle::RAD; + val = v; computed = Inkscape::Util::Quantity::convert(v, "rad", "°"); } else if (strncmp(e, "turn", 4) == 0) { unit = SVGAngle::TURN; + val = v; computed = Inkscape::Util::Quantity::convert(v, "turn", "°"); } else { return false; diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index c9f22f8a4..693094048 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -32,8 +32,8 @@ #include "svg-color.h" #include "svg-icc-color.h" -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color.h" +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color-profile.h" #include "document.h" #include "inkscape.h" diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h index 81a28c9e7..796943e45 100644 --- a/src/svg/svg-length-test.h +++ b/src/svg/svg-length-test.h @@ -164,13 +164,13 @@ SvgLengthTest::test_t const SvgLengthTest::absolute_tests[12] = { {"1.00001", SVGLength::NONE, 1.00001 , 1.00001}, {"1px", SVGLength::PX , 1 , 1}, {".1px", SVGLength::PX , 0.1 , 0.1}, - {"100pt", SVGLength::PT , 100 , 125}, - {"1e2pt", SVGLength::PT , 100 , 125}, - {"3pc", SVGLength::PC , 3 , 45}, - {"-3.5pc", SVGLength::PC , -3.5 , -3.5*15.}, - {"1.2345678mm", SVGLength::MM , 1.2345678, 1.2345678*3.543307}, // TODO: More precise constants? (a 7 digit constant when the default precision is 8 digits?) - {"123.45678cm", SVGLength::CM , 123.45678 , 123.45678*35.43307}, - {"73.162987in", SVGLength::INCH, 73.162987 , 73.162987*90}}; + {"100pt", SVGLength::PT , 100 , 400.0/3.0}, + {"1e2pt", SVGLength::PT , 100 , 400.0/3.0}, + {"3pc", SVGLength::PC , 3 , 48}, + {"-3.5pc", SVGLength::PC , -3.5 , -3.5*16.0}, + {"1.2345678mm", SVGLength::MM , 1.2345678, 1.2345678f*96.0/25.4}, // TODO: More precise constants? (a 7 digit constant when the default precision is 8 digits?) + {"123.45678cm", SVGLength::CM , 123.45678 , 123.45678f*96.0/2.54}, // Note that svg_length_read is casting the result from g_ascii_strtod to float. + {"73.162987in", SVGLength::INCH, 73.162987 , 73.162987f*96.0/1.00}}; SvgLengthTest::test_t const SvgLengthTest::relative_tests[3] = { {"123em", SVGLength::EM, 123, 123. * 7.}, {"123ex", SVGLength::EX, 123, 123. * 13.}, diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index b9b475f4b..ea235b2e4 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -520,7 +520,8 @@ gchar const *sp_svg_length_get_css_units(SVGLength::Unit unit) case SVGLength::MM: return "mm"; case SVGLength::CM: return "cm"; case SVGLength::INCH: return "in"; - case SVGLength::FOOT: return ""; // Does not have a "foot" unit string in the SVG spec + case SVGLength::FOOT: return ""; // Not in SVG/CSS specification. + case SVGLength::MITRE: return ""; // Not in SVG/CSS specification. case SVGLength::EM: return "em"; case SVGLength::EX: return "ex"; case SVGLength::PERCENT: return "%"; @@ -539,6 +540,8 @@ std::string sp_svg_length_write_with_units(SVGLength const &length) os << 100*length.value << sp_svg_length_get_css_units(length.unit); } else if (length.unit == SVGLength::FOOT) { os << 12*length.value << sp_svg_length_get_css_units(SVGLength::INCH); + } else if (length.unit == SVGLength::MITRE) { + os << 100*length.value << sp_svg_length_get_css_units(SVGLength::CM); } else { os << length.value << sp_svg_length_get_css_units(length.unit); } diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index c34905d07..1e6b4c96c 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -28,6 +28,7 @@ public: CM, INCH, FOOT, + MITRE, EM, EX, PERCENT, diff --git a/src/test-helpers.h b/src/test-helpers.h index 001356e65..d30449ebb 100644 --- a/src/test-helpers.h +++ b/src/test-helpers.h @@ -5,7 +5,7 @@ #include <cxxtest/TestSuite.h> #include "document.h" -#include "inkscape-private.h" +#include "inkscape.h" // Dummy functions to keep linker happy @@ -28,10 +28,10 @@ T* createSuiteAndDocument( void (*fun)(T*&) ) #endif Inkscape::GC::init(); - if ( !inkscape_get_instance() ) + if ( !Inkscape::Application::exists() ) { // Create the global inkscape object. - static_cast<void>(g_object_new(inkscape_get_type(), NULL)); + Inkscape::Application::create("", false); } SPDocument* tmp = SPDocument::createNewDoc( NULL, TRUE, true ); diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index aa2d81427..65b59f2ad 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -29,7 +29,7 @@ #include "message-stack.h" #include "selection.h" #include "style.h" -#include "desktop-handles.h" + #include "text-editing.h" #include "text-chemistry.h" #include "sp-flowtext.h" @@ -83,7 +83,7 @@ text_put_on_path() if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); @@ -91,18 +91,18 @@ text_put_on_path() Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); if (!text || !shape || g_slist_length((GSList *) selection->itemList()) != 2) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path.")); return; } if (SP_IS_TEXT_TEXTPATH(text)) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("This text object is <b>already put on a path</b>. Remove it from the path first. Use <b>Shift+D</b> to look up its path.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("This text object is <b>already put on a path</b>. Remove it from the path first. Use <b>Shift+D</b> to look up its path.")); return; } if (SP_IS_RECT(shape)) { // rect is the only SPShape which is not <path> yet, and thus SVG forbids us from putting text on it - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("You cannot put text on a rectangle in this version. Convert rectangle to path first.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot put text on a rectangle in this version. Convert rectangle to path first.")); return; } @@ -110,7 +110,7 @@ text_put_on_path() if (SP_IS_FLOWTEXT(text)) { if (!SP_FLOWTEXT(text)->layout.outputExists()) { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::WARNING_MESSAGE, _("The flowed text(s) must be <b>visible</b> in order to be put on a path.")); } @@ -122,14 +122,14 @@ text_put_on_path() Inkscape::XML::Node *parent = text->getRepr()->parent(); parent->appendChild(repr); - SPItem *new_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *new_item = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); new_item->doWriteTransform(repr, text->transform); new_item->updateRepr(); Inkscape::GC::release(repr); text->deleteObject(); // delete the orignal flowtext - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); selection->clear(); @@ -181,7 +181,7 @@ text_put_on_path() text->getRepr()->setAttribute("x", NULL); text->getRepr()->setAttribute("y", NULL); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Put text on path")); g_slist_free(text_reprs); } @@ -191,10 +191,10 @@ text_remove_from_path() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text on path</b> to remove it from path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text on path</b> to remove it from path.")); return; } @@ -215,9 +215,9 @@ text_remove_from_path() } if (!did) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No texts-on-paths</b> in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No texts-on-paths</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove text from path")); selection->setList(g_slist_copy((GSList *) selection->itemList())); // reselect to update statusbar description } @@ -256,10 +256,10 @@ text_remove_all_kerns() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); return; } @@ -280,9 +280,9 @@ text_remove_all_kerns() } if (!did) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove manual kerns")); } } @@ -294,16 +294,16 @@ text_flow_into_shape() if (!desktop) return; - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); if (!text || !shape || g_slist_length((GSList *) selection->itemList()) < 2) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); return; } @@ -375,7 +375,7 @@ text_flow_into_shape() DocumentUndo::done(doc, SP_VERB_CONTEXT_TEXT, _("Flow text into shape")); - sp_desktop_selection(desktop)->set(SP_ITEM(root_object)); + desktop->getSelection()->set(SP_ITEM(root_object)); Inkscape::GC::release(root_repr); Inkscape::GC::release(region_repr); @@ -388,14 +388,14 @@ text_unflow () if (!desktop) return; - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!flowtext_in_selection(selection) || g_slist_length((GSList *) selection->itemList()) < 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); return; } @@ -477,10 +477,10 @@ flowtext_to_text() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>flowed text(s)</b> to convert.")); return; } @@ -497,7 +497,7 @@ flowtext_to_text() continue; if (!SP_FLOWTEXT(item)->layout.outputExists()) { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::WARNING_MESSAGE, _("The flowed text(s) must be <b>visible</b> in order to be converted.")); return; @@ -512,7 +512,7 @@ flowtext_to_text() Inkscape::XML::Node *parent = item->getRepr()->parent(); parent->addChild(repr, item->getRepr()); - SPItem *new_item = reinterpret_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *new_item = reinterpret_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); new_item->doWriteTransform(repr, item->transform); new_item->updateRepr(); @@ -525,12 +525,12 @@ flowtext_to_text() g_slist_free(items); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_FLOWTEXT_TO_TEXT, _("Convert flowed text to text")); selection->setReprList(reprs); } else { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::ERROR_MESSAGE, _("<b>No flowed text(s)</b> to convert in the selection.")); } diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 47964880c..4a962ab4c 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -1321,23 +1321,23 @@ static unsigned char_index_of_iterator(Glib::ustring const &string, Glib::ustrin return n; } +// Move to style.h? /** applies the given style string on top of the existing styles for \a item, as opposed to sp_style_merge_from_style_string which merges its parameter underneath the existing styles (ie ignoring already set properties). */ static void overwrite_style_with_string(SPObject *item, gchar const *style_string) { - SPStyle *new_style = sp_style_new(item->document); - sp_style_merge_from_style_string(new_style, style_string); + SPStyle style(item->document); + style.mergeString(style_string); gchar const *item_style_string = item->getRepr()->attribute("style"); if (item_style_string && *item_style_string) { - sp_style_merge_from_style_string(new_style, item_style_string); + style.mergeString(item_style_string); } - gchar *new_style_string = sp_style_write_string(new_style); - sp_style_unref(new_style); - item->getRepr()->setAttribute("style", new_style_string && *new_style_string ? new_style_string : NULL); - g_free(new_style_string); + Glib::ustring new_style_string = style.write(); + item->getRepr()->setAttribute("style", new_style_string.empty() ? NULL : new_style_string.c_str()); } +// Move to style.h? /** Returns true if the style of \a parent and the style of \a child are equivalent (and hence the children of both will appear the same). It is a limitation of the current implementation that \a parent must be a (not @@ -1349,14 +1349,14 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi // implications too large for me to feel safe fixing, but mainly because the css spec // requires that the computed value is inherited, not the specified value. g_assert(parent->isAncestorOf(child)); - gchar *parent_style = sp_style_write_string(parent->style, SP_STYLE_FLAG_ALWAYS); + + Glib::ustring parent_style = parent->style->write( SP_STYLE_FLAG_ALWAYS ); + // we have to write parent_style then read it again, because some properties format their values // differently depending on whether they're set or not (*cough*dash-offset*cough*) - SPStyle *parent_spstyle = sp_style_new(parent->document); - sp_style_merge_from_style_string(parent_spstyle, parent_style); - g_free(parent_style); - parent_style = sp_style_write_string(parent_spstyle, SP_STYLE_FLAG_ALWAYS); - sp_style_unref(parent_spstyle); + SPStyle parent_spstyle(parent->document); + parent_spstyle.mergeString(parent_style.c_str()); + parent_style = parent_spstyle.write(SP_STYLE_FLAG_ALWAYS); Glib::ustring child_style_construction; while (child != parent) { @@ -1369,13 +1369,12 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi child = child->parent; } child_style_construction.insert(0, parent_style); - SPStyle *child_spstyle = sp_style_new(parent->document); - sp_style_merge_from_style_string(child_spstyle, child_style_construction.c_str()); - gchar *child_style = sp_style_write_string(child_spstyle, SP_STYLE_FLAG_ALWAYS); - sp_style_unref(child_spstyle); - bool equal = !strcmp(child_style, parent_style); - g_free(child_style); - g_free(parent_style); + + SPStyle child_spstyle(parent->document); + child_spstyle.mergeString(child_style_construction.c_str()); + Glib::ustring child_style = child_spstyle.write(SP_STYLE_FLAG_ALWAYS); + + bool equal = (child_style == parent_style); // Glib::ustring overloads == operator return equal; } diff --git a/src/text-tag-attributes.h b/src/text-tag-attributes.h index d2bfd854e..7a389ed39 100644 --- a/src/text-tag-attributes.h +++ b/src/text-tag-attributes.h @@ -54,7 +54,7 @@ public: that only fields from \a parent_attrs starting at that index will be used. Basically, the algorithm is that if a child attribute exists that will be used, otherwise the parent attribute will be used, - otherwise the vector will end. */ + otherwise the vector will end. textLength is never merged with parent. */ void mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs *output, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_attrs, unsigned parent_attrs_offset, bool copy_xy, bool copy_dxdyrotate) const; /** Deletes all the values from all the vectors beginning at @@ -127,6 +127,9 @@ public: /** Sets the first coordinates in the x and y vectors. */ void setFirstXY(Geom::Point &point); + SVGLength *getTextLength() { return &(attributes.textLength); } + int getLengthAdjust() { return attributes.lengthAdjust; } + private: /// This holds the actual values. Inkscape::Text::Layout::OptionalTextTagAttrs attributes; @@ -134,7 +137,11 @@ private: /** Does the reverse of readSingleAttribute(), converting a vector<> to its SVG string representation and writing it in to \a node. Used by writeTo(). */ - static void writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector); + static void writeSingleAttributeVector(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector); + + /** Writes a single length value to \a node. Used by + writeTo(). */ + static void writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length); /** Does mergeInto() for one member of #attributes. If \a overlay_list is NULL then it does a simple copy of parent elements, starting at diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 59dd6f254..69138463d 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -25,7 +25,7 @@ #include "trace/imagemap-gdk.h" #include <inkscape.h> -#include <desktop-handles.h> +#include "desktop.h" #include "message-stack.h" #include <sp-path.h> #include <svg/path-string.h> @@ -510,7 +510,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceBrightnessMulti(GdkP SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), traceCount++, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + desktop->getMessageStack()->flash(Inkscape::NORMAL_MESSAGE, msg); } } } @@ -573,7 +573,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceQuant(GdkPixbuf * th SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), colorIndex, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + desktop->getMessageStack()->flash(Inkscape::NORMAL_MESSAGE, msg); } } }// for colorIndex diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index cb83541e3..cc3d000a3 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -16,7 +16,7 @@ #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "message-stack.h" @@ -51,9 +51,9 @@ SPImage *Tracer::getSelectedSPImage() return NULL; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); if (!sel) { char *msg = _("Select an <b>image</b> to trace"); @@ -217,9 +217,9 @@ Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gd return Glib::RefPtr<Gdk::Pixbuf>(NULL); } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); if (!sel) { char *msg = _("Select an <b>image</b> to trace"); @@ -397,9 +397,9 @@ void Tracer::traceThread() return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!SP_ACTIVE_DOCUMENT) { diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index e5c605889..98a5a224c 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -4,8 +4,8 @@ set(ui_SRC control-manager.cpp dialog-events.cpp draw-anchor.cpp - interface.cpp - object-edit.cpp + interface.cpp + object-edit.cpp previewholder.cpp shape-editor.cpp tools-switch.cpp diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 931a295d8..94a1eb2dc 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -37,7 +37,7 @@ #include "inkscape.h" #include "io/stringstream.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" // for sp_desktop_set_style, used in _pasteStyle #include "document.h" #include "document-private.h" @@ -107,7 +107,7 @@ class ClipboardManagerImpl : public ClipboardManager { public: virtual void copy(SPDesktop *desktop); virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *); - virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style); + virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol); virtual bool paste(SPDesktop *desktop, bool in_place); virtual bool pasteStyle(SPDesktop *desktop); virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y); @@ -201,7 +201,7 @@ void ClipboardManagerImpl::copy(SPDesktop *desktop) if ( desktop == NULL ) { return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Special case for when the gradient dragger is active - copies gradient color if (desktop->event_context->get_drag()) { @@ -303,7 +303,7 @@ void ClipboardManagerImpl::copyPathParameter(Inkscape::LivePathEffect::PathParam * Copy a symbol from the symbol dialog. * @param symbol The Inkscape::XML::Node for the symbol. */ -void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* style) +void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol) { //std::cout << "ClipboardManagerImpl::copySymbol" << std::endl; if ( symbol == NULL ) { @@ -326,10 +326,28 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* Glib::ustring id("#"); id += symbol->attribute("id"); + gdouble scale_units = 1; // scale from "px" to "document-units" + Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); + if (nv_repr->attribute("inkscape:document-units")) + scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); + SPObject *cmobj = _clipboardSPDoc->getObjectByRepr(repr); + if (cmobj && !user_symbol) { // convert only stock symbols + if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { + dynamic_cast<SPGroup *>(cmobj)->scaleChildItemsRec(Geom::Scale(scale_units), + Geom::Point(0, SP_ACTIVE_DESKTOP->getDocument()->getHeight().value("px")), + false); + } + } + Inkscape::XML::Node *use = _doc->createElement("svg:use"); use->setAttribute("xlink:href", id.c_str() ); // Set a default style in <use> rather than <symbol> so it can be changed. use->setAttribute("style", style ); + if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { + gchar *transform_str = sp_svg_transform_write(Geom::Scale(1.0/scale_units)); + use->setAttribute("transform", transform_str); + g_free(transform_str); + } _root->appendChild(use); // This min and max sets offsets, we don't have any so set to zero. @@ -428,7 +446,7 @@ bool ClipboardManagerImpl::pasteStyle(SPDesktop *desktop) } // check whether something is selected - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste style to.")); return false; @@ -481,7 +499,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a if ( desktop == NULL ) { return false; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste size to.")); return false; @@ -544,7 +562,7 @@ bool ClipboardManagerImpl::pastePathEffect(SPDesktop *desktop) return false; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection && selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste live path effect to.")); return false; @@ -918,15 +936,18 @@ bool ClipboardManagerImpl::_pasteImage(SPDocument *doc) } Inkscape::Extension::Extension *png = *i; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring attr = prefs->getString("/dialogs/import/link"); + Glib::ustring attr_saved = prefs->getString("/dialogs/import/link"); + bool ask_saved = prefs->getBool("/dialogs/import/ask"); prefs->setString("/dialogs/import/link", "embed"); + prefs->setBool("/dialogs/import/ask", false); png->set_gui(false); gchar *filename = g_build_filename( g_get_tmp_dir(), "inkscape-clipboard-import", NULL ); img->save(filename, "png"); file_import(doc, filename, png); g_free(filename); - prefs->setString("/dialogs/import/link", attr); + prefs->setString("/dialogs/import/link", attr_saved); + prefs->setBool("/dialogs/import/ask", ask_saved); png->set_gui(true); return true; diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h index b565740c3..9f3b6cbdb 100644 --- a/src/ui/clipboard.h +++ b/src/ui/clipboard.h @@ -44,7 +44,7 @@ class ClipboardManager { public: virtual void copy(SPDesktop *desktop) = 0; virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *) = 0; - virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style) = 0; + virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol = true) = 0; virtual bool paste(SPDesktop *desktop, bool in_place = false) = 0; virtual bool pasteStyle(SPDesktop *desktop) = 0; virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y) = 0; diff --git a/src/ui/dialog-events.cpp b/src/ui/dialog-events.cpp index 6bd93bbc3..5bc8088a1 100644 --- a/src/ui/dialog-events.cpp +++ b/src/ui/dialog-events.cpp @@ -6,7 +6,7 @@ * bulia byak <bulia@dr.com> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> * - * Copyright (C) 2003-2007 Authors + * Copyright (C) 2003-2014 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -25,7 +25,7 @@ #include "macros.h" #include <gtk/gtk.h> #include "desktop.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "preferences.h" #include "ui/tools/tool-base.h" @@ -183,12 +183,11 @@ void sp_transientize(GtkWidget *dialog) void on_transientize (SPDesktop *desktop, win_data *wd ) { - sp_transientize_callback (0, desktop, wd); + sp_transientize_callback (desktop, wd); } void -sp_transientize_callback ( InkscapeApplication * /*inkscape*/, - SPDesktop *desktop, win_data *wd ) +sp_transientize_callback ( SPDesktop *desktop, win_data *wd ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint transient_policy = prefs->getIntLimited( "/options/transientpolicy/value", 1, 0, 2); diff --git a/src/ui/dialog-events.h b/src/ui/dialog-events.h index b33eb3f38..b4a5d7c35 100644 --- a/src/ui/dialog-events.h +++ b/src/ui/dialog-events.h @@ -4,7 +4,7 @@ /* Authors: * bulia byak <bulia@dr.com> * - * Copyright (C) 2003 authors + * Copyright (C) 2003-2014 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -28,8 +28,6 @@ class Entry; } class SPDesktop; - -struct InkscapeApplication; typedef struct { GtkWidget *win; @@ -53,14 +51,14 @@ void sp_transientize ( GtkWidget *win ); void on_transientize ( SPDesktop *desktop, win_data *wd ); -void sp_transientize_callback ( InkscapeApplication *inkscape, - SPDesktop *desktop, +void sp_transientize_callback ( SPDesktop *desktop, win_data *wd ); void on_dialog_hide (GtkWidget *w); void on_dialog_unhide (GtkWidget *w); -gboolean sp_dialog_hide (GObject *object, gpointer data); -gboolean sp_dialog_unhide (GObject *object, gpointer data); + +//gboolean sp_dialog_hide (GObject *object, gpointer data); +//gboolean sp_dialog_unhide (GObject *object, gpointer data); #endif diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 26a59ce2c..cbdae1cb0 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -101,7 +101,7 @@ ink_common_sources += \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ ui/dialog/tags.cpp \ - ui/dialpg/tags.h \ + ui/dialog/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 50b35ca2f..81f48e6ef 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -470,6 +470,7 @@ void AboutBox::initStrings() { "Arman Aksoy <armish@linux-sevenler.de>, 2003.\n" "Arpad Biro <biro_arpad@yahoo.com>, 2004, 2005.\n" "Benedikt Roth <Benedikt.Roth@gmx.net>, 2000.\n" +"Benjamin Weis <benjamin.weis@gmx.com>, 2014.\n" "Benno Schulenberg <benno@vertaalt.nl>, 2008.\n" "Boštjan Špetič <igzebedze@cyberpipe.org>, 2004, 2005.\n" "Brisa Francesco <fbrisa@yahoo.it>, 2000.\n" @@ -492,7 +493,7 @@ void AboutBox::initStrings() { "Elias Norberg <elno0959 at student.su.se>, 2009.\n" "Equipe de Tradução Inkscape Brasil <www.inkscapebrasil.org>, 2007.\n" "Fatih Demir <kabalak@gtranslator.org>, 2000.\n" -"Firas Hanife <FirasHanife@gmail.com>, 2014.\n" +"Firas Hanife <FirasHanife@gmail.com>, 2014-2015.\n" "Foppe Benedictus <foppe.benedictus@gmail.com>, 2007-2009.\n" "Francesc Dorca <f.dorca@filnet.es>, 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador <serrador@arrakis.es>, 2003.\n" @@ -500,6 +501,7 @@ void AboutBox::initStrings() { "Frederic Rodrigo <f.rodrigo free.fr>, 2004-2005.\n" "Ge'ez Frontier Foundation <locales@geez.org>, 2002.\n" "George Boukeas <boukeas@gmail.com>, 2011.\n" +"Heiko Wöhrle <mail@heikowoehrle.de>, 2014.\n" "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" "Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n" "Ilia Penev <lichopicho@gmail.com>, 2006.\n" @@ -564,7 +566,7 @@ void AboutBox::initStrings() { "Stefan Graubner <pflaumenmus92@gmx.net>, 2005.\n" "Supranee Thirawatthanasuk <supranee@opentle.org>, 2006.\n" "Takeshi Aihana <aihana@muc.biglobe.ne.jp>, 2000, 2001.\n" -"Tim Sheridan <tim.sheridan@gmail.com>, 2007-2011.\n" +"Tim Sheridan <tghs@tghs.net>, 2007-2014.\n" "Theppitak Karoonboonyanan <thep@linux.thai.net>, 2006.\n" "Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n" "Toshifumi Sato <sato@centrosystem.com>, 2005.\n" diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 431da7ad1..65bc94011 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -24,7 +24,7 @@ #include "align-and-distribute.h" #include <2geom/transforms.h> #include "ui/widget/spinbutton.h" -#include "desktop-handles.h" + #include "unclump.h" #include "document.h" #include "enums.h" @@ -91,7 +91,7 @@ Action::Action(const Glib::ustring &id, void ActionAlign::do_action(SPDesktop *desktop, int index) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -123,10 +123,10 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) focus = selection->smallestItem(horiz); break; case PAGE: - b = sp_desktop_document(desktop)->preferredBounds(); + b = desktop->getDocument()->preferredBounds(); break; case DRAWING: - b = sp_desktop_document(desktop)->getRoot()->desktopPreferredBounds(); + b = desktop->getDocument()->getRoot()->desktopPreferredBounds(); break; case SELECTION: b = selection->preferredBounds(); @@ -152,7 +152,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) for (std::list<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it) { - sp_desktop_document (desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); if (!sel_as_group) b = (*it)->desktopPreferredBounds(); if (b && (!focus || (*it) != focus)) { @@ -167,7 +167,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) } if (changed) { - DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done( desktop->getDocument() , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Align")); } } @@ -247,7 +247,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -337,7 +337,7 @@ private : prefs->setInt("/options/clonecompensation/value", saved_compensation); if (changed) { - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done( desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Distribute")); } } @@ -458,13 +458,12 @@ private : // xGap and yGap are the minimum space required between bounding rectangles. double const xGap = removeOverlapXGap.get_value(); double const yGap = removeOverlapYGap.get_value(); - removeoverlap(sp_desktop_selection(_dialog.getDesktop())->itemList(), - xGap, yGap); + removeoverlap(_dialog.getDesktop()->getSelection()->itemList(), xGap, yGap); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Remove overlaps")); } }; @@ -490,12 +489,12 @@ private : int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(sp_desktop_selection(_dialog.getDesktop())->itemList()); + graphlayout(_dialog.getDesktop()->getSelection()->itemList()); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); } }; @@ -547,7 +546,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -588,7 +587,7 @@ private : // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Exchange Positions")); } }; @@ -617,12 +616,12 @@ private : int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - unclump ((GSList *) sp_desktop_selection(_dialog.getDesktop())->itemList()); + unclump ((GSList *) _dialog.getDesktop()->getSelection()->itemList()); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Unclump")); } }; @@ -644,7 +643,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -677,7 +676,7 @@ private : it != selected.end(); ++it) { - sp_desktop_document (desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect item_box = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds(); if (item_box) { // find new center, staying within bbox @@ -694,7 +693,7 @@ private : // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Randomize positions")); } }; @@ -743,7 +742,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -797,7 +796,7 @@ private : } if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Distribute text baselines")); } @@ -820,7 +819,7 @@ private : } if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Align text baselines")); } } @@ -829,14 +828,14 @@ private : -static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) +static void on_tool_changed(AlignAndDistribute *daad) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); } -static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) +static void on_selection_changed(AlignAndDistribute *daad) { daad->randomize_bbox = Geom::OptRect(); } @@ -1044,10 +1043,10 @@ AlignAndDistribute::AlignAndDistribute() contents->pack_start(_nodesFrame, true, true); //Connect to the global tool change signal - g_signal_connect (G_OBJECT (INKSCAPE), "set_eventcontext", G_CALLBACK (on_tool_changed), this); + _toolChangeConn = INKSCAPE.signal_eventcontext_set.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this))); // Connect to the global selection change, to invalidate cached randomize_bbox - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); + _selChangeConn = INKSCAPE.signal_selection_changed.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_selection_changed), this))); randomize_bbox = Geom::OptRect(); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &AlignAndDistribute::setDesktop) ); @@ -1055,18 +1054,18 @@ AlignAndDistribute::AlignAndDistribute() show_all_children(); - on_tool_changed (NULL, NULL, this); // set current mode + on_tool_changed (this); // set current mode } AlignAndDistribute::~AlignAndDistribute() { - sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this); - for (std::list<Action *>::iterator it = _actionList.begin(); it != _actionList.end(); ++it) { delete *it; } + _toolChangeConn.disconnect(); + _selChangeConn.disconnect(); _desktopChangeConn.disconnect(); _deskTrack.disconnect(); } @@ -1075,7 +1074,7 @@ void AlignAndDistribute::setTargetDesktop(SPDesktop *desktop) { if (_desktop != desktop) { _desktop = desktop; - on_tool_changed (NULL, NULL, this); + on_tool_changed (this); } } diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index dfd84535b..eecc30ff8 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -127,7 +127,8 @@ protected: SPDesktop *_desktop; DesktopTracker _deskTrack; sigc::connection _desktopChangeConn; - + sigc::connection _toolChangeConn; + sigc::connection _selChangeConn; private: AlignAndDistribute(AlignAndDistribute const &d); AlignAndDistribute& operator=(AlignAndDistribute const &d); diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 5ef885ab2..fede30b26 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1,5 +1,6 @@ -/** @file +/** + * @file * Clone tiling dialog */ /* Authors: @@ -26,7 +27,7 @@ #include <gtkmm/adjustment.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/cairo-utils.h" #include "display/drawing.h" #include "display/drawing-context.h" @@ -75,15 +76,12 @@ static gdouble trace_zoom; static SPDocument *trace_doc = NULL; -CloneTiler::CloneTiler (void) : +CloneTiler::CloneTiler () : UI::Widget::Panel ("", "/dialogs/clonetiler/", SP_VERB_DIALOG_CLONETILER), dlg(NULL), desktop(NULL), deskTrack(), - table_row_labels(NULL), - selectChangedConn(), - subselChangedConn(), - selectModifiedConn() + table_row_labels(NULL) { Gtk::Box *contents = _getContents(); contents->set_spacing(0); @@ -1095,7 +1093,7 @@ CloneTiler::CloneTiler (void) : // unitmenu unit_menu = new Inkscape::UI::Widget::UnitMenu(); unit_menu->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - unit_menu->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); + unit_menu->setUnit(SP_ACTIVE_DESKTOP->getNamedView()->display_units->abbr); unitChangedConn = unit_menu->signal_changed().connect(sigc::mem_fun(*this, &CloneTiler::clonetiler_unit_changed)); { @@ -1272,12 +1270,13 @@ CloneTiler::CloneTiler (void) : // connect to global selection changed signal (so we can change desktops) and // external_change (so we're not fooled by undo) - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (clonetiler_change_selection), dlg); - g_signal_connect (G_OBJECT (INKSCAPE), "external_change", G_CALLBACK (clonetiler_external_change), dlg); - g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), G_OBJECT (INKSCAPE)); + selectChangedConn = INKSCAPE.signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_change_selection), dlg)); + externChangedConn = INKSCAPE.signal_external_change.connect (sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_external_change), dlg)); + + g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), this); // update now - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); + clonetiler_change_selection (SP_ACTIVE_DESKTOP->getSelection(), dlg); } { @@ -1349,7 +1348,7 @@ void CloneTiler::on_picker_color_changed(guint rgba) is_updating = false; } -void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +void CloneTiler::clonetiler_change_selection(Inkscape::Selection *selection, GtkWidget *dlg) { GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles")); GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); @@ -1378,16 +1377,18 @@ void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, } } -void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg) +void CloneTiler::clonetiler_external_change(GtkWidget *dlg) { - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); + clonetiler_change_selection (SP_ACTIVE_DESKTOP->getSelection(), dlg); } -void CloneTiler::clonetiler_disconnect_gsignal(GObject *widget, gpointer source) +void CloneTiler::clonetiler_disconnect_gsignal(GObject *, gpointer source) { - if (source && G_IS_OBJECT(source)) { - sp_signal_disconnect_by_data (source, widget); - } + g_return_if_fail(source != NULL); + + CloneTiler* dlg = reinterpret_cast<CloneTiler*>(source); + dlg->selectChangedConn.disconnect(); + dlg->externChangedConn.disconnect(); } Geom::Affine CloneTiler::clonetiler_get_transform( @@ -2002,7 +2003,7 @@ bool CloneTiler::clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); } - if (SP_IS_USE(tile) && + if (dynamic_cast<SPUse *>(tile) && tile->getRepr()->attribute("xlink:href") && (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && tile->getRepr()->attribute("inkscape:tiled-clone-of") && @@ -2025,8 +2026,10 @@ void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) return; for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { - if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) - SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + SPItem *item = dynamic_cast<SPItem *>(o); + if (item && clonetiler_is_a_clone_of(o, NULL)) { + item->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + } clonetiler_trace_hide_tiled_clones_recursively (o); } } @@ -2090,11 +2093,11 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to unclump.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to unclump.")); return; } @@ -2109,13 +2112,13 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) } } - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); unclump (to_unclump); g_slist_free (to_unclump); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Unclump tiled clones")); } @@ -2141,11 +2144,11 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to remove.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to remove.")); return; } @@ -2160,14 +2163,16 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d } } for (GSList *i = to_delete; i; i = i->next) { - SP_OBJECT(i->data)->deleteObject(); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + g_assert(obj != NULL); + obj->deleteObject(); } g_slist_free (to_delete); - clonetiler_change_selection (NULL, selection, dlg); + clonetiler_change_selection (selection, dlg); if (do_undo) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Delete tiled clones")); } } @@ -2211,17 +2216,17 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) return; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select an <b>object</b> to clone.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an <b>object</b> to clone.")); return; } // Check if more than one object is selected. if (g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, <b>group</b> them and <b>clone the group</b>.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, <b>group</b> them and <b>clone the group</b>.")); return; } @@ -2246,7 +2251,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); - double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit()); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", &desktop->getDocument()->getSVGUnit()); double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); @@ -2330,9 +2335,9 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPItem *item = dynamic_cast<SPItem *>(obj); if (dotrace) { - clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); + clonetiler_trace_setup (desktop->getDocument(), 1.0, item); } Geom::Point center; @@ -2606,24 +2611,25 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) parent->getRepr()->appendChild(clone); if (blur > 0.0) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); + SPObject *clone_object = desktop->getDocument()->getObjectByRepr(clone); double perimeter = perimeter_original * t.descrim(); double radius = blur * perimeter; // this is necessary for all newly added clones to have correct bboxes, // otherwise filters won't work: - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); // it's hard to figure out exact width/height of the tile without having an object // that we can take bbox of; however here we only need a lower bound so that blur // margins are not too small, and the perimeter should work - SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); + SPFilter *constructed = new_filter_gaussian_blur(desktop->getDocument(), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); sp_style_set_property_url (clone_object, "filter", constructed, false); } if (center_set) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); - if (clone_object && SP_IS_ITEM(clone_object)) { + SPObject *clone_object = desktop->getDocument()->getObjectByRepr(clone); + SPItem *item = dynamic_cast<SPItem *>(clone_object); + if (clone_object && item) { clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center)); + item->setCenter(desktop->doc2dt(new_center)); clone_object->updateRepr(); } } @@ -2637,11 +2643,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_trace_finish (); } - clonetiler_change_selection (NULL, selection, dlg); + clonetiler_change_selection (selection, dlg); desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Create tiled clones")); } diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index 70da86338..e5f5638b2 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -57,8 +57,8 @@ protected: static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); static void clonetiler_unclump(GtkWidget */*widget*/, void *); - static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); - static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_change_selection(Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(GtkWidget *dlg); static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); static guint clonetiler_number_of_clones(SPObject *obj); @@ -129,6 +129,7 @@ private: sigc::connection desktopChangeConn; sigc::connection selectChangedConn; + sigc::connection externChangedConn; sigc::connection subselChangedConn; sigc::connection selectModifiedConn; sigc::connection color_changed_connection; diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index bab7e18e1..a49a47d5c 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -29,7 +29,7 @@ #include "color-item.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/cairo-utils.h" #include "document.h" @@ -476,7 +476,7 @@ void ColorItem::_updatePreviews() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); + SPDocument* document = desktop->getDocument(); Inkscape::XML::Node *rroot = document->getReprRoot(); if ( rroot ) { @@ -706,7 +706,7 @@ void ColorItem::buttonClicked(bool secondary) sp_desktop_set_style(desktop, css); sp_repr_css_attr_unref(css); - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); + DocumentUndo::done( desktop->getDocument(), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); } } diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 3ed998252..0659de67b 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -22,7 +22,6 @@ DesktopTracker::DesktopTracker() : desktop(0), widget(0), hierID(0), - inkID(0), trackActive(false), desktopChangedSig() { @@ -41,7 +40,10 @@ void DesktopTracker::connect(GtkWidget *widget) // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); - inkID = g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(activateDesktopCB), this ); + inkID = INKSCAPE.signal_activate_desktop.connect( + sigc::bind( + sigc::ptr_fun(&DesktopTracker::activateDesktopCB), this) + ); GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); if (wdgt && !base) { @@ -60,11 +62,8 @@ void DesktopTracker::disconnect() } hierID = 0; } - if (inkID) { - if (INKSCAPE) { - g_signal_handler_disconnect(G_OBJECT(INKSCAPE), inkID); - } - inkID = 0; + if (inkID.connected()) { + inkID.disconnect(); } } @@ -94,12 +93,12 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot<void, S return desktopChangedSig.connect(slot); } -gboolean DesktopTracker::activateDesktopCB(InkscapeApplication */*inkscape*/, SPDesktop *desktop, DesktopTracker *self ) +void DesktopTracker::activateDesktopCB(SPDesktop *desktop, DesktopTracker *self ) { if (self && self->trackActive) { self->setDesktop(desktop); } - return FALSE; + //return FALSE; } bool DesktopTracker::hierarchyChangeCB(GtkWidget * /*widget*/, GtkWidget* /*prev*/, DesktopTracker *self) diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index 7b944ddfa..8cb205a35 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -36,7 +36,7 @@ public: sigc::connection connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot ); private: - static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static void activateDesktopCB(SPDesktop *desktop, DesktopTracker *self ); static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); void handleHierarchyChange(); @@ -46,7 +46,7 @@ private: SPDesktop *desktop; GtkWidget *widget; gulong hierID; - gulong inkID; + sigc::connection inkID; bool trackActive; sigc::signal<void, SPDesktop*> desktopChangedSig; }; diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 213965a18..27d88bae7 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -25,7 +25,7 @@ #include "inkscape.h" #include "ui/tools/tool-base.h" #include "desktop.h" -#include "desktop-handles.h" + #include "shortcuts.h" #include "preferences.h" #include "ui/interface.h" @@ -41,12 +41,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) -{ - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onDesktopActivated (desktop); -} - gboolean sp_retransientize_again(gpointer dlgPtr) { Dialog *dlg = static_cast<Dialog *>(dlgPtr); @@ -54,30 +48,6 @@ gboolean sp_retransientize_again(gpointer dlgPtr) return FALSE; // so that it is only called once } -void sp_dialog_shutdown(GObject * /*object*/, gpointer dlgPtr) -{ - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onShutdown(); -} - - -static void hideCallback(GObject * /*object*/, gpointer dlgPtr) -{ - g_return_if_fail( dlgPtr != NULL ); - - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onHideF12(); -} - -static void unhideCallback(GObject * /*object*/, gpointer dlgPtr) -{ - g_return_if_fail( dlgPtr != NULL ); - - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onShowF12(); -} - - //===================================================================== Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_path, int verb_num, @@ -103,10 +73,10 @@ Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_pat _behavior = behavior_factory(*this); _desktop = SP_ACTIVE_DESKTOP; - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_retransientize), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "shut_down", G_CALLBACK(sp_dialog_shutdown), (void *)this); + INKSCAPE.signal_activate_desktop.connect(sigc::mem_fun(*this, &Dialog::onDesktopActivated)); + INKSCAPE.signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dialog::onHideF12)); + INKSCAPE.signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dialog::onShowF12)); + INKSCAPE.signal_shut_down.connect(sigc::mem_fun(*this, &Dialog::onShutdown)); Glib::wrap(gobj())->signal_event().connect(sigc::mem_fun(*this, &Dialog::_onEvent)); Glib::wrap(gobj())->signal_key_press_event().connect(sigc::mem_fun(*this, &Dialog::_onKeyPress)); @@ -340,7 +310,7 @@ void Dialog::_defocus() Inkscape::Selection* Dialog::_getSelection() { - return sp_desktop_selection(SP_ACTIVE_DESKTOP); + return SP_ACTIVE_DESKTOP->getSelection(); } } // namespace Dialog diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h index ccff43a56..9c7efd47b 100644 --- a/src/ui/dialog/dialog.h +++ b/src/ui/dialog/dialog.h @@ -30,7 +30,6 @@ namespace Dialog { enum BehaviorType { FLOATING, DOCK }; -void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr); gboolean sp_retransientize_again(gpointer dlgPtr); void sp_dialog_shutdown(GObject *object, gpointer dlgPtr); diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 77ea175d9..da1facc08 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -20,7 +20,7 @@ #include "document-metadata.h" #include "desktop.h" -#include "desktop-handles.h" + #include "inkscape.h" #include "rdf.h" #include "sp-namedview.h" @@ -100,7 +100,7 @@ DocumentMetadata::init() { update(); - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); show_all_children(); @@ -108,7 +108,7 @@ DocumentMetadata::init() DocumentMetadata::~DocumentMetadata() { - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->removeListenerByData (this); for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); ++it) @@ -217,23 +217,23 @@ void DocumentMetadata::update() void DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); update(); } void -DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) +DocumentMetadata::_handleActivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); update(); } void -DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) +DocumentMetadata::_handleDeactivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->removeListenerByData(this); } diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 77084bc3d..cde5d92fd 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -28,6 +28,7 @@ # include <gtkmm/table.h> #endif +#include "inkscape.h" #include "ui/widget/licensor.h" #include "ui/widget/registry.h" @@ -56,8 +57,8 @@ protected: void init(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); - void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleActivateDesktop(SPDesktop *desktop); + void _handleDeactivateDesktop(SPDesktop *desktop); Gtk::Notebook _notebook; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index dc8a0fee2..af7ca678a 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -26,7 +26,7 @@ #include "document-properties.h" #include "display/canvas-grid.h" #include "document.h" -#include "desktop-handles.h" + #include "desktop.h" #include "inkscape.h" #include "io/sys.h" @@ -114,7 +114,7 @@ DocumentProperties::DocumentProperties() _rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false), _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing but used when exporting to bitmap."), "pagecolor", "inkscape:pageopacity", _wr), _rcp_bord(_("Border _color:"), _("Page border color"), _("Color of the page border"), "bordercolor", "borderopacity", _wr), - _rum_deflt(_("Default _units:"), "inkscape:document-units", _wr), + _rum_deflt(_("Display _units:"), "inkscape:document-units", _wr), _page_sizer(_wr), //--------------------------------------------------------------- //General snap options @@ -186,9 +186,9 @@ void DocumentProperties::init() { update(); - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); - Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->getRoot()->getRepr(); + Inkscape::XML::Node *root = getDesktop()->getDocument()->getRoot()->getRepr(); root->addListener (&_repr_events, this); show_all_children(); @@ -197,9 +197,9 @@ void DocumentProperties::init() DocumentProperties::~DocumentProperties() { - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->removeListenerByData (this); - Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->getRoot()->getRepr(); + Inkscape::XML::Node *root = getDesktop()->getDocument()->getRoot()->getRepr(); root->removeListenerByData (this); for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); ++it) @@ -1205,10 +1205,10 @@ void DocumentProperties::removeExternalScript(){ const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); - if (name == script->xlinkhref){ + SPObject* obj = reinterpret_cast<SPObject *>(current->data); + if (obj) { + SPScript* script = dynamic_cast<SPScript *>(obj); + if (script && (name == script->xlinkhref)) { //XML Tree being used directly here while it shouldn't be. Inkscape::XML::Node *repr = obj->getRepr(); @@ -1354,10 +1354,15 @@ void DocumentProperties::populate_script_lists(){ _ExternalScriptsListStore->clear(); _EmbeddedScriptsListStore->clear(); const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent); + if (current) { + SPObject *obj = reinterpret_cast<SPObject *>(current->data); + g_assert(obj != NULL); + _scripts_observer.set(obj->parent); + } while ( current ) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); + SPObject* obj = reinterpret_cast<SPObject *>(current->data); + SPScript* script = dynamic_cast<SPScript *>(obj); + g_assert(script != NULL); if (script->xlinkhref) { Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append()); @@ -1379,7 +1384,7 @@ void DocumentProperties::populate_script_lists(){ void DocumentProperties::update_gridspage() { SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); //remove all tabs while (_grids_notebook.get_n_pages() != 0) { @@ -1423,7 +1428,7 @@ void DocumentProperties::build_gridspage() /// Dissenting view: you want snapping without grid. SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); (void)nv; _grids_label_crea.set_markup(_("<b>Creation</b>")); @@ -1459,7 +1464,7 @@ void DocumentProperties::update() if (_wr.isUpdating()) return; SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); _wr.setUpdating (true); set_sensitive (true); @@ -1475,25 +1480,25 @@ void DocumentProperties::update() _rcb_antialias.set_xml_target(root->getRepr(), dt->getDocument()); _rcb_antialias.setActive(root->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); - if (nv->doc_units) { - _rum_deflt.setUnit (nv->doc_units->abbr); + if (nv->display_units) { + _rum_deflt.setUnit (nv->display_units->abbr); } - double doc_w = sp_desktop_document(dt)->getRoot()->width.value; - Glib::ustring doc_w_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->width.unit)->abbr; + double doc_w = dt->getDocument()->getRoot()->width.value; + Glib::ustring doc_w_unit = unit_table.getUnit(dt->getDocument()->getRoot()->width.unit)->abbr; if (doc_w_unit == "") { doc_w_unit = "px"; - } else if (doc_w_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + } else if (doc_w_unit == "%" && dt->getDocument()->getRoot()->viewBox_set) { doc_w_unit = "px"; - doc_w = sp_desktop_document(dt)->getRoot()->viewBox.width(); + doc_w = dt->getDocument()->getRoot()->viewBox.width(); } - double doc_h = sp_desktop_document(dt)->getRoot()->height.value; - Glib::ustring doc_h_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->height.unit)->abbr; + double doc_h = dt->getDocument()->getRoot()->height.value; + Glib::ustring doc_h_unit = unit_table.getUnit(dt->getDocument()->getRoot()->height.unit)->abbr; if (doc_h_unit == "") { doc_h_unit = "px"; - } else if (doc_h_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + } else if (doc_h_unit == "%" && dt->getDocument()->getRoot()->viewBox_set) { doc_h_unit = "px"; - doc_h = sp_desktop_document(dt)->getRoot()->viewBox.height(); + doc_h = dt->getDocument()->getRoot()->viewBox.height(); } _page_sizer.setDim(Inkscape::Util::Quantity(doc_w, doc_w_unit), Inkscape::Util::Quantity(doc_h, doc_h_unit)); _page_sizer.updateFitMarginsUI(nv->getRepr()); @@ -1587,27 +1592,27 @@ void DocumentProperties::save_default_metadata() void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); Inkscape::XML::Node *root = document->getRoot()->getRepr(); root->addListener(&_repr_events, this); update(); } -void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) +void DocumentProperties::_handleActivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); - Inkscape::XML::Node *root = sp_desktop_document(desktop)->getRoot()->getRepr(); + Inkscape::XML::Node *root = desktop->getDocument()->getRoot()->getRepr(); root->addListener(&_repr_events, this); update(); } -void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) +void DocumentProperties::_handleDeactivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->removeListenerByData(this); - Inkscape::XML::Node *root = sp_desktop_document(desktop)->getRoot()->getRepr(); + Inkscape::XML::Node *root = desktop->getDocument()->getRoot()->getRepr(); root->removeListenerByData(this); } @@ -1642,8 +1647,8 @@ static void on_repr_attr_changed(Inkscape::XML::Node *, gchar const *, gchar con void DocumentProperties::onNewGrid() { SPDesktop *dt = getDesktop(); - Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); - SPDocument *doc = sp_desktop_document(dt); + Inkscape::XML::Node *repr = dt->getNamedView()->getRepr(); + SPDocument *doc = dt->getDocument(); Glib::ustring typestring = _grids_combo_gridtype.get_active_text(); CanvasGrid::writeNewGridToRepr(repr, doc, CanvasGrid::getGridTypeFromName(typestring.c_str())); @@ -1660,7 +1665,7 @@ void DocumentProperties::onRemoveGrid() return; SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); Inkscape::CanvasGrid * found_grid = NULL; int i = 0; for (GSList const * l = nv->grids; l != NULL; l = l->next, i++) { // not a very nice fix, but works. @@ -1674,7 +1679,7 @@ void DocumentProperties::onRemoveGrid() // delete the grid that corresponds with the selected tab // when the grid is deleted from SVG, the SPNamedview handler automatically deletes the object, so found_grid becomes an invalid pointer! found_grid->repr->parent()->removeChild(found_grid->repr); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid")); + DocumentUndo::done(dt->getDocument(), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid")); } } @@ -1692,7 +1697,7 @@ void DocumentProperties::onDocUnitChange() } - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); Inkscape::Util::Unit const *old_doc_unit = unit_table.getUnit("px"); if(repr->attribute("inkscape:document-units")) { old_doc_unit = unit_table.getUnit(repr->attribute("inkscape:document-units")); @@ -1703,7 +1708,10 @@ void DocumentProperties::onDocUnitChange() Inkscape::SVGOStringStream os; os << doc_unit->abbr; repr->setAttribute("inkscape:document-units", os.str().c_str()); - + + // Disable changing of SVG Units. The intent here is to change the units in the UI, not the units in SVG. + // This code should be moved (and fixed) once we have an "SVG Units" setting that sets what units are used in SVG data. +#if 0 // Set viewBox if (doc->getRoot()->viewBox_set) { gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); @@ -1755,10 +1763,11 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/rectcorners", transform_rectcorners); prefs->setBool("/options/transform/pattern", transform_pattern); prefs->setBool("/options/transform/gradient", transform_gradient); +#endif doc->setModifiedSinceSave(); - DocumentUndo::done(doc, SP_VERB_NONE, _("Changed document unit")); + DocumentUndo::done(doc, SP_VERB_NONE, _("Changed default display unit")); } } // namespace Dialog diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index ee7e88b18..b1f90b4b7 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -94,8 +94,8 @@ protected: void save_default_metadata(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); - void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleActivateDesktop(SPDesktop *desktop); + void _handleDeactivateDesktop(SPDesktop *desktop); Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer; Gtk::Notebook _notebook; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index a4d8801f7..6d90c792e 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -51,10 +51,10 @@ #include "ui/widget/unit-menu.h" #include "util/units.h" #include "helper/window.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" + #include "sp-item.h" #include "selection.h" #include "file.h" @@ -101,7 +101,6 @@ #define EXPORT_COORD_PRECISION 3 -#include "../../desktop-handles.h" #include "../../document.h" #include "../../document-undo.h" #include "verbs.h" @@ -206,7 +205,7 @@ Export::Export (void) : SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { - unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); + unit_selector.setUnit(desktop->getNamedView()->display_units->abbr); } unitChangedConn = unit_selector.signal_changed().connect(sigc::mem_fun(*this, &Export::onUnitChanged)); unitbox.pack_end(unit_selector, false, false, 0); @@ -537,7 +536,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { + if (l) { l->set_mnemonic_widget(*sb); } @@ -588,7 +587,7 @@ Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ust } if (directory.empty()) { - directory = homedir_path(NULL); + directory = INKSCAPE.homedir_path(NULL); } Glib::ustring filename = Glib::build_filename(directory, id+".png"); @@ -606,7 +605,7 @@ void Export::onBatchClicked () void Export::updateCheckbuttons () { - gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList()); + gint num = g_slist_length((GSList *) SP_ACTIVE_DESKTOP->getSelection()->itemList()); if (num >= 2) { batch_export.set_sensitive(true); batch_export.set_label(g_strdup_printf (ngettext("B_atch export %d selected object","B_atch export %d selected objects",num), num)); @@ -622,7 +621,7 @@ inline void Export::findDefaultSelection() { selection_type key = SELECTION_NUMBER_OF; - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { key = SELECTION_SELECTION; } @@ -660,15 +659,15 @@ inline void Export::findDefaultSelection() */ void Export::onSelectionChanged() { - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); if ((current_key == SELECTION_DRAWING || current_key == SELECTION_PAGE) && - (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false && + (SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false && was_empty) { current_key = SELECTION_SELECTION; selectiontype_buttons[current_key]->set_active(true); } - was_empty = (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty(); + was_empty = (SP_ACTIVE_DESKTOP->getSelection())->isEmpty(); if ( selection && SELECTION_CUSTOM != current_key) { @@ -685,7 +684,7 @@ void Export::onSelectionModified ( guint /*flags*/ ) case SELECTION_DRAWING: if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); if (bbox) { setArea ( bbox->left(), @@ -696,7 +695,7 @@ void Export::onSelectionModified ( guint /*flags*/ ) } break; case SELECTION_SELECTION: - Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); + Sel = SP_ACTIVE_DESKTOP->getSelection(); if (Sel->isEmpty() == false) { Geom::OptRect bbox = Sel->visualBounds(); if (bbox) @@ -736,16 +735,16 @@ void Export::onAreaToggled () SPDocument *doc; Geom::OptRect bbox; bbox = Geom::Rect(Geom::Point(0.0, 0.0),Geom::Point(0.0, 0.0)); - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); /* Notice how the switch is used to 'fall through' here to get various backups. If you modify this without noticing you'll probabaly screw something up. */ switch (key) { case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { - bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); + bbox = SP_ACTIVE_DESKTOP->getSelection()->visualBounds(); /* Only if there is a selection that we can set do we break, otherwise we fall through to the drawing */ @@ -810,15 +809,15 @@ void Export::onAreaToggled () break; } case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { - sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); + sp_selection_get_export_hints (SP_ACTIVE_DESKTOP->getSelection(), filename, &xdpi, &ydpi); /* If we still don't have a filename -- let's build one that's nice */ if (filename.empty()) { const gchar * id = "object"; - const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); + const GSList * reprlst = SP_ACTIVE_DESKTOP->getSelection()->reprList(); for(; reprlst != NULL; reprlst = reprlst->next) { Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; if (repr->attribute("id")) { @@ -1002,8 +1001,8 @@ void Export::onExport () SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) return; - SPNamedView *nv = sp_desktop_namedview(desktop); - SPDocument *doc = sp_desktop_document (desktop); + SPNamedView *nv = desktop->getNamedView(); + SPDocument *doc = desktop->getDocument(); bool exportSuccessful = false; @@ -1011,7 +1010,7 @@ void Export::onExport () if (batch_export.get_active ()) { // Batch export of selected objects - gint num = g_slist_length(const_cast<GSList *>(sp_desktop_selection(desktop)->itemList())); + gint num = g_slist_length(const_cast<GSList *>(desktop->getSelection()->itemList())); gint n = 0; if (num < 1) { @@ -1025,7 +1024,7 @@ void Export::onExport () gint export_count = 0; - for (GSList *i = const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()); i && !interrupted; i = i->next) { + for (GSList *i = const_cast<GSList *>(desktop->getSelection()->itemList()); i && !interrupted; i = i->next) { SPItem *item = reinterpret_cast<SPItem *>(i->data); prog_dlg->set_data("current", GINT_TO_POINTER(n)); @@ -1070,7 +1069,7 @@ void Export::onExport () nv->pagecolor, onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking - hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL + hide ? const_cast<GSList *>(desktop->getSelection()->itemList()) : NULL )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1154,12 +1153,12 @@ void Export::onExport () prog_dlg->set_data("total", GINT_TO_POINTER(0)); /* Do export */ - ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(), + ExportResult status = sp_export_png_file(desktop->getDocument(), path.c_str(), Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, nv->pagecolor, onProgressCallback, (void*)prog_dlg, FALSE, - hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL + hide ? const_cast<GSList *>(desktop->getSelection()->itemList()) : NULL ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); @@ -1231,7 +1230,7 @@ void Export::onExport () bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - reprlst = sp_desktop_selection(desktop)->reprList(); + reprlst = desktop->getSelection()->reprList(); for(; reprlst != NULL; reprlst = reprlst->next) { Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data); @@ -1463,8 +1462,8 @@ void Export::detectSize() { i++) { switch (this_test[i]) { case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { + Geom::OptRect bbox = (SP_ACTIVE_DESKTOP->getSelection())->bounds(SPItem::VISUAL_BBOX); if ( bbox && bbox_equal(*bbox,current_bbox)) { key = SELECTION_SELECTION; @@ -1472,7 +1471,7 @@ void Export::detectSize() { } break; case SELECTION_DRAWING: { - SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + SPDocument *doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); @@ -1485,7 +1484,7 @@ void Export::detectSize() { case SELECTION_PAGE: { SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::Point x(0.0, 0.0); Geom::Point y(doc->getWidth().value("px"), diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 5d330f7f0..17cf835cd 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -577,8 +577,9 @@ bool SVGPreview::set(Glib::ustring &fileName, int dialogType) SVGPreview::SVGPreview() { - if (!INKSCAPE) - inkscape_application_init("", false); + // \FIXME Why?!!?? + if (!Inkscape::Application::exists()) + Inkscape::Application::create("", false); document = NULL; viewerGtk = NULL; set_size_request(150, 150); @@ -1083,7 +1084,7 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const Gl } // allow easy access to the user's own templates folder - gchar *templates = profile_path("templates"); + gchar *templates = Inkscape::Application::profile_path("templates"); if (Inkscape::IO::file_test(templates, G_FILE_TEST_EXISTS) && Inkscape::IO::file_test(templates, G_FILE_TEST_IS_DIR) && g_path_is_absolute(templates)) { add_shortcut_folder(templates); diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index c55d55cda..8141f7696 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -16,7 +16,7 @@ */ #include "ui/widget/notebook-page.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "fill-and-stroke.h" diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 35c98ef9c..f2a6bf39d 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -41,8 +41,7 @@ public: virtual void setDesktop(SPDesktop *desktop); - void selectionChanged(InkscapeApplication *inkscape, - Inkscape::Selection *selection); + //void selectionChanged(Inkscape::Selection *selection); void showPageFill(); void showPageStrokePaint(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index bd44846a3..3da0e0043 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -33,7 +33,7 @@ #include <glibmm/stringutils.h> #include "desktop.h" -#include "desktop-handles.h" + #include "dir-util.h" #include "document.h" #include "document-undo.h" @@ -688,7 +688,7 @@ public: private: void select_svg_element(){ - Inkscape::Selection* sel = sp_desktop_selection(_desktop); + Inkscape::Selection* sel = _desktop->getSelection(); if (sel->isEmpty()) return; Inkscape::XML::Node* node = (Inkscape::XML::Node*) g_slist_nth_data((GSList *)sel->reprList(), 0); if (!node || !node->matchAttributeName("id")) return; @@ -1416,7 +1416,7 @@ void FilterEffectsDialog::FilterModifier::setTargetDesktop(SPDesktop *desktop) _selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FilterModifier::on_modified_selection))); } _doc_replaced = desktop->connectDocumentReplaced( sigc::mem_fun(*this, &FilterModifier::on_document_replaced)); - _resource_changed = sp_desktop_document(desktop)->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); + _resource_changed = desktop->getDocument()->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); _dialog.setDesktop(desktop); update_filters(); @@ -1441,7 +1441,7 @@ void FilterEffectsDialog::FilterModifier::on_document_replaced(SPDesktop * /*des // When the selection changes, show the active filter(s) in the dialog void FilterEffectsDialog::FilterModifier::on_change_selection() { - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); update_selection(selection); } @@ -1537,9 +1537,9 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri if(iter) { SPDesktop *desktop = _dialog.getDesktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); SPFilter* filter = (*iter)[_columns.filter]; - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); /* If this filter is the only one used in the selection, unset it */ if((*iter)[_columns.sel] == 1) @@ -1571,7 +1571,7 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri void FilterEffectsDialog::FilterModifier::update_filters() { SPDesktop* desktop = _dialog.getDesktop(); - SPDocument* document = sp_desktop_document(desktop); + SPDocument* document = desktop->getDocument(); const GSList* filters = document->getResourceList("filter"); _model->clear(); @@ -1627,7 +1627,7 @@ void FilterEffectsDialog::FilterModifier::filter_list_button_release(GdkEventBut void FilterEffectsDialog::FilterModifier::add_filter() { - SPDocument* doc = sp_desktop_document(_dialog.getDesktop()); + SPDocument* doc = _dialog.getDesktop()->getDocument(); SPFilter* filter = new_filter(doc); const int count = _model->children().size(); @@ -1937,7 +1937,7 @@ void FilterEffectsDialog::PrimitiveList::remove_selected() //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(prim->getRepr()); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_FILTER_EFFECTS, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove filter primitive")); update(); diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 1a4823e4a..6d8d64607 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -29,7 +29,7 @@ #include "document.h" #include "document-undo.h" #include "selection.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "verbs.h" @@ -238,10 +238,10 @@ Find::Find() show_all_children(); - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); SPItem *item = selection->singleItem(); if (item) { - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { gchar *str; str = sp_te_get_string_multiline (item); entry_find.getEntry()->set_text(str); @@ -343,7 +343,7 @@ bool Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool ca return false; } - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { const gchar *item_text = sp_te_get_string_multiline (item); if (item_text == NULL) { return false; @@ -388,7 +388,7 @@ bool Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casema return false; } - if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching + if (dynamic_cast<SPString *>(item)) { // SPStrings have "on demand" ids which are useless for searching return false; } @@ -561,11 +561,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (check_searchin_text.get_active()) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_text_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_text_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_text_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_text_match(item, text, exact, casematch, _action_replace); } } } @@ -581,11 +584,13 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (ids) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_id_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + if (item_id_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_id_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_id_match(item, text, exact, casematch, _action_replace); } } } @@ -595,12 +600,15 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (style) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_style_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_style_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_style_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_style_match(item, text, exact, casematch, _action_replace); } } } @@ -610,11 +618,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrname) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attr_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_attr_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attr_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attr_match(item, text, exact, casematch, _action_replace); } } } @@ -624,11 +635,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrvalue) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_attrvalue_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attrvalue_match(item, text, exact, casematch, _action_replace); } } } @@ -638,11 +652,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (font) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_font_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_font_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_font_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_font_match(item, text, exact, casematch, _action_replace); } } } @@ -661,34 +678,34 @@ bool Find::item_type_match (SPItem *item) { bool all =check_alltypes.get_active(); - if ( SP_IS_RECT(item)) { + if ( dynamic_cast<SPRect *>(item)) { return ( all ||check_rects.get_active()); - } else if (SP_IS_GENERICELLIPSE(item)) { + } else if (dynamic_cast<SPGenericEllipse *>(item)) { return ( all || check_ellipses.get_active()); - } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { + } else if (dynamic_cast<SPStar *>(item) || dynamic_cast<SPPolygon *>(item)) { return ( all || check_stars.get_active()); - } else if (SP_IS_SPIRAL(item)) { + } else if (dynamic_cast<SPSpiral *>(item)) { return ( all || check_spirals.get_active()); - } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { + } else if (dynamic_cast<SPPath *>(item) || dynamic_cast<SPLine *>(item) || dynamic_cast<SPPolyLine *>(item)) { return (all || check_paths.get_active()); - } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) { + } else if (dynamic_cast<SPText *>(item) || dynamic_cast<SPTSpan *>(item) || dynamic_cast<SPTRef *>(item) || dynamic_cast<SPString *>(item)) { return (all || check_texts.get_active()); - } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! + } else if (dynamic_cast<SPGroup *>(item) && !desktop->isLayer(item) ) { // never select layers! return (all || check_groups.get_active()); - } else if (SP_IS_USE(item)) { + } else if (dynamic_cast<SPUse *>(item)) { return (all || check_clones.get_active()); - } else if (SP_IS_IMAGE(item)) { + } else if (dynamic_cast<SPImage *>(item)) { return (all || check_images.get_active()); - } else if (SP_IS_OFFSET(item)) { + } else if (dynamic_cast<SPOffset *>(item)) { return (all || check_offsets.get_active()); } @@ -699,7 +716,10 @@ GSList *Find::filter_types (GSList *l) { GSList *n = NULL; for (GSList *i = l; i != NULL; i = i->next) { - if (item_type_match (SP_ITEM(i->data))) { + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item_type_match(item)) { n = g_slist_prepend (n, i->data); } } @@ -716,7 +736,7 @@ GSList *Find::filter_list (GSList *l, bool exact, bool casematch) GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) { - if (SP_IS_DEFS(r)) { + if (dynamic_cast<SPDefs *>(r)) { return l; // we're not interested in items in defs } @@ -725,8 +745,8 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM(child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) { - SPItem *item = reinterpret_cast<SPItem *>(child); + SPItem *item = dynamic_cast<SPItem *>(child); + if (item && !child->cloned && !desktop->isLayer(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, child); } @@ -739,16 +759,18 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) GSList *Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked) { for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { - if (SP_IS_ITEM (i->data) && !reinterpret_cast<SPItem *>(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) { - SPItem *item = reinterpret_cast<SPItem *>(i->data); + SPObject *obj = reinterpret_cast<SPObject *>(i->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + if (item && !item->cloned && !desktop->isLayer(item)) { if (!ancestor || ancestor->isAncestorOf(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, i->data); } } } - if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { - l = all_items (SP_OBJECT (i->data), l, hidden, locked); + if (!ancestor || ancestor->isAncestorOf(item)) { + l = all_items(item, l, hidden, locked); } } return l; @@ -802,7 +824,7 @@ void Find::onAction() if (check_scope_layer.get_active()) { l = all_items (desktop->currentLayer(), l, hidden, locked); } else { - l = all_items(sp_desktop_document(desktop)->getRoot(), l, hidden, locked); + l = all_items(desktop->getDocument()->getRoot(), l, hidden, locked); } } guint all = g_slist_length (l); @@ -828,19 +850,22 @@ void Find::onAction() button_replace.set_sensitive(attributenameyok); } - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->setList(n); - scroll_to_show_item (desktop, SP_ITEM(n->data)); + SPObject *obj = reinterpret_cast<SPObject *>(n->data); + SPItem *item = dynamic_cast<SPItem *>(obj); + g_assert(item != NULL); + scroll_to_show_item(desktop, item); if (_action_replace) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); } } else { status.set_text(_("Nothing found")); if (!check_scope_selection.get_active()) { - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); } desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No objects found")); diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index db7bdf222..ae03bdf0e 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -28,7 +28,7 @@ #include "selection.h" #include "ui/dialog-events.h" -#include "desktop-handles.h" + #include "selection-chemistry.h" #include "preferences.h" @@ -134,7 +134,7 @@ FontSubstitution::show(Glib::ustring out, GSList *l) if (cbSelect->get_active()) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->setList(l); } diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index 9bad90e7c..2b9053da9 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -709,13 +709,12 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ ) calcCanInsert(); if (targetDesktop && updateStyle) { - //SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + //SPStyle query(SP_ACTIVE_DOCUMENT); - //int result_family = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - //int result_style = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - //int result_numbers = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + //int result_family = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + //int result_style = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + //int result_numbers = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - //sp_style_unref(query); } } diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 1417b39fa..d3ccb9bde 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -31,7 +31,7 @@ #include "verbs.h" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -165,9 +165,9 @@ void GridArrangeTab::arrange() grid_top = 99999; SPDesktop *desktop = Parent->getDesktop(); - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); const GSList *items = selection ? selection->itemList() : 0; cnt=0; for (; items != NULL; items = items->next) { @@ -347,7 +347,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h g_slist_free (current_row); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_ARRANGE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_ARRANGE, _("Arrange in a grid")); } @@ -567,17 +567,6 @@ void GridArrangeTab::updateSelection() } - -/*########################## -## Experimental -##########################*/ - -static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) -{ - dlg->updateSelection(); -} - - //######################################################################### //## C O N S T R U C T O R / D E S T R U C T O R //######################################################################### @@ -605,7 +594,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) { // Selection Change signal - g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); + INKSCAPE.signal_selection_changed.connect(sigc::hide<0>(sigc::mem_fun(*this, &GridArrangeTab::updateSelection))); } Gtk::Box *contents = this; diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 4519a905f..af8e2cc31 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -24,7 +24,7 @@ #include "document-undo.h" #include "sp-guide.h" #include "sp-namedview.h" -#include "desktop-handles.h" + #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include <glibmm/i18n.h> @@ -216,8 +216,8 @@ void GuidelinePropertiesDialog::_setup() { /* fixme: We should allow percents here too, as percents of the canvas size */ _unit_menu.setUnitType(UNIT_TYPE_LINEAR); _unit_menu.setUnit("px"); - if (_desktop->namedview->doc_units) { - _unit_menu.setUnit( _desktop->namedview->doc_units->abbr ); + if (_desktop->namedview->display_units) { + _unit_menu.setUnit( _desktop->namedview->display_units->abbr ); } _spin_angle.setUnit(_angle_unit_status); diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 468e85d36..b908a90cb 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -35,7 +35,7 @@ #include "ui/widget/frame.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/drawing.h" #include "document.h" #include "inkscape.h" @@ -362,7 +362,7 @@ void IconPreviewPanel::refreshPreview() target = (hold && !targetId.empty()) ? desktop->doc()->getObjectById( targetId.c_str() ) : 0; if ( !target ) { targetId.clear(); - Inkscape::Selection * sel = sp_desktop_selection(desktop); + Inkscape::Selection * sel = desktop->getSelection(); if ( sel ) { //g_message("found a selection to play with"); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index c2da12058..0ea6cf082 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -32,7 +32,7 @@ #include "util/units.h" #include <iostream> #include "enums.h" -#include "desktop-handles.h" + #include "extension/internal/gdkpixbuf-input.h" #include "message-stack.h" #include "style.h" @@ -213,10 +213,10 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects selected</b> to take the style from.")); return; } @@ -225,7 +225,7 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc /* TODO: If each item in the selection has the same style then don't consider it an error. * Maybe we should try to handle multiple selections anyway, e.g. the intersection of the * style attributes for the selected items. */ - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>More than one object selected.</b> Cannot take style from multiple objects.")); return; } @@ -234,6 +234,9 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc if (!css) return; + // remove black-listed properties + css = sp_css_attr_unset_blacklist (css); + // only store text style for the text tool if (prefs_path != "/tools/text") { css = sp_css_attr_unset_text (css); @@ -276,10 +279,14 @@ void InkscapePreferences::AddNewObjectsStyle(DialogPage &p, Glib::ustring const p.add_line( true, "", *hb, "", ""); // style swatch - Gtk::Button* button = Gtk::manage( new Gtk::Button(_("Take from selection"),true)); + Gtk::Button* button = Gtk::manage( new Gtk::Button(_("Take from selection"), true)); StyleSwatch *swatch = 0; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getInt(prefs_path + "/usecurrent")) { + button->set_sensitive(false); + } + SPCSSAttr *css = prefs->getStyle(prefs_path + "/style"); swatch = new StyleSwatch(css, _("This tool's style of new objects")); hb->add(*swatch); @@ -458,7 +465,7 @@ void InkscapePreferences::initPageTools() _page_text.add_line( false, _("Text size unit type:"), _font_unit_type, "", _("Set the type of unit used in the text toolbar and text dialogs"), false); _font_output_px.init ( _("Always output text size in pixels (px)"), "/options/font/textOutputPx", true); - _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); +// _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); this->AddNewObjectsStyle(_page_text, "/tools/text"); @@ -838,7 +845,7 @@ void InkscapePreferences::initPageIO() _save_use_current_dir.init( _("Use current directory for \"Save As ...\""), "/dialogs/save_as/use_current_dir", true); _page_io.add_line( false, "", _save_use_current_dir, "", - _("When this option is on, the \"Save as...\" and \"Save a Copy\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); + _("When this option is on, the \"Save as...\" and \"Save a Copy...\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); _misc_comment.init( _("Add label comments to printing output"), "/printing/debug/show-label-comments", false); _page_io.add_line( false, "", _misc_comment, "", @@ -1739,6 +1746,10 @@ void InkscapePreferences::onKBListKeyboardShortcuts() // Find this group in the tree Glib::ustring group = verb->get_group() ? _(verb->get_group()) : _("Misc"); + Glib::ustring verb_id = verb->get_id(); + if (verb_id .compare(0,26,"org.inkscape.effect.filter") == 0) { + group = _("Filters"); + } Gtk::TreeStore::iterator iter_group; bool found = false; while (path) { @@ -1910,7 +1921,7 @@ void InkscapePreferences::initPageSystem() _page_system.add_group_header( _("System info")); - _sys_user_config.set_text((char const *)profile_path("")); + _sys_user_config.set_text((char const *)Inkscape::Application::profile_path("")); _sys_user_config.set_editable(false); _page_system.add_line(true, _("User config: "), _sys_user_config, "", _("Location of users configuration"), true); diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index d5540b88a..1b8fbb3f7 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -23,7 +23,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" @@ -132,7 +132,7 @@ LayerPropertiesDialog::_apply() g_assert(_strategy != NULL); _strategy->perform(*this); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE, _("Add layer")); _close(); @@ -364,7 +364,7 @@ void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) { (gchar *)name.c_str(), FALSE ); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Rename layer")); // TRANSLATORS: This means "The layer has been renamed" desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Renamed layer")); @@ -399,7 +399,7 @@ void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { if (!name.empty()) { desktop->layer_manager->renameLayer( new_layer, (gchar *)name.c_str(), TRUE ); } - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); desktop->setCurrentLayer(new_layer); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created.")); } diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 9a569725c..3b87597c8 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -23,7 +23,7 @@ #include <vector> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "gtkmm/widget.h" @@ -295,9 +295,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if ( item ) { - if ( SP_IS_LPE_ITEM(item) ) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); - + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if ( lpeitem ) { effect_list_reload(lpeitem); current_lpeitem = lpeitem; @@ -318,25 +317,28 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) button_up.set_sensitive(false); button_down.set_sensitive(false); } - } else if ( SP_IS_USE(item) ) { - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. - set_sensitize_all(true); - showText(_("Click add button to convert clone")); - button_remove.set_sensitive(false); - button_up.set_sensitive(false); - button_down.set_sensitive(false); + } else { + SPUse *use = dynamic_cast<SPUse *>(item); + if ( use ) { + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast<SPShape *>(orig) || + dynamic_cast<SPText *>(orig) ) + { + // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. + set_sensitize_all(true); + showText(_("Click add button to convert clone")); + button_remove.set_sensitive(false); + button_up.set_sensitive(false); + button_down.set_sensitive(false); + } else { + showText(_("Select a path or shape")); + set_sensitize_all(false); + } } else { showText(_("Select a path or shape")); set_sensitize_all(false); } - } else { - showText(_("Select a path or shape")); - set_sensitize_all(false); } } else { showText(_("Only one item can be selected")); @@ -396,7 +398,7 @@ LivePathEffectEditor::setDesktop(SPDesktop *desktop) lpe_list_locked = false; current_desktop = desktop; if (desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection_changed_connection = selection->connectChanged( sigc::bind (sigc::ptr_fun(&lpeeditor_selection_changed), this ) ); selection_modified_connection = selection->connectModified( @@ -423,7 +425,7 @@ LivePathEffectEditor::onAdd() if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if (item) { - if ( SP_IS_LPE_ITEM(item) ) { + if ( dynamic_cast<SPLPEItem *>(item) ) { // show effectlist dialog using Inkscape::UI::Dialog::LivePathEffectAdd; LivePathEffectAdd::show(current_desktop); @@ -439,7 +441,7 @@ LivePathEffectEditor::onAdd() } // If item is a SPRect, convert it to path first: - if ( SP_IS_RECT(item) ) { + if ( dynamic_cast<SPRect *>(item) ) { sp_selected_path_to_curves(sel, current_desktop, false); item = sel->singleItem(); // get new item } @@ -451,41 +453,47 @@ LivePathEffectEditor::onAdd() lpe_list_locked = false; onSelectionChanged(sel); - } - else if ( SP_IS_USE(item) ) { - // item is a clone. do not show effectlist dialog. - // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path - - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // select original - sel->set(orig); - - // delete clone but remember its id and transform - gchar *id = g_strdup(item->getRepr()->attribute("id")); - gchar *transform = g_strdup(item->getRepr()->attribute("transform")); - item->deleteObject(false); - item = NULL; - - // run sp_selection_clone_original_path_lpe - sp_selection_clone_original_path_lpe(current_desktop); - SPItem *new_item = sel->singleItem(); - new_item->getRepr()->setAttribute("id", id); - new_item->getRepr()->setAttribute("transform", transform); - g_free(id); - g_free(transform); - - /// \todo Add the LPE stack of the original path? - - SPDocument *doc = current_desktop->doc(); - DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Create and apply Clone original path effect")); - - lpe_list_locked = false; - onSelectionChanged(sel); + } else { + SPUse *use = dynamic_cast<SPUse *>(item); + if ( use ) { + // item is a clone. do not show effectlist dialog. + // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path + + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast<SPShape *>(orig) || + dynamic_cast<SPText *>(orig) ) + { + // select original + sel->set(orig); + + // delete clone but remember its id and transform + gchar *id = g_strdup(item->getRepr()->attribute("id")); + gchar *transform = g_strdup(item->getRepr()->attribute("transform")); + item->deleteObject(false); + item = NULL; + + // run sp_selection_clone_original_path_lpe + sp_selection_clone_original_path_lpe(current_desktop); + + SPItem *new_item = sel->singleItem(); + // Check that the cloning was successful. We don't want to change the ID of the original referenced path! + if (new_item && (new_item != orig)) { + new_item->getRepr()->setAttribute("id", id); + new_item->getRepr()->setAttribute("transform", transform); + } + g_free(id); + g_free(transform); + + /// \todo Add the LPE stack of the original path? + + SPDocument *doc = current_desktop->doc(); + DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Create and apply Clone original path effect")); + + lpe_list_locked = false; + onSelectionChanged(sel); + } } } } @@ -498,13 +506,14 @@ LivePathEffectEditor::onRemove() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( item && SP_IS_LPE_ITEM(item) ) { - SP_LPE_ITEM(item)->removeCurrentPathEffect(false); + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if ( lpeitem ) { + lpeitem->removeCurrentPathEffect(false); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Remove path effect") ); - effect_list_reload(SP_LPE_ITEM(item)); + effect_list_reload(lpeitem); } } @@ -515,10 +524,11 @@ void LivePathEffectEditor::onUp() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if ( lpeitem ) { lpeitem->upCurrentPathEffect(); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Move path effect up") ); effect_list_reload(lpeitem); @@ -531,10 +541,11 @@ void LivePathEffectEditor::onDown() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); + if ( lpeitem ) { lpeitem->downCurrentPathEffect(); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Move path effect down") ); effect_list_reload(lpeitem); @@ -573,7 +584,7 @@ void LivePathEffectEditor::on_visibility_toggled( Glib::ustring const& str ) /* FIXME: this explicit writing to SVG is wrong. The lpe_item should have a method to disable/enable an effect within its stack. * So one can call: lpe_item->setActive(lpeobjref->lpeobject); */ lpeobjref->lpeobject->get_lpe()->getRepr()->setAttribute("is_visible", newValue ? "true" : "false"); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, newValue ? _("Activate path effect") : _("Deactivate path effect")); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index ad8b66b8c..b318933a7 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -23,7 +23,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" @@ -46,7 +46,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::Box *mainVBox = get_vbox(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); - _layout_table.resize(2, 2); + _layout_table.resize(3, 3); // Layer name widgets _fillet_chamfer_position_numeric.set_digits(4); @@ -61,20 +61,33 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_chamfer_subdivisions.set_digits(0); + _fillet_chamfer_chamfer_subdivisions.set_increments(1,1); + //todo: get tha max aloable infinity freeze the widget + _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999.0); + + _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:")); + _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions_label, 0, 1, 1, 2, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions, 1, 2, 1, 2, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); - _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); - _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer")); + _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group); + mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); - mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -106,7 +119,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() { - _setDesktop(NULL); + _set_desktop(NULL); } void FilletChamferPropertiesDialog::showDialog( @@ -115,16 +128,18 @@ void FilletChamferPropertiesDialog::showDialog( FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius) + bool aprox_radius, + Glib::ustring const * documentUnit) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); - dialog->_setDesktop(desktop); - dialog->_setUnit(unit); + dialog->_set_desktop(desktop); + dialog->_set_unit(unit); dialog->_set_use_distance(use_distance); dialog->_set_aprox(aprox_radius); - dialog->_setKnotPoint(knotpoint); - dialog->_setPt(pt); + dialog->_set_document_unit(documentUnit); + dialog->_set_knot_point(knotpoint); + dialog->_set_pt(pt); dialog->set_title(_("Modify Fillet-Chamfer")); dialog->_apply_button.set_label(_("_Modify")); @@ -146,10 +161,10 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; - } else if (_fillet_chamfer_type_chamfer.get_active() == true) { - d_width = 3; + } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) { + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000; } else { - d_width = 4; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -157,7 +172,7 @@ void FilletChamferPropertiesDialog::_apply() } d_pos = _index + (d_pos / 100); } else { - d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, *document_unit); d_pos = d_pos * -1; } _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); @@ -167,7 +182,7 @@ void FilletChamferPropertiesDialog::_apply() void FilletChamferPropertiesDialog::_close() { - _setDesktop(NULL); + _set_desktop(NULL); destroy_(); Glib::signal_idle().connect( sigc::bind_return( @@ -177,7 +192,7 @@ void FilletChamferPropertiesDialog::_close() ); } -bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { return false; } @@ -189,15 +204,15 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) } } -void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) { double position; - std::string distance_or_radius = std::string(_("Radius ")); + std::string distance_or_radius = std::string(_("Radius")); if(aprox){ - distance_or_radius = std::string(_("Radius aproximated ")); + distance_or_radius = std::string(_("Radius approximated")); } if(use_distance){ - distance_or_radius = std::string(_("Knot distance ")); + distance_or_radius = std::string(_("Knot distance")); } if (knotpoint.x() > 0) { double intpart; @@ -207,25 +222,27 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) _fillet_chamfer_position_label.set_label(_("Position (%):")); } else { _flexible = false; - std::string posConcat = distance_or_radius + - std::string(_("(")) + std::string(unit) + std::string(")"); + std::string posConcat = Glib::ustring::compose (_("%1 (%2):"), distance_or_radius, unit); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; - position = Inkscape::Util::Quantity::convert(position, "px", unit); + + position = Inkscape::Util::Quantity::convert(position, *document_unit, unit); } _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() == 3) { + } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000); _fillet_chamfer_type_chamfer.set_active(true); - } else if (knotpoint.y() == 1) { - _fillet_chamfer_type_double_chamfer.set_active(true); + } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000); + _fillet_chamfer_type_inverse_chamfer.set_active(true); } } -void FilletChamferPropertiesDialog::_setPt( +void FilletChamferPropertiesDialog::_set_pt( const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt) { @@ -234,11 +251,16 @@ void FilletChamferPropertiesDialog::_setPt( pt); } -void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr) { unit = abbr; } +void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring const *abbr) +{ + document_unit = abbr; +} + void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance) { use_distance = use_knot_distance; @@ -249,7 +271,7 @@ void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius) aprox = aprox_radius; } -void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +void FilletChamferPropertiesDialog::_set_desktop(SPDesktop *desktop) { if (desktop) { Inkscape::GC::anchor(desktop); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 47ff97b00..3807e98c8 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -32,7 +32,8 @@ public: FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius); + bool aprox_radius, + Glib::ustring const * documentUnit); protected: @@ -46,7 +47,9 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; - Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer; + Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; + Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; Gtk::Table _layout_table; bool _position_visible; @@ -62,19 +65,21 @@ protected: return instance; } - void _setDesktop(SPDesktop *desktop); - void _setPt(const Inkscape::LivePathEffect:: + void _set_desktop(SPDesktop *desktop); + void _set_pt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); - void _setUnit(const gchar *abbr); + void _set_unit(const gchar *abbr); + void _set_document_unit(Glib::ustring const * abbr); void _set_use_distance(bool use_knot_distance); void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; + Glib::ustring const * document_unit; bool use_distance; bool aprox; - void _setKnotPoint(Geom::Point knotpoint); + void _set_knot_point(Geom::Point knotpoint); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); bool _handleKeyEvent(GdkEventKey *event); diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index c34351511..a9e57970d 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -32,7 +32,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" @@ -152,7 +152,7 @@ PowerstrokePropertiesDialog::_close() ); } -bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { /*switch (get_group0_keyval(event)) { diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index cfa5c6182..f43a15225 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -22,7 +22,7 @@ #include "ui/dialog/dialog-manager.h" #include "desktop.h" -#include "desktop-handles.h" + #include "macros.h" #include "sp-anchor.h" #include "sp-image.h" @@ -113,7 +113,7 @@ void ObjectAttributes::widget_setup (void) return; } - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); SPItem *item = selection->singleItem(); if (!item) { diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 28e9b360b..dfe211e94 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -28,7 +28,7 @@ #include "object-properties.h" #include "widgets/sp-attribute-widget.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "verbs.h" @@ -353,7 +353,7 @@ void ObjectProperties::update() return; } - Inkscape::Selection *selection = sp_desktop_selection(SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); Gtk::Box *contents = _getContents(); if (!selection->singleItem()) { @@ -458,7 +458,7 @@ void ObjectProperties::_labelChanged() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail (item != NULL); _blocked = true; @@ -518,7 +518,7 @@ void ObjectProperties::_imageRenderingChanged() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail (item != NULL); _blocked = true; @@ -543,7 +543,7 @@ void ObjectProperties::_sensitivityToggled() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail(item != NULL); _blocked = true; @@ -559,7 +559,7 @@ void ObjectProperties::_hiddenToggled() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail(item != NULL); _blocked = true; diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 93d5dfbd5..c95529a56 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -988,7 +988,7 @@ void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) /* * Drap and drop within the tree */ -bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time) +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index b4a355083..39110f47a 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,19 +49,10 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop); - } - - static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop); - } inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); - inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *); - inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *); + inline virtual void _propagateDesktopActivated(SPDesktop *); + inline virtual void _propagateDesktopDeactivated(SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; @@ -134,17 +125,17 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument _panel.signalDocumentReplaced().emit(desktop, document); } -void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopActivated(SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); - _panel.signalActivateDesktop().emit(application, desktop); + _panel.signalActivateDesktop().emit(desktop); } -void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopDeactivated(SPDesktop *desktop) { _document_replaced_connection.disconnect(); - _panel.signalDeactiveDesktop().emit(application, desktop); + _panel.signalDeactiveDesktop().emit(desktop); } @@ -162,7 +153,7 @@ PanelDialog<B>::PanelDialog(Widget::Panel &panel, char const *prefs_path, int co SPDesktop *desktop = SP_ACTIVE_DESKTOP; - _propagateDesktopActivated(INKSCAPE, desktop); + _propagateDesktopActivated(desktop); _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced)); @@ -211,7 +202,7 @@ PanelDialog<Behavior::FloatingBehavior>::PanelDialog(UI::Widget::Panel &panel, c SPDesktop *desktop = SP_ACTIVE_DESKTOP; - _propagateDesktopActivated(INKSCAPE, desktop); + _propagateDesktopActivated(desktop); _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced)); @@ -247,8 +238,12 @@ PanelDialog<Behavior::FloatingBehavior> *PanelDialog<Behavior::FloatingBehavior> new PanelDialog<Behavior::FloatingBehavior>(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel()); - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(_handle_activate_desktop), instance); - g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK(handle_deactivate_desktop), instance); + INKSCAPE.signal_activate_desktop.connect( + sigc::mem_fun(*instance, &PanelDialog<Behavior::FloatingBehavior>::_propagateDesktopActivated) + ); + INKSCAPE.signal_deactivate_desktop.connect( + sigc::mem_fun(*instance, &PanelDialog<Behavior::FloatingBehavior>::_propagateDesktopDeactivated) + ); return instance; } diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index 80579c9d3..281958998 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -16,7 +16,7 @@ #include "verbs.h" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -38,12 +38,12 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) #else parametersTable(3, 3, false), #endif - centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), - centerX("", "X coordinate of the center", centerY), - radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), - radiusX("", "X coordinate of the radius", radiusY), - angleY("", "Starting angle", UNIT_TYPE_RADIAL), - angleX("", "End angle", angleY) + centerY("", C_("Polar arrange tab", "Y coordinate of the center"), UNIT_TYPE_LINEAR), + centerX("", C_("Polar arrange tab", "X coordinate of the center"), centerY), + radiusY("", C_("Polar arrange tab", "Y coordinate of the radius"), UNIT_TYPE_LINEAR), + radiusX("", C_("Polar arrange tab", "X coordinate of the radius"), radiusY), + angleY("", C_("Polar arrange tab", "Starting angle"), UNIT_TYPE_RADIAL), + angleX("", C_("Polar arrange tab", "End angle"), angleY) { anchorPointLabel.set_text(C_("Polar arrange tab", "Anchor point:")); anchorPointLabel.set_alignment(Gtk::ALIGN_START); @@ -80,7 +80,7 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) arrangeOnParametersRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); pack_start(arrangeOnParametersRadio, false, false); - centerLabel.set_text(_("Center X/Y:")); + centerLabel.set_text(C_("Polar arrange tab", "Center X/Y:")); #if WITH_GTKMM_3_0 parametersTable.attach(centerLabel, 0, 0, 1, 1); #else @@ -102,7 +102,7 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); #endif - radiusLabel.set_text(_("Radius X/Y:")); + radiusLabel.set_text(C_("Polar arrange tab", "Radius X/Y:")); #if WITH_GTKMM_3_0 parametersTable.attach(radiusLabel, 0, 1, 1, 1); #else @@ -296,7 +296,7 @@ static void moveToPoint(int anchor, SPItem *item, Geom::Point p) void PolarArrangeTab::arrange() { - Inkscape::Selection *selection = sp_desktop_selection(parent->getDesktop()); + Inkscape::Selection *selection = parent->getDesktop()->getSelection(); const GSList *items, *tmp; tmp = items = selection->itemList(); SPGenericEllipse *referenceEllipse = NULL; // Last ellipse in selection @@ -399,7 +399,7 @@ void PolarArrangeTab::arrange() tmp = tmp->next; } - DocumentUndo::done(sp_desktop_document(parent->getDesktop()), SP_VERB_SELECTION_ARRANGE, + DocumentUndo::done(parent->getDesktop()->getDocument(), SP_VERB_SELECTION_ARRANGE, _("Arrange on ellipse")); } diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 9faa8a2cb..6da8acb20 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -22,7 +22,7 @@ #include "document.h" #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "ui/tools-switch.h" #include "ui/tools/text-tool.h" #include "ui/interface.h" @@ -407,7 +407,7 @@ SpellCheck::init(SPDesktop *d) } #endif /* HAVE_ASPELL */ - _root = sp_desktop_document(desktop)->getRoot(); + _root = desktop->getDocument()->getRoot(); // empty the list of objects we've checked g_slist_free (_seen_objects); @@ -612,7 +612,7 @@ SpellCheck::nextWord() area.expandBy(MAX(0.05 * mindim, 1)); // create canvas path rectangle, red stroke - SPCanvasItem *rect = sp_canvas_bpath_new(sp_desktop_sketch(desktop), NULL); + SPCanvasItem *rect = sp_canvas_bpath_new(desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(rect), 0xff0000ff, 3.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(rect), 0, SP_WIND_RULE_NONZERO); SPCurve *curve = new SPCurve(); @@ -792,7 +792,7 @@ void SpellCheck::onAccept () // find the end of the word anew _end_w = _begin_w; _end_w.nextEndOfWord(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Fix spelling")); } } diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 56ecfdecc..bc228633d 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -29,7 +29,8 @@ #include "xml/node.h" #include "xml/repr.h" #include "sp-font-face.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "display/nr-svgfonts.h" #include "verbs.h" #include "sp-glyph.h" @@ -181,7 +182,7 @@ void SvgFontsDialog::on_kerning_value_changed(){ return; } - SPDocument* document = sp_desktop_document(this->getDesktop()); + SPDocument* document = this->getDesktop()->getDocument(); //TODO: I am unsure whether this is the correct way of calling SPDocumentUndo::maybe_done Glib::ustring undokey = "svgfonts:hkern:k:"; @@ -264,7 +265,7 @@ void SvgFontsDialog::update_sensitiveness(){ void SvgFontsDialog::update_fonts() { SPDesktop* desktop = this->getDesktop(); - SPDocument* document = sp_desktop_document(desktop); + SPDocument* document = desktop->getDocument(); const GSList* fonts = document->getResourceList("font"); _model->clear(); @@ -481,7 +482,7 @@ void SvgFontsDialog::update_glyphs(){ void SvgFontsDialog::add_glyph(){ const int count = _GlyphsListStore->children().size(); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); /* SPGlyph* glyph =*/ new_glyph(doc, get_selected_spfont(), count+1); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add glyph")); @@ -514,9 +515,9 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){ return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); - SPDocument* doc = sp_desktop_document(desktop); - Inkscape::Selection* sel = sp_desktop_selection(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); + SPDocument* doc = desktop->getDocument(); + Inkscape::Selection* sel = desktop->getSelection(); if (sel->isEmpty()){ char *msg = _("Select a <b>path</b> to define the curves of a glyph"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); @@ -556,9 +557,9 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); - SPDocument* doc = sp_desktop_document(desktop); - Inkscape::Selection* sel = sp_desktop_selection(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); + SPDocument* doc = desktop->getDocument(); + Inkscape::Selection* sel = desktop->getSelection(); if (sel->isEmpty()){ char *msg = _("Select a <b>path</b> to define the curves of a glyph"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); @@ -597,7 +598,7 @@ void SvgFontsDialog::reset_missing_glyph_description(){ return; } - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); SPObject* obj; for (obj = get_selected_spfont()->children; obj; obj=obj->next){ if (SP_IS_MISSING_GLYPH(obj)){ @@ -618,7 +619,7 @@ void SvgFontsDialog::glyph_name_edit(const Glib::ustring&, const Glib::ustring& //XML Tree being directly used here while it shouldn't be. glyph->getRepr()->setAttribute("glyph-name", str.c_str()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Edit glyph name")); update_glyphs(); @@ -632,7 +633,7 @@ void SvgFontsDialog::glyph_unicode_edit(const Glib::ustring&, const Glib::ustrin //XML Tree being directly used here while it shouldn't be. glyph->getRepr()->setAttribute("unicode", str.c_str()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph unicode")); update_glyphs(); @@ -644,7 +645,7 @@ void SvgFontsDialog::remove_selected_font(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(font->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove font")); update_fonts(); @@ -661,7 +662,7 @@ void SvgFontsDialog::remove_selected_glyph(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(glyph->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove glyph")); update_glyphs(); @@ -678,7 +679,7 @@ void SvgFontsDialog::remove_selected_kerning_pair(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(pair->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove kerning pair")); update_glyphs(); @@ -749,7 +750,7 @@ void SvgFontsDialog::add_kerning_pair(){ if (this->kerning_pair) return; //We already have this kerning pair - SPDocument* document = sp_desktop_document(this->getDesktop()); + SPDocument* document = this->getDesktop()->getDocument(); Inkscape::XML::Document *xml_doc = document->getReprDoc(); // create a new hkern node @@ -863,7 +864,7 @@ void set_font_family(SPFont* font, char* str){ } void SvgFontsDialog::add_font(){ - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); SPFont* font = new_font(doc); const int count = _model->children().size(); @@ -937,7 +938,7 @@ SvgFontsDialog::SvgFontsDialog() _FontsList.signal_button_release_event().connect_notify(sigc::mem_fun(*this, &SvgFontsDialog::fonts_list_button_release)); create_fonts_popup_menu(_FontsList, sigc::mem_fun(*this, &SvgFontsDialog::remove_selected_font)); - _defs_observer.set(sp_desktop_document(this->getDesktop())->getDefs()); + _defs_observer.set(this->getDesktop()->getDocument()->getDefs()); _defs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_fonts)); _getContents()->show_all(); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index a3cfeeba8..8759039c3 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -28,7 +28,7 @@ #include "color-item.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "document-private.h" @@ -122,15 +122,15 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) if ( gr ) { bool shown = false; if ( desktop && desktop->doc() ) { - Inkscape::Selection *selection = sp_desktop_selection( desktop ); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); if (items) { - SPStyle *query = sp_style_new( desktop->doc() ); - int result = objects_query_fillstroke(const_cast<GSList *>(items), query, true); + SPStyle query( desktop->doc() ); + int result = objects_query_fillstroke(const_cast<GSList *>(items), &query, true); if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { // could be pertinent - if (query->fill.isPaintserver()) { - SPPaintServer* server = query->getFillPaintServer(); + if (query.fill.isPaintserver()) { + SPPaintServer* server = query.getFillPaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* grad = SP_GRADIENT(server); if ( grad->isSwatch() && grad->getId() == gr->getId()) { @@ -140,7 +140,6 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) } } } - sp_style_unref(query); } } @@ -527,7 +526,7 @@ static void loadEmUp() beenHere = true; std::list<gchar *> sources; - sources.push_back( profile_path("palettes") ); + sources.push_back( Inkscape::Application::profile_path("palettes") ); sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); sources.push_back( g_strdup(CREATE_PALETTESDIR) ); @@ -1061,15 +1060,15 @@ void SwatchesPanel::_updateFromSelection() Glib::ustring fillId; Glib::ustring strokeId; - SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); - int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); + SPStyle tmpStyle(_currentDesktop->getDocument()); + int result = sp_desktop_query_style( _currentDesktop, &tmpStyle, QUERY_STYLE_PROPERTY_FILL ); switch (result) { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: { - if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { - SPPaintServer* server = tmpStyle->getFillPaintServer(); + if (tmpStyle.fill.set && tmpStyle.fill.isPaintserver()) { + SPPaintServer* server = tmpStyle.getFillPaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* target = 0; SPGradient* grad = SP_GRADIENT(server); @@ -1095,14 +1094,14 @@ void SwatchesPanel::_updateFromSelection() } } - result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); + result = sp_desktop_query_style( _currentDesktop, &tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); switch (result) { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: { - if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { - SPPaintServer* server = tmpStyle->getStrokePaintServer(); + if (tmpStyle.stroke.set && tmpStyle.stroke.isPaintserver()) { + SPPaintServer* server = tmpStyle.getStrokePaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* target = 0; SPGradient* grad = SP_GRADIENT(server); @@ -1126,7 +1125,6 @@ void SwatchesPanel::_updateFromSelection() break; } } - sp_style_unref(tmpStyle); for ( boost::ptr_vector<ColorItem>::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { ColorItem* item = &*it; diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index a9cf8d068..eeb4d6cbe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -52,7 +52,7 @@ #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "inkscape.h" #include "sp-root.h" @@ -287,8 +287,8 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : ++row; /**********************************************************/ - currentDesktop = inkscape_active_desktop(); - currentDocument = sp_desktop_document(currentDesktop); + currentDesktop = SP_ACTIVE_DESKTOP; + currentDocument = currentDesktop->getDocument(); previewDocument = symbols_preview_doc(); /* Template to render symbols in */ previewDocument->ensureUpToDate(); /* Necessary? */ @@ -298,8 +298,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : // This might need to be a global variable so setTargetDesktop can modify it SPDefs *defs = currentDocument->getDefs(); - sigc::connection defsModifiedConn = (SP_OBJECT(defs))->connectModified( - sigc::mem_fun(*this, &SymbolsDialog::defsModified)); + sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified)); instanceConns.push_back(defsModifiedConn); sigc::connection selectionChangedConn = currentDesktop->selection->connectChanged( @@ -499,7 +498,7 @@ void SymbolsDialog::iconChanged() { } ClipboardManager *cm = ClipboardManager::get(); - cm->copySymbol(symbol->getRepr(), style); + cm->copySymbol(symbol->getRepr(), style, symbolDocument == currentDocument); } } @@ -586,13 +585,15 @@ void SymbolsDialog::get_symbols() { std::list<Glib::ustring> directories; +// \TODO optimize this + if( Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_EXISTS ) && Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) { directories.push_back( INKSCAPE_SYMBOLSDIR ); } - if( Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_EXISTS ) && - Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { - directories.push_back( profile_path("symbols") ); + if( Inkscape::IO::file_test( Inkscape::Application::profile_path("symbols"), G_FILE_TEST_EXISTS ) && + Inkscape::IO::file_test( Inkscape::Application::profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { + directories.push_back( Inkscape::Application::profile_path("symbols") ); } std::list<Glib::ustring>::iterator it; @@ -658,11 +659,11 @@ GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l) g_return_val_if_fail(r != NULL, l); // Stop multiple counting of same symbol - if( SP_IS_USE(r) ) { + if ( dynamic_cast<SPUse *>(r) ) { return l; } - if( SP_IS_SYMBOL(r) ) { + if ( dynamic_cast<SPSymbol *>(r) ) { l = g_slist_prepend (l, r); } @@ -684,7 +685,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l) { - if( SP_IS_USE(r) ) { + if ( dynamic_cast<SPUse *>(r) ) { l = g_slist_prepend (l, r); } @@ -709,8 +710,9 @@ gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* documen gchar const* style = 0; GSList* l = use_in_doc( document ); for( ; l != NULL; l = l->next ) { - SPObject* use = SP_OBJECT(l->data); - if( SP_IS_USE( use ) ) { + SPObject *obj = reinterpret_cast<SPObject *>(l->data); + SPUse *use = dynamic_cast<SPUse *>(obj); + if ( use ) { gchar const *href = use->getRepr()->attribute("xlink:href"); if( href ) { Glib::ustring href2(href); @@ -730,8 +732,9 @@ void SymbolsDialog::add_symbols( SPDocument* symbolDocument ) { GSList* l = symbols_in_doc( symbolDocument ); for( ; l != NULL; l = l->next ) { - SPObject* symbol = SP_OBJECT(l->data); - if (SP_IS_SYMBOL(symbol)) { + SPObject *obj = reinterpret_cast<SPObject *>(l->data); + SPSymbol *symbol = dynamic_cast<SPSymbol *>(obj); + if (symbol) { add_symbol( symbol ); } } @@ -820,7 +823,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); previewDocument->ensureUpToDate(); - SPItem *item = SP_ITEM(object_temp); + SPItem *item = dynamic_cast<SPItem *>(object_temp); + g_assert(item != NULL); unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr<Gdk::Pixbuf> pixbuf(NULL); diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 127e4d95e..8a104d137 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -380,7 +380,7 @@ void TagsPanel::_objectsSelected( Selection *sel ) { _checkTreeSelection(); } -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) { Gtk::TreeModel::Row row = *iter; SPObject * it = row[_model->_colObject]; @@ -393,6 +393,7 @@ bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter return false; } +// TODO does not look good that we're ignoring the passed in root. Investigate. void TagsPanel::_objectsChanged(SPObject* root) { while (!_objectWatchers.empty()) @@ -754,7 +755,7 @@ void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) * Drap and drop within the tree * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time) +bool TagsPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; @@ -885,7 +886,7 @@ void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name } } -bool TagsPanel::_noSelection( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +bool TagsPanel::_noSelection( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) { return false; } diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 13cb01eef..fca1f7b30 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -194,7 +194,7 @@ void TemplateLoadTab::_refreshTemplatesList() void TemplateLoadTab::_loadTemplates() { // user's local dir - _getTemplatesFromDir(profile_path("templates") + _loading_path); + _getTemplatesFromDir(Inkscape::Application::profile_path("templates") + _loading_path); // system templates dir _getTemplatesFromDir(INKSCAPE_TEMPLATESDIR + _loading_path); diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index f79d166f2..eff75b311 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -20,7 +20,7 @@ #include "template-load-tab.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "file.h" @@ -68,8 +68,8 @@ void TemplateWidget::create() SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDesktop *desc = sp_file_new_default(); _current_template.tpl_effect->effect(desc); - DocumentUndo::clearUndo(sp_desktop_document(desc)); - sp_desktop_document(desc)->setModifiedSinceSave(false); + DocumentUndo::clearUndo(desc->getDocument()); + desc->getDocument()->setModifiedSinceSave(false); // Apply cx,cy etc. from document sp_namedview_window_from_document( desc ); diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 0f4a6f7f1..a8be8b543 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -41,7 +41,7 @@ extern "C" { #include "document.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document-undo.h" #include "selection.h" #include "style.h" @@ -325,18 +325,18 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) if (dostyle) { // create temporary style - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection - //int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + //int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, read the style from the text tool prefs (default style for new texts) // (Ok to not get a font specification - must just rely on the family and style in that case) if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { - sp_style_read_from_prefs(query, "/tools/text"); + query.readFromPrefs("/tools/text"); } // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists @@ -344,47 +344,46 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); // This is normally done for us by text-toolbar but only when we are in text editing context - fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->update_font_list(this->desktop->getDocument()); fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); sp_font_selector_set_fontspec(fsel, fontspec, size ); setPreviewText (fontspec, phrase); - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { - if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { + if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { align_justify.set_active(); } else { align_left.set_active(); } - } else if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) { + } else if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) { align_center.set_active(); } else { align_right.set_active(); } - if (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) { + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) { text_horizontal.set_active(); } else { text_vertical.set_active(); } double height; - if (query->line_height.normal) height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; - else if (query->line_height.unit == SP_CSS_UNIT_PERCENT) - height = query->line_height.value; - else height = query->line_height.computed; + if (query.line_height.normal) height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + else if (query.line_height.unit == SP_CSS_UNIT_PERCENT) + height = query.line_height.value; + else height = query.line_height.computed; gchar *sstr = g_strdup_printf ("%d%%", (int) floor(height * 100 + 0.5)); gtk_entry_set_text ((GtkEntry *) gtk_bin_get_child ((GtkBin *) spacing_combo), sstr); g_free(sstr); - sp_style_unref(query); } blocked = false; } @@ -419,7 +418,7 @@ SPItem *TextEdit::getSelectedTextItem (void) if (!SP_ACTIVE_DESKTOP) return NULL; - for (const GSList *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (const GSList *item = SP_ACTIVE_DESKTOP->getSelection()->itemList(); item != NULL; item = item->next) { @@ -438,7 +437,7 @@ unsigned TextEdit::getSelectedTextCount (void) unsigned int items = 0; - for (const GSList *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (const GSList *item = SP_ACTIVE_DESKTOP->getSelection()->itemList(); item != NULL; item = item->next) { @@ -543,7 +542,7 @@ void TextEdit::onApply() SPDesktop *desktop = SP_ACTIVE_DESKTOP; unsigned items = 0; - const GSList *item_list = sp_desktop_selection(desktop)->itemList(); + const GSList *item_list = desktop->getSelection()->itemList(); SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); @@ -569,7 +568,7 @@ void TextEdit::onApply() } else if (items == 1) { // exactly one text object; now set its text, too - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT(item)) { updateObjectText (item); } @@ -583,7 +582,7 @@ void TextEdit::onApply() } // complete the transaction - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Set text style")); apply_button.set_sensitive ( false ); @@ -658,7 +657,7 @@ void TextEdit::onStartOffsetChange(GtkTextBuffer * /*text_buffer*/, TextEdit *se const gchar *sstr = gtk_combo_box_text_get_active_text(reinterpret_cast<GtkComboBoxText *>(self->startOffset)); tp->setAttribute("startOffset", sstr); - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "startOffset", SP_VERB_CONTEXT_TEXT, _("Set text style")); + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "startOffset", SP_VERB_CONTEXT_TEXT, _("Set text style")); } } diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 3e135b9b2..233d99750 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -25,7 +25,8 @@ #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "transformation.h" #include "align-and-distribute.h" #include "inkscape.h" @@ -47,16 +48,13 @@ namespace Inkscape { namespace UI { namespace Dialog { -static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) +static void on_selection_changed(Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); } -static void on_selection_modified( InkscapeApplication */*inkscape*/, - Inkscape::Selection *selection, - guint /*flags*/, - Transformation *daad ) +static void on_selection_modified(Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); @@ -159,8 +157,8 @@ Transformation::Transformation() } // Connect to the global selection changed & modified signals - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); - g_signal_connect (G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (on_selection_modified), this); + _selChangeConn = INKSCAPE.signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&on_selection_changed), this)); + _selModifyConn = INKSCAPE.signal_selection_modified.connect(sigc::hide<1>(sigc::bind(sigc::ptr_fun(&on_selection_modified), this))); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Transformation::setDesktop) ); _deskTrack.connect(GTK_WIDGET(gobj())); @@ -170,7 +168,8 @@ Transformation::Transformation() Transformation::~Transformation() { - sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this); + _selModifyConn.disconnect(); + _selChangeConn.disconnect(); _desktopChangeConn.disconnect(); _deskTrack.disconnect(); } @@ -207,9 +206,9 @@ void Transformation::layoutPageMove() // Setting default unit to document unit SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); - if (nv->doc_units) { - _units_move.setUnit(nv->doc_units->abbr); + SPNamedView *nv = dt->getNamedView(); + if (nv->display_units) { + _units_move.setUnit(nv->display_units->abbr); } _scalar_move_horizontal.initScalar(-1e6, 1e6); @@ -580,7 +579,7 @@ void Transformation::onSwitchPage(Gtk::Widget * /*page*/, guint pagenum) void Transformation::onSwitchPage(GtkNotebookPage * /*page*/, guint pagenum) #endif { - updateSelection((PageType)pagenum, sp_desktop_selection(getDesktop())); + updateSelection((PageType)pagenum, getDesktop()->getSelection()); } @@ -803,7 +802,7 @@ void Transformation::applyPageMove(Inkscape::Selection *selection) } } - DocumentUndo::done( sp_desktop_document(selection->desktop()) , SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done( selection->desktop()->getDocument() , SP_VERB_DIALOG_TRANSFORM, _("Move")); } @@ -865,7 +864,7 @@ void Transformation::applyPageScale(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Scale")); } @@ -890,7 +889,7 @@ void Transformation::applyPageRotate(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Rotate")); } @@ -905,7 +904,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("%"); double skewY = _scalar_skew_vertical.getValue("%"); if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_item_skew_rel (item, 0.01*skewX, 0.01*skewY); @@ -916,7 +915,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } double skewX = tan(-angleX); @@ -930,7 +929,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double width = bbox->dimensions()[Geom::X]; double height = bbox->dimensions()[Geom::Y]; if (fabs(skewX*skewY - width*height) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_item_skew_rel (item, skewX/height, skewY/width); @@ -949,7 +948,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("%"); double skewY = _scalar_skew_vertical.getValue("%"); if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY); @@ -960,7 +959,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } double skewX = tan(-angleX); @@ -970,7 +969,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); if (fabs(skewX*skewY - width*height) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_selection_skew_relative(selection, *center, skewX/height, skewY/width); @@ -978,7 +977,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Skew")); } @@ -994,7 +993,7 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection) Geom::Affine displayed(a, b, c, d, e, f); if (displayed.isSingular()) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } @@ -1008,7 +1007,7 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection) sp_selection_apply_affine(selection, displayed); // post-multiply each object's transform } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Edit transformation matrix")); } diff --git a/src/ui/dialog/transformation.h b/src/ui/dialog/transformation.h index 1d24a0c94..89aa95d90 100644 --- a/src/ui/dialog/transformation.h +++ b/src/ui/dialog/transformation.h @@ -232,6 +232,9 @@ private: Gtk::Button *applyButton; Gtk::Button *resetButton; Gtk::Button *cancelButton; + + sigc::connection _selChangeConn; + sigc::connection _selModifyConn; }; diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index 53691cd37..a50a169eb 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -24,7 +24,7 @@ #include "document-undo.h" #include "inkscape.h" #include "verbs.h" -#include "desktop-handles.h" + #include "util/signal-blocker.h" #include "desktop.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 7ab6c78ba..c02520218 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -23,7 +23,7 @@ #include <gtkmm/stock.h> #include "desktop.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" @@ -360,10 +360,10 @@ void XmlTree::set_tree_desktop(SPDesktop *desktop) } current_desktop = desktop; if (desktop) { - sel_changed_connection = sp_desktop_selection(desktop)->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); + sel_changed_connection = desktop->getSelection()->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(this, &XmlTree::on_document_replaced)); - set_tree_document(sp_desktop_document(desktop)); + set_tree_document(desktop->getDocument()); } else { set_tree_document(NULL); } @@ -472,7 +472,7 @@ Inkscape::XML::Node *XmlTree::get_dt_select() if (!current_desktop) { return NULL; } - return sp_desktop_selection(current_desktop)->singleRepr(); + return current_desktop->getSelection()->singleRepr(); } @@ -483,7 +483,7 @@ void XmlTree::set_dt_select(Inkscape::XML::Node *repr) return; } - Inkscape::Selection *selection = sp_desktop_selection(current_desktop); + Inkscape::Selection *selection = current_desktop->getSelection(); SPObject *object; if (repr) { @@ -493,7 +493,7 @@ void XmlTree::set_dt_select(Inkscape::XML::Node *repr) repr = repr->parent(); } // end of while loop - object = sp_desktop_document(current_desktop)->getObjectByRepr(repr); + object = current_desktop->getDocument()->getObjectByRepr(repr); } else { object = NULL; } @@ -827,7 +827,7 @@ void XmlTree::on_document_replaced(SPDesktop *dt, SPDocument *doc) if (current_desktop) sel_changed_connection.disconnect(); - sel_changed_connection = sp_desktop_selection(dt)->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); + sel_changed_connection = dt->getSelection()->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); set_tree_document(doc); } diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp index 84c919018..6b9a88ed7 100644 --- a/src/ui/draw-anchor.cpp +++ b/src/ui/draw-anchor.cpp @@ -15,7 +15,6 @@ #include "ui/draw-anchor.h" #include "desktop.h" -#include "desktop-handles.h" #include "ui/tools/tool-base.h" #include "ui/tools/lpe-tool.h" #include "display/sodipodi-ctrl.h" @@ -45,7 +44,7 @@ SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve a->start = start; a->active = FALSE; a->dp = delta; - a->ctrl = ControlManager::getManager().createControl(sp_desktop_controls(&dc->getDesktop()), Inkscape::CTRL_TYPE_ANCHOR); + a->ctrl = ControlManager::getManager().createControl(dc->getDesktop().getControls(), Inkscape::CTRL_TYPE_ANCHOR); SP_CTRL(a->ctrl)->moveto(delta); diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 7830a8de1..28a65e0b4 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -29,7 +29,7 @@ #include <gtkmm/imagemenuitem.h> #include <gtkmm/separatormenuitem.h> -#include "inkscape-private.h" +#include "inkscape.h" #include "extension/db.h" #include "extension/effect.h" #include "extension/input.h" @@ -38,7 +38,7 @@ #include "path-prefix.h" #include "shortcuts.h" #include "document.h" -#include "desktop-handles.h" + #include "ui/interface.h" #include "desktop.h" #include "selection.h" @@ -270,7 +270,7 @@ sp_create_window(SPViewWidget *vw, bool editable) // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet if ( SP_IS_DESKTOP_WIDGET(vw) ) { - inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); + INKSCAPE.reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); } } @@ -318,13 +318,13 @@ sp_ui_close_view(GtkWidget */*widget*/) // If closing the last document, open a new document so Inkscape doesn't quit. std::list<SPDesktop *> desktops; - inkscape_get_all_desktops(desktops); + INKSCAPE.get_all_desktops(desktops); if (desktops.size() == 1) { Glib::ustring templateUri = sp_file_default_template_uri(); SPDocument *doc = SPDocument::createNewDoc( templateUri.c_str() , TRUE, true ); // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } dt->change_document(doc); sp_namedview_window_from_document(dt); @@ -921,7 +921,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I GtkWidget *sp_ui_main_menubar(Inkscape::UI::View::View *view) { GtkWidget *mbar = gtk_menu_bar_new(); - sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); + sp_ui_build_dyn_menus(INKSCAPE.get_menus(), mbar, view); return mbar; } @@ -1232,12 +1232,12 @@ sp_ui_drag_data_received(GtkWidget *widget, SPObject *new_obj = NULL; new_obj = desktop->currentLayer()->appendChildRepr(newgroup); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->set(SP_ITEM(new_obj)); // move to mouse pointer { - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); @@ -2117,13 +2117,13 @@ void ContextMenu::ImageEdit(void) void ContextMenu::ImageTraceBitmap(void) { - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); _desktop->_dlg_mgr->showDialog("Trace"); } void ContextMenu::ImageTracePixelArt(void) { - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); _desktop->_dlg_mgr->showDialog("PixelArt"); } diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp index ca550502d..fb99dfd59 100644 --- a/src/ui/object-edit.cpp +++ b/src/ui/object-edit.cpp @@ -28,7 +28,7 @@ #include "preferences.h" #include "style.h" #include "desktop.h" -#include "desktop-handles.h" + #include "sp-namedview.h" #include "live_effects/effect.h" #include "sp-pattern.h" diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp index 0b9fc24c5..aec5cde27 100644 --- a/src/ui/shape-editor.cpp +++ b/src/ui/shape-editor.cpp @@ -14,7 +14,7 @@ #include <string.h> #include <glibmm/i18n.h> -#include "desktop-handles.h" +#include "desktop.h" #include "document.h" #include "gc-anchored.h" #include "knotholder.h" @@ -146,7 +146,7 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { void ShapeEditor::reset_item(bool keep_knotholder) { if (knotholder) { - SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + SPObject *obj = desktop->getDocument()->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. set_item(SP_ITEM(obj), keep_knotholder); } } diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index e98c7b2a2..bcf5c9fce 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -11,7 +11,7 @@ #include <gdkmm.h> #include <2geom/point.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/snap-indicator.h" #include "ui/tools/tool-base.h" @@ -74,7 +74,7 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho _lurking(false) { _canvas_item = sp_canvas_item_new( - group ? group : sp_desktop_controls(_desktop), SP_TYPE_CTRL, + group ? group : _desktop->getControls(), SP_TYPE_CTRL, "anchor", (SPAnchorType) anchor, "size", (gdouble) pixbuf->get_width(), "shape", SP_CTRL_SHAPE_BITMAP, "pixbuf", pixbuf->gobj(), "filled", TRUE, "fill_color", _cset.normal.fill, @@ -93,7 +93,7 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho _position(initial_pos), _lurking(false) { - _canvas_item = ControlManager::getManager().createControl(group ? group : sp_desktop_controls(_desktop), type); + _canvas_item = ControlManager::getManager().createControl(group ? group : _desktop->getControls(), type); g_object_set(_canvas_item, "anchor", anchor, "filled", TRUE, "fill_color", _cset.normal.fill, diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 013553410..49c949107 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,22 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && held_shift(*event))second->back()->move(new_pos); - else if(weight<=0.2 && held_shift(*event))first->front()->move(new_pos); + }else if(weight>=0.8){ + if(held_shift(*event)){ + second->back()->move(new_pos); + } else { + second->move(second->position() + delta); + } + }else if(weight<=0.2){ + if(held_shift(*event)){ + first->back()->move(new_pos); + } else { + first->move(first->position() + delta); + } + }else{ + first->move(first->position() + delta); + second->move(second->position() + delta); + } _pm.update(); } diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index d7b35c974..f53cef5f4 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -14,7 +14,7 @@ #include "node.h" #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "live_effects/lpeobject.h" @@ -820,9 +820,9 @@ void MultiPathManipulator::_commit(CommitEvent cps) _selection.signal_update.emit(); invokeForAll(&PathManipulator::writeXML); if (key) { - DocumentUndo::maybeDone(sp_desktop_document(_desktop), key, SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::maybeDone(_desktop->getDocument(), key, SP_VERB_CONTEXT_NODE, reason); } else { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, reason); } signal_coords_changed.emit(); } @@ -831,7 +831,7 @@ void MultiPathManipulator::_commit(CommitEvent cps) void MultiPathManipulator::_done(gchar const *reason, bool alert_LPE) { invokeForAll(&PathManipulator::update, alert_LPE); invokeForAll(&PathManipulator::writeXML); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, reason); signal_coords_changed.emit(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4abc901d2..eeea47e4d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -17,7 +17,7 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" #include "desktop.h" -#include "desktop-handles.h" + #include "preferences.h" #include "snap.h" #include "snap-preferences.h" @@ -60,10 +60,10 @@ Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) namespace Inkscape { namespace UI { -const double handleCubicGap = 0.01; +/*const double handleCubicGap = 0.01;*/ const double noPower = 0.0; const double defaultStartPower = 0.3334; -const double defaultEndPower = 0.6667; +/*const double defaultEndPower = 0.6667;*/ ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke @@ -566,9 +566,9 @@ Glib::ustring Handle::_getDragTip(GdkEventMotion */*event*/) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px"); Inkscape::Util::Quantity len_q = Inkscape::Util::Quantity(length(), "px"); - GString *x = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *y = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); - GString *len = g_string_new(len_q.string(_desktop->namedview->doc_units).c_str()); + GString *x = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *y = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); + GString *len = g_string_new(len_q.string(_desktop->namedview->display_units).c_str()); Glib::ustring ret = format_tip(C_("Path handle tip", "Move handle by %s, %s; angle %.2f°, length %s"), x->str, y->str, angle, len->str); g_string_free(x, TRUE); @@ -1490,8 +1490,8 @@ Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) const Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px"); - GString *x = g_string_new(x_q.string(_desktop->namedview->doc_units).c_str()); - GString *y = g_string_new(y_q.string(_desktop->namedview->doc_units).c_str()); + GString *x = g_string_new(x_q.string(_desktop->namedview->display_units).c_str()); + GString *y = g_string_new(y_q.string(_desktop->namedview->display_units).c_str()); Glib::ustring ret = format_tip(C_("Path node tip", "Move node by %s, %s"), x->str, y->str); g_string_free(x, TRUE); g_string_free(y, TRUE); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 52ff5d42c..c8b986824 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -23,7 +23,7 @@ #include <glibmm/i18n.h> #include "ui/tool/path-manipulator.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" #include "display/curve.h" @@ -59,7 +59,7 @@ enum PathChange { const double handleCubicGap = 0.01; const double noPower = 0.0; const double defaultStartPower = 0.3334; -const double defaultEndPower = 0.6667; + /** * Notifies the path manipulator when something changes the path being edited @@ -972,6 +972,10 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d NodeList &list = NodeList::get(first); NodeList::iterator second = first.next(); if (!second) throw std::invalid_argument("Subdivide after last node in open path"); + if (first->type() == NODE_SYMMETRIC) + first->setType(NODE_SMOOTH, false); + if (second->type() == NODE_SYMMETRIC) + second->setType(NODE_SMOOTH, false); // We need to insert the segment after 'first'. We can't simply use 'second' // as the point of insertion, because when 'first' is the last node of closed path, @@ -1000,7 +1004,6 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d n->front()->setPosition(seg2[1]); n->setType(NODE_SMOOTH, false); } else { - const double handleCubicGap = 0.01; Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); if(second->back()->isDegenerate()){ @@ -1251,7 +1254,6 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ h = h2; } double pos = noPower; - const double handleCubicGap = 0.01; Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); @@ -1279,7 +1281,6 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; - const double handleCubicGap = 0.01; Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; @@ -1620,13 +1621,13 @@ void PathManipulator::_removeNodesFromSelection() void PathManipulator::_commit(Glib::ustring const &annotation) { writeXML(); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, annotation.data()); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, annotation.data()); } void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key) { writeXML(); - DocumentUndo::maybeDone(sp_desktop_document(_desktop), key, SP_VERB_CONTEXT_NODE, + DocumentUndo::maybeDone(_desktop->getDocument(), key, SP_VERB_CONTEXT_NODE, annotation.data()); } diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index bdeacadc9..e4e701785 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -11,7 +11,7 @@ #include "control-point.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrlrect.h" #include "ui/tools/tool-base.h" #include "preferences.h" @@ -37,7 +37,7 @@ public: _cancel(false) { setVisible(false); - _rubber = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop), + _rubber = static_cast<CtrlRect*>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); sp_canvas_item_hide(_rubber); } @@ -100,7 +100,7 @@ private: Selector::Selector(SPDesktop *d) : Manipulator(d) - , _dragger(new SelectorPoint(d, sp_desktop_controls(d), this)) + , _dragger(new SelectorPoint(d, d->getControls(), this)) { _dragger->setVisible(false); } diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index 7d5c9bf0c..da2a54989 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -15,7 +15,7 @@ #include <glib/gi18n.h> #include <2geom/transforms.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrlrect.h" #include "preferences.h" #include "snap.h" @@ -686,7 +686,7 @@ TransformHandleSet::TransformHandleSet(SPDesktop *d, SPCanvasGroup *th_group) , _in_transform(false) , _visible(true) { - _trans_outline = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop), + _trans_outline = static_cast<CtrlRect*>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); sp_canvas_item_hide(_trans_outline); _trans_outline->setDashed(true); diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp index 47b9d2832..11313f550 100644 --- a/src/ui/tools-switch.cpp +++ b/src/ui/tools-switch.cpp @@ -16,9 +16,9 @@ #include <cstring> #include <string> -#include "inkscape-private.h" +#include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include <glibmm/i18n.h> #include <xml/repr.h> @@ -159,7 +159,7 @@ tools_switch(SPDesktop *dt, int num) /* fixme: This is really ugly hack. We should bind and unbind class methods */ /* First 4 tools use guides, first is undefined but we don't care */ dt->activate_guides(num < 5); - inkscape_eventcontext_set(dt->getEventContext()); + INKSCAPE.eventcontext_set(dt->getEventContext()); } void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 4f64ade25..b9206407a 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -29,7 +29,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "pixmaps/cursor-ellipse.xpm" #include "xml/repr.h" @@ -109,11 +109,11 @@ void ArcTool::selection_changed(Inkscape::Selection* selection) { void ArcTool::setup() { ToolBase::setup(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } @@ -151,7 +151,7 @@ bool ArcTool::item_handler(SPItem* item, GdkEvent* event) { bool ArcTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -405,8 +405,8 @@ void ArcTool::drag(Geom::Point pt, guint state) { Inkscape::Util::Quantity rdimx_q = Inkscape::Util::Quantity(rdimx, "px"); Inkscape::Util::Quantity rdimy_q = Inkscape::Util::Quantity(rdimy, "px"); - GString *xs = g_string_new(rdimx_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(rdimy_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(rdimx_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(rdimy_q.string(desktop->namedview->display_units).c_str()); if (state & GDK_CONTROL_MASK) { int ratio_x, ratio_y; @@ -442,16 +442,16 @@ void ArcTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->arc); + desktop->getSelection()->set(this->arc); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, _("Create ellipse")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, _("Create ellipse")); this->arc = NULL; } } void ArcTool::cancel() { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0); if (this->arc != NULL) { @@ -466,7 +466,7 @@ void ArcTool::cancel() { desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index 0a20a0842..f8ae685c4 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -26,7 +26,7 @@ #include "sp-namedview.h" #include "selection.h" #include "selection-chemistry.h" -#include "desktop-handles.h" + #include "snap.h" #include "display/curve.h" #include "display/sp-canvas-item.h" @@ -145,17 +145,17 @@ void Box3dTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &Box3dTool::selection_changed) ); - this->_vpdrag = new Box3D::VPDrag(sp_desktop_document(this->desktop)); + this->_vpdrag = new Box3D::VPDrag(this->desktop->getDocument()); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -195,8 +195,8 @@ bool Box3dTool::item_handler(SPItem* item, GdkEvent* event) { bool Box3dTool::root_handler(GdkEvent* event) { static bool dragging; - SPDocument *document = sp_desktop_document (desktop); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); @@ -466,7 +466,7 @@ bool Box3dTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); //TODO: make dragging escapable by Esc break; @@ -589,7 +589,7 @@ void Box3dTool::finishItem() { this->extruded = false; if (this->box3d != NULL) { - SPDocument *doc = sp_desktop_document(this->desktop); + SPDocument *doc = this->desktop->getDocument(); if (!doc || !doc->getCurrentPersp3D()) { return; @@ -604,8 +604,8 @@ void Box3dTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->box3d); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + desktop->getSelection()->set(this->box3d); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Create 3D box")); this->box3d = NULL; diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp index d297fe5e1..151ab5f89 100644 --- a/src/ui/tools/calligraphic-tool.cpp +++ b/src/ui/tools/calligraphic-tool.cpp @@ -47,7 +47,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "preferences.h" @@ -141,7 +141,7 @@ void CalligraphicTool::setup() { this->cal1 = new SPCurve(); this->cal2 = new SPCurve(); - this->currentshape = sp_canvas_item_new(sp_desktop_sketch(this->desktop), SP_TYPE_CANVAS_BPATH, NULL); + this->currentshape = sp_canvas_item_new(this->desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->currentshape), DDC_RED_RGBA, SP_WIND_RULE_EVENODD); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->currentshape), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -155,7 +155,7 @@ void CalligraphicTool::setup() { SPCurve *c = new SPCurve(path); - this->hatch_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->hatch_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); @@ -373,7 +373,7 @@ void CalligraphicTool::brush() { double R, G, B, A; Geom::IntRect area = Geom::IntRect::from_xywh(brush_w.floor(), Geom::IntPoint(1, 1)); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(SP_EVENT_CONTEXT(this)->desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(this->desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); double max = MAX (MAX (R, G), B); @@ -506,7 +506,7 @@ bool CalligraphicTool::root_handler(GdkEvent* event) { if (event->motion.state & GDK_CONTROL_MASK) { // hatching - sense the item - SPItem *selected = sp_desktop_selection(desktop)->singleItem(); + SPItem *selected = desktop->getSelection()->singleItem(); if (selected && (SP_IS_SHAPE(selected) || SP_IS_TEXT(selected))) { // One item selected, and it's a path; // let's try to track it as a guide @@ -940,14 +940,14 @@ void CalligraphicTool::set_to_accumulated(bool unionize, bool subtract) { g_free(str); if (unionize) { - sp_desktop_selection(desktop)->add(this->repr); - sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); + desktop->getSelection()->add(this->repr); + sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); } else if (subtract) { - sp_desktop_selection(desktop)->add(this->repr); - sp_selected_path_diff_skip_undo(sp_desktop_selection(desktop), desktop); + desktop->getSelection()->add(this->repr); + sp_selected_path_diff_skip_undo(desktop->getSelection(), desktop); } else { if (this->keep_selected) { - sp_desktop_selection(desktop)->set(this->repr); + desktop->getSelection()->set(this->repr); } } @@ -973,7 +973,7 @@ void CalligraphicTool::set_to_accumulated(bool unionize, bool subtract) { this->repr = NULL; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_CALLIGRAPHIC, _("Draw calligraphic stroke")); } @@ -1142,7 +1142,7 @@ void CalligraphicTool::fit_and_split(bool release) { if (!release) { g_assert(!this->currentcurve->is_empty()); - SPCanvasItem *cbp = sp_canvas_item_new(sp_desktop_sketch(desktop), + SPCanvasItem *cbp = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); SPCurve *curve = this->currentcurve->copy(); diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index 7b5c84c16..26a4eadd5 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -79,7 +79,7 @@ #include "svg/svg.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "message-context.h" @@ -223,7 +223,7 @@ ConnectorTool::~ConnectorTool() { void ConnectorTool::setup() { ToolBase::setup(); - this->selection = sp_desktop_selection(this->desktop); + this->selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); this->sel_changed_connection = this->selection->connectChanged( @@ -231,7 +231,7 @@ void ConnectorTool::setup() { ); /* Create red bpath */ - this->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->red_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->red_bpath), this->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->red_bpath), 0x00000000, @@ -659,7 +659,7 @@ bool ConnectorTool::_handleButtonRelease(GdkEventButton const &revent) { bool ret = false; if ( revent.button == 1 && !this->space_panning ) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); SnapManager &m = desktop->namedview->snap_manager; Geom::Point const event_w(revent.x, revent.y); @@ -729,7 +729,7 @@ bool ConnectorTool::_handleKeyPress(guint const keyval) { break; case GDK_KEY_Escape: if (this->state == SP_CONNECTOR_CONTEXT_REROUTING) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); this->_reroutingFinish(NULL); @@ -754,7 +754,7 @@ bool ConnectorTool::_handleKeyPress(guint const keyval) { } void ConnectorTool::_reroutingFinish(Geom::Point *const p) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); // Clear the temporary path: this->red_curve->reset(); @@ -812,7 +812,7 @@ void ConnectorTool::_setSubsequentPoint(Geom::Point const p) { Avoid::Point dst(d[Geom::X], d[Geom::Y]); if (!this->newConnRef) { - Avoid::Router *router = sp_desktop_document(desktop)->router; + Avoid::Router *router = desktop->getDocument()->router; this->newConnRef = new Avoid::ConnRef(router); this->newConnRef->setEndpoint(Avoid::VertID::src, src); if (this->isOrthogonal) @@ -876,7 +876,7 @@ void ConnectorTool::_flushWhite(SPCurve *gc) { /* Now we have to go back to item coordinates at last */ c->transform(this->desktop->dt2doc()); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { @@ -1304,14 +1304,14 @@ bool cc_item_is_connector(SPItem *item) void cc_selection_set_avoid(bool const set_avoid) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) { return; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList *l = const_cast<GSList *>(selection->itemList()); diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp index 6c55f7484..9038628ee 100644 --- a/src/ui/tools/dropper-tool.cpp +++ b/src/ui/tools/dropper-tool.cpp @@ -34,7 +34,7 @@ #include "sp-namedview.h" #include "sp-cursor.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -73,7 +73,7 @@ const std::string& DropperTool::getPrefsPath() { const std::string DropperTool::prefsPath = "/tools/dropper"; DropperTool::DropperTool() - : ToolBase(cursor_dropper_f_xpm, 7, 7) + : ToolBase(cursor_dropper_f_xpm, 5, 5) , R(0) , G(0) , B(0) @@ -83,8 +83,8 @@ DropperTool::DropperTool() , area(NULL) , centre(0, 0) { - cursor_dropper_fill = sp_cursor_new_from_xpm(cursor_dropper_f_xpm , 7, 7); - cursor_dropper_stroke = sp_cursor_new_from_xpm(cursor_dropper_s_xpm , 7, 7); + cursor_dropper_fill = sp_cursor_new_from_xpm(cursor_dropper_f_xpm , 5, 5); + cursor_dropper_stroke = sp_cursor_new_from_xpm(cursor_dropper_s_xpm , 5, 5); } DropperTool::~DropperTool() { @@ -99,7 +99,7 @@ void DropperTool::setup() { SPCurve *c = new SPCurve(path); - this->area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); @@ -200,7 +200,7 @@ bool DropperTool::root_handler(GdkEvent* event) { // If one time pick with stroke set the pixmap if (prefs->getBool("/tools/dropper/onetimepick", false) && prefs->getInt("/dialogs/fillstroke/page", 0) == 1) { //TODO Only set when not set already - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } @@ -230,7 +230,7 @@ bool DropperTool::root_handler(GdkEvent* event) { if (!r.hasZeroArea()) { Geom::IntRect area = r.roundOutwards(); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, area.width(), area.height()); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); } @@ -238,14 +238,14 @@ bool DropperTool::root_handler(GdkEvent* event) { // pick single pixel Geom::IntRect area = Geom::IntRect::from_xywh(floor(event->button.x), floor(event->button.y), 1, 1); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); } if (pick == SP_DROPPER_PICK_VISIBLE) { // compose with page color - guint32 bg = sp_desktop_namedview(desktop)->pagecolor; + guint32 bg = desktop->getNamedView()->pagecolor; R = R + (SP_RGBA32_R_F(bg)) * (1 - A); G = G + (SP_RGBA32_G_F(bg)) * (1 - A); B = B + (SP_RGBA32_B_F(bg)) * (1 - A); @@ -324,12 +324,12 @@ bool DropperTool::root_handler(GdkEvent* event) { // REJON: set aux. toolbar input to hex color! if (event->button.state & GDK_SHIFT_MASK) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } - if (!(sp_desktop_selection(desktop)->isEmpty())) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER, + if (!(desktop->getSelection()->isEmpty())) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_DROPPER, _("Set picked color")); } @@ -359,11 +359,11 @@ bool DropperTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: if (!desktop->isWaitingCursor() && !prefs->getBool("/tools/dropper/onetimepick", false)) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } @@ -378,7 +378,7 @@ bool DropperTool::root_handler(GdkEvent* event) { case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: if (!desktop->isWaitingCursor() && !prefs->getBool("/tools/dropper/onetimepick", false)) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_fill); } break; diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index bf4015b4c..1b4dcfe25 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -44,7 +44,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "preferences.h" @@ -121,7 +121,7 @@ void EraserTool::setup() { this->cal1 = new SPCurve(); this->cal2 = new SPCurve(); - this->currentshape = sp_canvas_item_new(sp_desktop_sketch(desktop), SP_TYPE_CANVAS_BPATH, NULL); + this->currentshape = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->currentshape), ERC_RED_RGBA, SP_WIND_RULE_EVENODD); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->currentshape), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -666,7 +666,7 @@ void EraserTool::set_to_accumulated() { if ( this->repr ) { bool wasSelection = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; @@ -680,10 +680,10 @@ void EraserTool::set_to_accumulated() { if (selection->isEmpty()) { if ( eraserMode ) { - toWorkOn = sp_desktop_document(desktop)->getItemsPartiallyInBox(desktop->dkey, bounds); + toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, bounds); } else { Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); - toWorkOn = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, r->getPoints()); + toWorkOn = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); } toWorkOn = g_slist_remove( toWorkOn, acid ); @@ -767,9 +767,9 @@ void EraserTool::set_to_accumulated() { if ( workDone ) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ERASER, _("Draw eraser stroke")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ERASER, _("Draw eraser stroke")); } else { - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } @@ -949,7 +949,7 @@ void EraserTool::fit_and_split(bool release) { gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; g_assert(!this->currentcurve->is_empty()); - SPCanvasItem *cbp = sp_canvas_item_new(sp_desktop_sketch(desktop), SP_TYPE_CANVAS_BPATH, NULL); + SPCanvasItem *cbp = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); SPCurve *curve = this->currentcurve->copy(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH (cbp), curve); curve->unref(); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 5745fc9cc..e4c4e855d 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -31,7 +31,7 @@ #include "color.h" #include "context-fns.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" @@ -128,13 +128,13 @@ void FloodTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &FloodTool::selection_changed) ); @@ -360,7 +360,7 @@ inline static bool check_if_pixel_is_paintable(guchar *px, unsigned char *trace_ * @param union_with_selection If true, merge the final SVG path with the current selection. */ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *desktop, Geom::Affine transform, unsigned int min_x, unsigned int max_x, unsigned int min_y, unsigned int max_y, bool union_with_selection) { - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); unsigned char *trace_t; @@ -467,7 +467,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto g_free(affinestr); } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); pathRepr->setPosition(-1); @@ -476,7 +476,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto ngettext("Area filled, path with <b>%d</b> node created and unioned with selection.","Area filled, path with <b>%d</b> nodes created and unioned with selection.", SP_PATH(reprobj)->nodesInPath()), SP_PATH(reprobj)->nodesInPath() ); selection->add(reprobj); - sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); + sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); } else { desktop->messageStack()->flashF( Inkscape::WARNING_MESSAGE, ngettext("Area filled, path with <b>%d</b> node created.","Area filled, path with <b>%d</b> nodes created.", @@ -621,7 +621,7 @@ static ScanlineCheckResult perform_bitmap_scanline_check(std::deque<Geom::Point> bool currently_painting_top = false; bool currently_painting_bottom = false; - unsigned int top_ty = bci.y - 1; + unsigned int top_ty = (bci.y > 0) ? bci.y - 1 : 0; unsigned int bottom_ty = bci.y + 1; bool can_paint_top = (top_ty > 0); @@ -740,7 +740,7 @@ static bool sort_fill_queue_horizontal(Geom::Point a, Geom::Point b) { */ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, bool union_with_selection, bool is_point_fill, bool is_touch_fill) { SPDesktop *desktop = event_context->desktop; - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); document->ensureUpToDate(); @@ -792,7 +792,7 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo Inkscape::DrawingContext dc(s, Geom::Point(0,0)); // cairo_translate not necessary here - surface origin is at 0,0 - SPNamedView *nv = sp_desktop_namedview(desktop); + SPNamedView *nv = desktop->getNamedView(); bgcolor = nv->pagecolor; // bgcolor is 0xrrggbbaa, we need 0xaarrggbb dtc = (bgcolor >> 8) | (bgcolor << 24); @@ -1096,7 +1096,7 @@ bool FloodTool::item_handler(SPItem* item, GdkEvent* event) { // Set style desktop->applyCurrentOrToolStyle(item, "/tools/paintbucket", false); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_PAINTBUCKET, _("Set style on object")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_PAINTBUCKET, _("Set style on object")); ret = TRUE; } @@ -1229,9 +1229,9 @@ void FloodTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->item); + desktop->getSelection()->set(this->item); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_PAINTBUCKET, _("Fill bounded area")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_PAINTBUCKET, _("Fill bounded area")); this->item = NULL; } diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6434c30d2..0f14d7534 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -27,7 +27,7 @@ #include <glibmm/i18n.h> #include "display/curve.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "ui/draw-anchor.h" @@ -117,7 +117,7 @@ FreehandBase::~FreehandBase() { void FreehandBase::setup() { ToolBase::setup(); - this->selection = sp_desktop_selection(desktop); + this->selection = desktop->getSelection(); // Connect signals to track selection changes this->sel_changed_connection = this->selection->connectChanged( @@ -128,14 +128,14 @@ void FreehandBase::setup() { ); // Create red bpath - this->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->red_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->red_bpath), this->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); // Create red curve this->red_curve = new SPCurve(); // Create blue bpath - this->blue_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->blue_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); // Create blue curve @@ -247,16 +247,14 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points char const *style_str = NULL; style_str = repr->attribute("style"); if (style_str) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str); - stroke_width = style->stroke_width.computed; - style->stroke_width.computed = 0; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str); + stroke_width = style.stroke_width.computed; } std::ostringstream s; s.imbue(std::locale::classic()); - s << "0," << stroke_width / 2.; + s << points[0][Geom::X] << "," << stroke_width / 2.; // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); @@ -500,7 +498,7 @@ void spdc_endpoint_snap_free(ToolBase const * const ec, Geom::Point& p, boost::o { SPDesktop *dt = ec->desktop; SnapManager &m = dt->namedview->snap_manager; - Inkscape::Selection *selection = sp_desktop_selection (dt); + Inkscape::Selection *selection = dt->getSelection(); // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping) // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment @@ -667,7 +665,7 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) : dc->desktop->dt2doc() ); SPDesktop *desktop = dc->desktop; - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { @@ -703,8 +701,8 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) dc->selection->set(repr); Inkscape::GC::release(repr); item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); item->updateRepr(); + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, @@ -715,7 +713,7 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) // results in the tool losing all of the selected path's curve except that last subpath. To // fix this, we force the selection_modified callback now, to make sure the tool's curve is // in sync immediately. - spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + spdc_selection_modified(desktop->getSelection(), 0, dc); } c->unref(); @@ -821,14 +819,11 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too // find out stroke width (TODO: is there an easier way??) double stroke_width = 3.0; - gchar const *style_str = NULL; - style_str = repr->attribute("style"); + gchar const *style_str = repr->attribute("style"); if (style_str) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str); - stroke_width = style->stroke_width.computed; - style->stroke_width.computed = 0; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str); + stroke_width = style.stroke_width.computed; } // unset stroke and set fill color to former stroke color @@ -862,10 +857,10 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too sp_repr_set_svg_double (repr, "sodipodi:ry", rad * stroke_width); item->updateRepr(); - sp_desktop_selection(desktop)->set(item); + desktop->getSelection()->set(item); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single dot")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, _("Create single dot")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create single dot")); } } diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index 9c853917e..5da30da7b 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -23,7 +23,7 @@ #include "document.h" #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "message-context.h" #include "message-stack.h" #include "pixmaps/cursor-gradient.xpm" @@ -112,7 +112,7 @@ void GradientTool::selection_changed(Inkscape::Selection*) { GradientTool *rc = (GradientTool *) this; GrDrag *drag = rc->_grdrag; - Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(rc)->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (selection == NULL) { return; } @@ -167,7 +167,7 @@ void GradientTool::setup() { } this->enableGrDrag(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->selcon = new sigc::connection(selection->connectChanged( sigc::mem_fun(this, &GradientTool::selection_changed) @@ -464,7 +464,7 @@ sp_gradient_context_add_stop_near_point (GradientTool *rc, SPItem *item, Geom:: SPStop *newstop = ec->get_drag()->addStopNearPoint (item, mouse_p, tolerance/desktop->current_zoom()); - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Add gradient stop")); ec->get_drag()->updateDraggers(); @@ -475,7 +475,7 @@ sp_gradient_context_add_stop_near_point (GradientTool *rc, SPItem *item, Geom:: bool GradientTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -509,13 +509,13 @@ bool GradientTool::root_handler(GdkEvent* event) { SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR); Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; - SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, item, fsmode); + SPGradient *vector = sp_gradient_vector_for_object(desktop->getDocument(), desktop, item, fsmode); SPGradient *priv = sp_item_set_gradient(item, vector, new_type, fsmode); sp_gradient_reset_to_userspace(priv, item); } - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Create default gradient")); } ret = TRUE; @@ -892,8 +892,8 @@ bool GradientTool::root_handler(GdkEvent* event) { static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*state*/, guint32 etime) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); ToolBase *ec = SP_EVENT_CONTEXT(&rc); if (!selection->isEmpty()) { @@ -957,7 +957,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), n_objects); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); } } diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index 1fd1ebf8c..c9b656397 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -30,7 +30,7 @@ #include "preferences.h" #include "ui/shape-editor.h" #include "selection.h" -#include "desktop-handles.h" + #include "document.h" #include "display/curve.h" #include "display/canvas-bpath.h" @@ -110,7 +110,7 @@ LpeTool::~LpeTool() { void LpeTool::setup() { PenTool::setup(); - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); SPItem *item = selection->singleItem(); this->sel_changed_connection.disconnect(); @@ -164,7 +164,7 @@ bool LpeTool::item_handler(SPItem* item, GdkEvent* event) { case GDK_BUTTON_PRESS: { // select the clicked item but do nothing else - Inkscape::Selection * const selection = sp_desktop_selection(this->desktop); + Inkscape::Selection * const selection = this->desktop->getSelection(); selection->clear(); selection->add(item); ret = TRUE; @@ -186,7 +186,7 @@ bool LpeTool::item_handler(SPItem* item, GdkEvent* event) { } bool LpeTool::root_handler(GdkEvent* event) { - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); bool ret = false; @@ -305,12 +305,12 @@ int lpetool_item_has_construction(LpeTool */*lc*/, SPItem *item) bool lpetool_try_construction(LpeTool *lc, Inkscape::LivePathEffect::EffectType const type) { - Inkscape::Selection *selection = sp_desktop_selection(lc->desktop); + Inkscape::Selection *selection = lc->desktop->getSelection(); SPItem *item = selection->singleItem(); // TODO: should we check whether type represents a valid geometric construction? if (item && SP_IS_LPE_ITEM(item) && Inkscape::LivePathEffect::Effect::acceptsNumClicks(type) == 0) { - Inkscape::LivePathEffect::Effect::createAndApply(type, sp_desktop_document(lc->desktop), item); + Inkscape::LivePathEffect::Effect::createAndApply(type, lc->desktop->getDocument(), item); return true; } return false; @@ -360,7 +360,7 @@ lpetool_context_reset_limiting_bbox(LpeTool *lc) if (!prefs->getBool("/tools/lpetool/show_bbox", true)) return; - SPDocument *document = sp_desktop_document(lc->desktop); + SPDocument *document = lc->desktop->getDocument(); Geom::Point A, B; lpetool_get_limiting_bbox_corners(document, A, B); @@ -371,7 +371,7 @@ lpetool_context_reset_limiting_bbox(LpeTool *lc) Geom::Rect rect(A, B); SPCurve *curve = SPCurve::new_from_rect(rect); - lc->canvas_bbox = sp_canvas_bpath_new (sp_desktop_controls(lc->desktop), curve); + lc->canvas_bbox = sp_canvas_bpath_new (lc->desktop->getControls(), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(lc->canvas_bbox), 0x0000ffff, 0.8, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT, 5, 5); } @@ -396,7 +396,7 @@ void lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) { if (!selection) { - selection = sp_desktop_selection(lc->desktop); + selection = lc->desktop->getSelection(); } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show = prefs->getBool("/tools/lpetool/show_measuring_info", true); @@ -404,7 +404,7 @@ lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) SPPath *path; SPCurve *curve; SPCanvasText *canvas_text; - SPCanvasGroup *tmpgrp = sp_desktop_tempgroup(lc->desktop); + SPCanvasGroup *tmpgrp = lc->desktop->getTempGroup(); gchar *arc_length; double lengthval; diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 6b5cbeccd..b7e54b9c8 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -29,7 +29,7 @@ #include "pixmaps/cursor-measure.xpm" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "ui/tools/measure-tool.h" #include "ui/tools/freehand-base.h" #include "display/canvas-text.h" @@ -228,7 +228,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom yc + ay + (k2 * ax)); Geom::Point p3(xc + bx + (k2 * by), yc + by - (k2 * bx)); - SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(sp_desktop_tempgroup(desktop), p1, p2, p3, p4, CTLINE_SECONDARY); + SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(desktop->getTempGroup(), p1, p2, p3, p4, CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); } @@ -291,7 +291,7 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: //TODO: consider only visible intersections Geom::Point intersection = lineseg[0].pointAt((*m).ta); double eps = 0.0001; - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); if (((*m).ta > eps && item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) || ((*m).ta + eps < 1 && @@ -441,7 +441,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO switch to a different variable name. The single letter 'l' is easy to misread. //select elements crossed by line segment: - GSList *items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, points); + GSList *items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points); std::vector<double> intersection_times; for (GSList *l = items; l != NULL; l = l->next) { SPItem *item = static_cast<SPItem*>(l->data); @@ -525,7 +525,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *measure_str = g_strdup_printf("%.2f %s", place.lengthVal, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, place.end, measure_str); @@ -548,7 +548,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *angle_str = g_strdup_printf("%.2f °", angle * 180/M_PI); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, angleDisplayPt, angle_str); @@ -569,7 +569,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), totallength_str); @@ -590,7 +590,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *total_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * 60, total_str); @@ -609,7 +609,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { for (size_t idx = 0; idx < intersections.size(); ++idx) { // Display the intersection indicator (i.e. the cross) - SPCanvasItem * canvasitem = sp_canvas_item_new(sp_desktop_tempgroup(desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, @@ -627,7 +627,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // draw main control line { - SPCtrlLine *control_line = ControlManager::getManager().createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), start_point, end_point); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); @@ -642,7 +642,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { * Geom::Affine(Geom::Translate(start_point))); } - SPCtrlLine *control_line = ControlManager::getManager().createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), start_point, anchorEnd, CTLINE_SECONDARY); @@ -655,17 +655,17 @@ bool MeasureTool::root_handler(GdkEvent* event) { if (intersections.size() > 2) { ControlManager &mgr = ControlManager::getManager(); SPCtrlLine *control_line = 0; - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]) + normal * 60, desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 60); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * 65); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 65); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); @@ -677,7 +677,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { LabelPlacement &place = *it; ControlManager &mgr = ControlManager::getManager(); - SPCtrlLine *control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), place.start, place.end, CTLINE_SECONDARY); @@ -689,7 +689,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2; ControlManager &mgr = ControlManager::getManager(); - SPCtrlLine *control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(measure_text_pos), desktop->doc2dt(measure_text_pos) - (normal * DIMENSION_OFFSET), CTLINE_SECONDARY); @@ -699,7 +699,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // Initial point { - SPCanvasItem * canvasitem = sp_canvas_item_new(sp_desktop_tempgroup(desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 8a1fb7c72..d333b932e 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -27,7 +27,7 @@ // General #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "macros.h" @@ -107,7 +107,7 @@ const gchar *ms_handle_descr [] = { void MeshTool::selection_changed(Inkscape::Selection* /*sel*/) { GrDrag *drag = this->_grdrag; - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (selection == NULL) { return; @@ -234,7 +234,7 @@ void MeshTool::setup() { } this->enableGrDrag(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->selcon = new sigc::connection(selection->connectChanged( sigc::mem_fun(this, &MeshTool::selection_changed) @@ -317,7 +317,7 @@ static void sp_mesh_context_split_near_point(MeshTool *rc, SPItem *item, Geom:: ec->get_drag()->addStopNearPoint (item, mouse_p, tolerance/desktop->current_zoom()); - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Split mesh row/column")); ec->get_drag()->updateDraggers(); @@ -440,7 +440,7 @@ Handles all keyboard and mouse input for meshs. bool MeshTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -488,13 +488,13 @@ bool MeshTool::root_handler(GdkEvent* event) { #ifdef DEBUG_MESH std::cout << "sp_mesh_context_root_handler: creating new mesh on: " << (fsmode == Inkscape::FOR_FILL ? "Fill" : "Stroke") << std::endl; #endif - SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, item, fsmode); + SPGradient *vector = sp_gradient_vector_for_object(desktop->getDocument(), desktop, item, fsmode); SPGradient *priv = sp_item_set_gradient(item, vector, new_type, fsmode); sp_gradient_reset_to_userspace(priv, item); } - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Create default mesh")); } @@ -933,8 +933,8 @@ bool MeshTool::root_handler(GdkEvent* event) { static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/, guint32 /*etime*/) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); ToolBase *ec = SP_EVENT_CONTEXT(&rc); if (!selection->isEmpty()) { @@ -994,7 +994,7 @@ static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/ "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), n_objects); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); } } diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index e2bb85d11..caec901a6 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -13,7 +13,7 @@ #include "ui/tool/curve-drag-point.h" #include <glib/gi18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas-group.h" #include "display/canvas-bpath.h" #include "display/curve.h" @@ -155,7 +155,7 @@ NodeTool::NodeTool() SPCanvasGroup *create_control_group(SPDesktop *d) { return reinterpret_cast<SPCanvasGroup*>(sp_canvas_item_new( - sp_desktop_controls(d), SP_TYPE_CANVAS_GROUP, NULL)); + d->getControls(), SP_TYPE_CANVAS_GROUP, NULL)); } void destroy_group(SPCanvasGroup *g) @@ -215,7 +215,7 @@ void NodeTool::setup() { data.node_data.node_group = create_control_group(this->desktop); data.node_data.handle_group = create_control_group(this->desktop); - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->_selection_changed_connection.disconnect(); this->_selection_changed_connection = @@ -295,7 +295,7 @@ void NodeTool::setup() { // show helper paths of the applied LPE, if any void NodeTool::update_helperpath () { - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (this->helperpath_tmpitem) { this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); @@ -305,6 +305,16 @@ void NodeTool::update_helperpath () { if (SP_IS_LPE_ITEM(selection->singleItem())) { Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + Inkscape::UI::ControlPointSelection::Set &selectionNodes = _selected_nodes->allPoints(); + std::vector<Geom::Point> selectedNodesPositions; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = selectionNodes.begin(); i != selectionNodes.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); + selectedNodesPositions.push_back(n->position()); + } + } + lpe->setSelectedNodePoints(selectedNodesPositions); + lpe->setCurrentZoom(this->desktop->current_zoom()); SPCurve *c = new SPCurve(); SPCurve *cc = new SPCurve(); std::vector<Geom::PathVector> cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); @@ -314,7 +324,7 @@ void NodeTool::update_helperpath () { cc->reset(); } if (!c->is_empty()) { - SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + SPCanvasItem *helperpath = sp_canvas_bpath_new(this->desktop->getTempGroup(), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), 0x0000ff9A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); sp_canvas_item_affine_absolute(helperpath, selection->singleItem()->i2dt_affine()); @@ -517,7 +527,7 @@ bool NodeTool::root_handler(GdkEvent* event) { } c->transform(over_item->i2dt_affine()); - SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); + SPCanvasItem *flash = sp_canvas_bpath_new(desktop->getTempGroup(), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), //prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, @@ -658,7 +668,7 @@ void NodeTool::select_area(Geom::Rect const &sel, GdkEventButton *event) { if (this->_multipath->empty()) { // if multipath is empty, select rubberbanded items rather than nodes Inkscape::Selection *selection = this->desktop->selection; - GSList *items = sp_desktop_document(this->desktop)->getItemsInBox(this->desktop->dkey, sel); + GSList *items = this->desktop->getDocument()->getItemsInBox(this->desktop->dkey, sel); selection->setList(items); g_slist_free(items); } else { diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index ab72f3632..20375e869 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -33,6 +33,8 @@ namespace Inkscape { } } +struct SPCanvasGroup; + #define INK_NODE_TOOL(obj) (dynamic_cast<Inkscape::UI::Tools::NodeTool*>((Inkscape::UI::Tools::ToolBase*)obj)) #define INK_IS_NODE_TOOL(obj) (dynamic_cast<const Inkscape::UI::Tools::NodeTool*>((const Inkscape::UI::Tools::ToolBase*)obj)) diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 92937a135..5174775c9 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -20,10 +20,13 @@ #include <cstring> #include <string> +#include "shortcuts.h" +#include "verbs.h" + #include "ui/tools/pen-tool.h" #include "sp-namedview.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "selection-chemistry.h" #include "ui/draw-anchor.h" @@ -192,14 +195,14 @@ void PenTool::setup() { ControlManager &mgr = ControlManager::getManager(); // Pen indicators - this->c0 = mgr.createControl(sp_desktop_controls(this->desktop), Inkscape::CTRL_TYPE_ADJ_HANDLE); + this->c0 = mgr.createControl(this->desktop->getControls(), Inkscape::CTRL_TYPE_ADJ_HANDLE); mgr.track(this->c0); - this->c1 = mgr.createControl(sp_desktop_controls(this->desktop), Inkscape::CTRL_TYPE_ADJ_HANDLE); + this->c1 = mgr.createControl(this->desktop->getControls(), Inkscape::CTRL_TYPE_ADJ_HANDLE); mgr.track(this->c1); - this->cl0 = mgr.createControlLine(sp_desktop_controls(this->desktop)); - this->cl1 = mgr.createControlLine(sp_desktop_controls(this->desktop)); + this->cl0 = mgr.createControlLine(this->desktop->getControls()); + this->cl1 = mgr.createControlLine(this->desktop->getControls()); sp_canvas_item_hide(this->c0); sp_canvas_item_hide(this->c1); @@ -468,7 +471,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { // This is the first click of a new curve; deselect item so that // this curve is not combined with it (unless it is drawn from its // anchor, which is handled by the sibling branch above) - Inkscape::Selection * const selection = sp_desktop_selection(desktop); + Inkscape::Selection * const selection = desktop->getSelection(); if (!(bevent.state & GDK_SHIFT_MASK) || this->hasWaitingLPE()) { // if we have a waiting LPE, we need a fresh path to be created // so don't append to an existing one @@ -614,7 +617,12 @@ bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { ret = true; break; case PenTool::STOP: - // This is perfectly valid + if (!this->sp_event_context_knot_mouseover()) { + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE)); + m.unSetup(); + } break; default: break; @@ -685,8 +693,7 @@ bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { ret = true; break; case PenTool::STOP: - // This is perfectly valid - break; + // Don't break; fall through to default to do preSnapping default: if (!this->sp_event_context_knot_mouseover()) { SnapManager &m = desktop->namedview->snap_manager; @@ -846,7 +853,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { if (this->expecting_clicks_for_LPE == 0 && this->hasWaitingLPE()) { this->setPolylineMode(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (this->waiting_LPE) { // we have an already created LPE waiting for a path @@ -881,7 +888,7 @@ void PenTool::_redrawAll() { this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // one canvas bpath for all of green_curve - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), this->green_curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), this->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); @@ -1064,6 +1071,23 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000, "px"); // in px + // Check for undo if we have started drawing a path. + if (this->npoints > 0) { + unsigned int shortcut = Inkscape::UI::Tools::get_group0_keyval (&event->key) | + ( event->key.state & GDK_SHIFT_MASK ? + SP_SHORTCUT_SHIFT_MASK : 0 ) | + ( event->key.state & GDK_CONTROL_MASK ? + SP_SHORTCUT_CONTROL_MASK : 0 ) | + ( event->key.state & GDK_MOD1_MASK ? + SP_SHORTCUT_ALT_MASK : 0 ); + Inkscape::Verb* verb = sp_shortcut_get_verb(shortcut); + if (verb) { + unsigned int vcode = verb->get_code(); + if (vcode == SP_VERB_EDIT_UNDO) + return _undoLastPoint(); + } + } + switch (get_group0_keyval (&event->key)) { case GDK_KEY_Left: // move last point left case GDK_KEY_KP_Left: @@ -1218,14 +1242,6 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { ret = true; } break; - case GDK_KEY_z: - case GDK_KEY_Z: - if (MOD__CTRL_ONLY(event) && this->npoints != 0) { - // if drawing, cancel, otherwise pass it up for undo - this->_cancel (); - ret = true; - } - break; case GDK_KEY_g: case GDK_KEY_G: if (MOD__SHIFT_ONLY(event)) { @@ -1236,83 +1252,7 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { case GDK_KEY_BackSpace: case GDK_KEY_Delete: case GDK_KEY_KP_Delete: - if ( this->green_curve->is_empty() || (this->green_curve->last_segment() == NULL) ) { - if (!this->red_curve->is_empty()) { - this->_cancel (); - ret = true; - } else { - // do nothing; this event should be handled upstream - } - } else { - // Reset red curve - this->red_curve->reset(); - // Destroy topmost green bpath - if (this->green_bpaths) { - if (this->green_bpaths->data) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); - } - this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); - } - // Get last segment - if ( this->green_curve->is_empty() ) { - g_warning("pen_handle_key_press, case GDK_KP_Delete: Green curve is empty"); - break; - } - // The code below assumes that this->green_curve has only ONE path ! - Geom::Curve const * crv = this->green_curve->last_segment(); - this->p[0] = crv->initialPoint(); - if ( Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>(crv)) { - this->p[1] = (*cubic)[1]; - - } else { - this->p[1] = this->p[0]; - } - - // asign the value in a third of the distance of the last segment. - if (this->bspline){ - this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); - } - - Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); - - this->npoints = 2; - // delete the last segment of the green curve - if (this->green_curve->get_segment_count() == 1) { - this->npoints = 5; - if (this->green_bpaths) { - if (this->green_bpaths->data) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); - } - this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); - } - this->green_curve->reset(); - } else { - this->green_curve->backspace(); - } - - // assign the value of this->p[1] to the oposite of the green line last segment - if (this->spiro){ - Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(this->green_curve->last_segment()); - if ( cubic ) { - this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; - SP_CTRL(this->c1)->moveto(this->p[0]); - } else { - this->p[1] = this->p[0]; - } - } - - sp_canvas_item_hide(this->c0); - sp_canvas_item_hide(this->c1); - sp_canvas_item_hide(this->cl0); - sp_canvas_item_hide(this->cl1); - this->state = PenTool::POINT; - this->_setSubsequentPoint(pt, true); - pen_last_paraxial_dir = !pen_last_paraxial_dir; - - //redraw - this->_bspline_spiro_build(); - ret = true; - } + ret = _undoLastPoint(); break; default: break; @@ -1366,7 +1306,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t Geom::Point rel = p - this->p[pc_point_to_compare]; Inkscape::Util::Quantity q = Inkscape::Util::Quantity(Geom::L2(rel), "px"); - GString *dist = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *dist = g_string_new(q.string(desktop->namedview->display_units).c_str()); double angle = atan2(rel[Geom::Y], rel[Geom::X]) * 180 / M_PI; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/compassangledisplay/value", 0) != 0) { @@ -1415,7 +1355,7 @@ void PenTool::_bspline_spiro_color() this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // one canvas bpath for all of green_curve - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), this->green_curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), this->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape); @@ -2161,7 +2101,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { SPCurve *curve = this->red_curve->copy(); /// \todo fixme: - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), curve); curve->unref(); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -2175,6 +2115,92 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { } } +// Partial fix for https://bugs.launchpad.net/inkscape/+bug/171990 +// TODO: implement the redo feature +bool PenTool::_undoLastPoint() { + bool ret = false; + + if ( this->green_curve->is_empty() || (this->green_curve->last_segment() == NULL) ) { + if (!this->red_curve->is_empty()) { + this->_cancel (); + ret = true; + } else { + // do nothing; this event should be handled upstream + } + } else { + // Reset red curve + this->red_curve->reset(); + // Destroy topmost green bpath + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + // Get last segment + if ( this->green_curve->is_empty() ) { + g_warning("pen_handle_key_press, case GDK_KP_Delete: Green curve is empty"); + return false; + } + // The code below assumes that this->green_curve has only ONE path ! + Geom::Curve const * crv = this->green_curve->last_segment(); + this->p[0] = crv->initialPoint(); + if ( Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>(crv)) { + this->p[1] = (*cubic)[1]; + + } else { + this->p[1] = this->p[0]; + } + + // asign the value in a third of the distance of the last segment. + if (this->bspline){ + this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); + } + + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); + + this->npoints = 2; + // delete the last segment of the green curve + if (this->green_curve->get_segment_count() == 1) { + this->npoints = 5; + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + this->green_curve->reset(); + } else { + this->green_curve->backspace(); + } + + // assign the value of this->p[1] to the oposite of the green line last segment + if (this->spiro){ + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(this->green_curve->last_segment()); + if ( cubic ) { + this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; + SP_CTRL(this->c1)->moveto(this->p[0]); + } else { + this->p[1] = this->p[0]; + } + } + + sp_canvas_item_hide(this->c0); + sp_canvas_item_hide(this->c1); + sp_canvas_item_hide(this->cl0); + sp_canvas_item_hide(this->cl1); + this->state = PenTool::POINT; + this->_setSubsequentPoint(pt, true); + pen_last_paraxial_dir = !pen_last_paraxial_dir; + + //redraw + this->_bspline_spiro_build(); + ret = true; + } + + return ret; +} + void PenTool::_finish(gboolean const closed) { if (this->expecting_clicks_for_LPE > 1) { // don't let the path be finished before we have collected the required number of mouse clicks @@ -2277,7 +2303,7 @@ void PenTool::_setToNearestHorizVert(Geom::Point &pt, guint const state, bool sn // Snap along the constraint line; if we didn't snap then still the constraint will be applied SnapManager &m = this->desktop->namedview->snap_manager; - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping) // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 98fd0a43e..2208005c5 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -121,6 +121,7 @@ private: void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); void _setCtrl(Geom::Point const p, guint state); void _finishSegment(Geom::Point p, guint state); + bool _undoLastPoint(); void _finish(gboolean closed); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 3ea2ae843..28fed3a8f 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -20,7 +20,7 @@ #include "ui/tools/pencil-tool.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "selection-chemistry.h" #include "ui/draw-anchor.h" @@ -153,7 +153,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) { bool ret = false; if ( bevent.button == 1 && !this->space_panning) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (Inkscape::have_viable_layer(desktop, this->message_context) == false) { return true; @@ -853,7 +853,7 @@ void PencilTool::_fitAndSplit() { SPCurve *curve = this->red_curve->copy(); /// \todo fixme: - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), curve); curve->unref(); this->highlight_color = SP_ITEM(this->desktop->currentLayer())->highlight_color(); diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index de91dcff4..9476ff624 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -28,7 +28,7 @@ #include "sp-namedview.h" #include "selection.h" #include "selection-chemistry.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -111,13 +111,13 @@ void RectTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &RectTool::selection_changed) ); @@ -170,7 +170,7 @@ bool RectTool::root_handler(GdkEvent* event) { static bool dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -422,8 +422,8 @@ void RectTool::drag(Geom::Point const pt, guint state) { Inkscape::Util::Quantity rdimx_q = Inkscape::Util::Quantity(rdimx, "px"); Inkscape::Util::Quantity rdimy_q = Inkscape::Util::Quantity(rdimy, "px"); - GString *xs = g_string_new(rdimx_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(rdimy_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(rdimx_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(rdimy_q.string(desktop->namedview->display_units).c_str()); if (state & GDK_CONTROL_MASK) { int ratio_x, ratio_y; @@ -476,16 +476,16 @@ void RectTool::finishItem() { this->desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(this->desktop)->set(this->rect); + this->desktop->getSelection()->set(this->rect); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_RECT, _("Create rectangle")); + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Create rectangle")); this->rect = NULL; } } void RectTool::cancel(){ - sp_desktop_selection(this->desktop)->clear(); + this->desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(this->desktop->acetate), 0); if (this->rect != NULL) { @@ -500,7 +500,7 @@ void RectTool::cancel(){ this->desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(this->desktop)); + DocumentUndo::cancel(this->desktop->getDocument()); } } diff --git a/src/ui/tools/rect-tool.h b/src/ui/tools/rect-tool.h index a50fd7b24..a22f1caa8 100644 --- a/src/ui/tools/rect-tool.h +++ b/src/ui/tools/rect-tool.h @@ -6,6 +6,7 @@ * * Author: * Lauris Kaplinski <lauris@kaplinski.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2000 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. @@ -21,9 +22,6 @@ #include "sp-rect.h" -#define SP_RECT_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::RectTool*>((Inkscape::UI::Tools::ToolBase*)obj)) -#define SP_IS_RECT_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::RectTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) - namespace Inkscape { namespace UI { namespace Tools { diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 21459e5d0..939b1a0b3 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -38,7 +38,7 @@ #include "extension/dbus/document-interface.h" #endif #include "desktop.h" -#include "desktop-handles.h" + #include "sp-root.h" #include "preferences.h" #include "ui/tools-switch.h" @@ -208,7 +208,7 @@ bool SelectTool::sp_select_context_abort() { if (this->item) { // only undo if the item is still valid if (this->item->document) { - DocumentUndo::undo(sp_desktop_document(desktop)); + DocumentUndo::undo(desktop->getDocument()); } sp_object_unref( this->item, NULL); @@ -216,7 +216,7 @@ bool SelectTool::sp_select_context_abort() { // NOTE: This is a workaround to a bug. // When the ctrl key is held, sc->item is not defined // so in this case (only), we skip the object doc check - DocumentUndo::undo(sp_desktop_document(desktop)); + DocumentUndo::undo(desktop->getDocument()); } this->item = NULL; @@ -272,7 +272,7 @@ sp_select_context_up_one_layer(SPDesktop *desktop) { desktop->setCurrentLayer(parent); if (current_group && (SPGroup::LAYER != current_group->layerMode())) { - sp_desktop_selection(desktop)->set(current_layer); + desktop->getSelection()->set(current_layer); } } } @@ -308,7 +308,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { // if shift or ctrl was pressed, do not move objects; // pass the event to root handler which will perform rubberband, shift-click, ctrl-click, ctrl-drag } else { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); this->dragging = TRUE; this->moved = FALSE; @@ -353,7 +353,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { case GDK_ENTER_NOTIFY: { if (!desktop->isWaitingCursor() && !this->dragging) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectMouseover); } @@ -361,7 +361,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { } case GDK_LEAVE_NOTIFY: if (!desktop->isWaitingCursor() && !this->dragging) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, this->cursor); } @@ -469,7 +469,7 @@ bool SelectTool::root_handler(GdkEvent* event) { SPItem *item_at_point = NULL, *group_at_point = NULL, *item_in_group = NULL; gint ret = FALSE; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // make sure we still have valid objects to move around @@ -485,7 +485,7 @@ bool SelectTool::root_handler(GdkEvent* event) { if (dynamic_cast<SPGroup *>(clicked_item) && !dynamic_cast<SPBox3D *>(clicked_item)) { // enter group if it's not a 3D box desktop->setCurrentLayer(clicked_item); - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); this->dragging = false; sp_event_context_discard_delayed_snap_event(this); @@ -573,7 +573,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // but not with shift) we want to drag rather than rubberband this->dragging = TRUE; - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectDragging); @@ -702,7 +702,7 @@ bool SelectTool::root_handler(GdkEvent* event) { } this->dragging = FALSE; - window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectMouseover); sp_event_context_discard_delayed_snap_event(this); @@ -722,9 +722,9 @@ bool SelectTool::root_handler(GdkEvent* event) { if (r->getMode() == RUBBERBAND_MODE_RECT) { Geom::OptRect const b = r->getRectangle(); - items = sp_desktop_document(desktop)->getItemsInBox(desktop->dkey, *b); + items = desktop->getDocument()->getItemsInBox(desktop->dkey, *b); } else if (r->getMode() == RUBBERBAND_MODE_TOUCHPATH) { - items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, r->getPoints()); + items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); } _seltrans->resetState(); @@ -953,7 +953,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // if Alt and nonempty selection, show moving cursor ("move selected"): if (alt && !selection->isEmpty() && !desktop->isWaitingCursor()) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectDragging); } @@ -974,15 +974,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*-10, 0); // shift + sp_selection_move_screen(desktop->getSelection(), mul*-10, 0); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*-1, 0); // no shift + sp_selection_move_screen(desktop->getSelection(), mul*-1, 0); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), mul*-10*nudge, 0); // shift + sp_selection_move(desktop->getSelection(), mul*-10*nudge, 0); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), mul*-nudge, 0); // no shift + sp_selection_move(desktop->getSelection(), mul*-nudge, 0); // no shift } } @@ -997,15 +997,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*10); // shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*10); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*1); // no shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*1); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*10*nudge); // shift + sp_selection_move(desktop->getSelection(), 0, mul*10*nudge); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*nudge); // no shift + sp_selection_move(desktop->getSelection(), 0, mul*nudge); // no shift } } @@ -1020,15 +1020,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*10, 0); // shift + sp_selection_move_screen(desktop->getSelection(), mul*10, 0); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*1, 0); // no shift + sp_selection_move_screen(desktop->getSelection(), mul*1, 0); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), mul*10*nudge, 0); // shift + sp_selection_move(desktop->getSelection(), mul*10*nudge, 0); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), mul*nudge, 0); // no shift + sp_selection_move(desktop->getSelection(), mul*nudge, 0); // no shift } } @@ -1043,15 +1043,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-10); // shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*-10); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-1); // no shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*-1); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*-10*nudge); // shift + sp_selection_move(desktop->getSelection(), 0, mul*-10*nudge); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*-nudge); // no shift + sp_selection_move(desktop->getSelection(), 0, mul*-nudge); // no shift } } @@ -1153,9 +1153,9 @@ bool SelectTool::root_handler(GdkEvent* event) { if (selection->singleItem()) { SPItem *clicked_item = selection->singleItem(); SPGroup *clickedGroup = dynamic_cast<SPGroup *>(clicked_item); - if ( (clickedGroup && (clickedGroup->layerMode() == SPGroup::LAYER)) || dynamic_cast<SPBox3D *>(clicked_item)) { // enter group or a 3D box + if ( (clickedGroup && (clickedGroup->layerMode() != SPGroup::LAYER)) || dynamic_cast<SPBox3D *>(clicked_item)) { // enter group or a 3D box desktop->setCurrentLayer(clicked_item); - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); } else { this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); } @@ -1226,7 +1226,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // set cursor to default. if (!desktop->isWaitingCursor()) { // Do we need to reset the cursor here on key release ? - //GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + //GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); //gdk_window_set_cursor(window, event_context->cursor); } break; diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 18c3e4e2d..f208e1c43 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -27,7 +27,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -117,12 +117,12 @@ void SpiralTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); this->sel_changed_connection = selection->connectChanged(sigc::mem_fun(this, &SpiralTool::selection_changed)); @@ -154,7 +154,7 @@ bool SpiralTool::root_handler(GdkEvent* event) { static gboolean dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -395,7 +395,7 @@ void SpiralTool::drag(Geom::Point const &p, guint state) { /* status text */ Inkscape::Util::Quantity q = Inkscape::Util::Quantity(rad, "px"); - GString *rads = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *rads = g_string_new(q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Spiral</b>: radius %s, angle %5g°; with <b>Ctrl</b> to snap angle"), rads->str, sp_round((arg + 2.0*M_PI*this->spiral->revo)*180/M_PI, 0.0001)); @@ -417,15 +417,15 @@ void SpiralTool::finishItem() { this->desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(this->desktop)->set(this->spiral); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_SPIRAL, _("Create spiral")); + this->desktop->getSelection()->set(this->spiral); + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, _("Create spiral")); this->spiral = NULL; } } void SpiralTool::cancel() { - sp_desktop_selection(this->desktop)->clear(); + this->desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(this->desktop->acetate), 0); if (this->spiral != NULL) { @@ -440,7 +440,7 @@ void SpiralTool::cancel() { this->desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(this->desktop)); + DocumentUndo::cancel(this->desktop->getDocument()); } } diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index cdc608558..a01c5c55b 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -33,7 +33,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "message-context.h" #include "pixmaps/cursor-spray.xpm" #include <boost/optional.hpp> @@ -222,7 +222,7 @@ void SprayTool::setup() { SPCurve *c = new SPCurve(path); - this->dilate_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->dilate_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->dilate_area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->dilate_area), 0xff9900ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -527,7 +527,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { SPDesktop *desktop = tc->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { return false; @@ -735,15 +735,15 @@ bool SprayTool::root_handler(GdkEvent* event) { this->has_dilated = false; switch (this->mode) { case SPRAY_MODE_COPY: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray with copies")); break; case SPRAY_MODE_CLONE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray with clones")); break; case SPRAY_MODE_SINGLE_PATH: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray in single path")); break; } diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index 7604ba04e..df311f2d8 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -30,7 +30,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -127,12 +127,12 @@ void StarTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); @@ -168,7 +168,7 @@ bool StarTool::root_handler(GdkEvent* event) { static bool dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -411,7 +411,7 @@ void StarTool::drag(Geom::Point p, guint state) /* status text */ Inkscape::Util::Quantity q = Inkscape::Util::Quantity(r1, "px"); - GString *rads = g_string_new(q.string(desktop->namedview->doc_units).c_str()); + GString *rads = g_string_new(q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, ( this->isflatsided? _("<b>Polygon</b>: radius %s, angle %5g°; with <b>Ctrl</b> to snap angle") @@ -441,8 +441,8 @@ void StarTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->star); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + desktop->getSelection()->set(this->star); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Create star")); this->star = NULL; @@ -450,7 +450,7 @@ void StarTool::finishItem() { } void StarTool::cancel() { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0); if (this->star != NULL) { @@ -465,7 +465,7 @@ void StarTool::cancel() { desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index a72748733..df0583d67 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -26,7 +26,7 @@ #include <sstream> #include "context-fns.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "desktop.h" #include "document.h" @@ -131,17 +131,17 @@ void TextTool::setup() { timeout /= 2; } - this->cursor = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop), Geom::Point(100, 0), Geom::Point(100, 100)); + this->cursor = ControlManager::getManager().createControlLine(desktop->getControls(), Geom::Point(100, 0), Geom::Point(100, 100)); this->cursor->setRgba32(0x000000ff); sp_canvas_item_hide(this->cursor); - this->indicator = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL); + this->indicator = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRLRECT, NULL); SP_CTRLRECT(this->indicator)->setRectangle(Geom::Rect(Geom::Point(0, 0), Geom::Point(100, 100))); SP_CTRLRECT(this->indicator)->setColor(0x0000ff7f, false, 0); SP_CTRLRECT(this->indicator)->setShadow(1, 0xffffff7f); sp_canvas_item_hide(this->indicator); - this->frame = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL); + this->frame = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRLRECT, NULL); SP_CTRLRECT(this->frame)->setRectangle(Geom::Rect(Geom::Point(0, 0), Geom::Point(100, 100))); SP_CTRLRECT(this->frame)->setColor(0x0000ff7f, false, 0); sp_canvas_item_hide(this->frame); @@ -150,7 +150,7 @@ void TextTool::setup() { this->imc = gtk_im_multicontext_new(); if (this->imc) { - GtkWidget *canvas = GTK_WIDGET(sp_desktop_canvas(desktop)); + GtkWidget *canvas = GTK_WIDGET(desktop->getCanvas()); /* im preedit handling is very broken in inkscape for * multi-byte characters. See bug 1086769. @@ -175,15 +175,15 @@ void TextTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { this->shape_editor->set_item(item); } - this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst( + this->sel_changed_connection = desktop->getSelection()->connectChangedFirst( sigc::mem_fun(*this, &TextTool::_selectionChanged) ); - this->sel_modified_connection = sp_desktop_selection(desktop)->connectModifiedFirst( + this->sel_modified_connection = desktop->getSelection()->connectModifiedFirst( sigc::mem_fun(*this, &TextTool::_selectionModified) ); this->style_set_connection = desktop->connectSetStyle( @@ -193,7 +193,7 @@ void TextTool::setup() { sigc::mem_fun(*this, &TextTool::_styleQueried) ); - _selectionChanged(sp_desktop_selection(desktop)); + _selectionChanged(desktop->getSelection()); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/text/selcue")) { @@ -206,7 +206,7 @@ void TextTool::setup() { void TextTool::finish() { if (this->desktop) { - sp_signal_disconnect_by_data(sp_desktop_canvas(this->desktop), this); + sp_signal_disconnect_by_data(this->desktop->getCanvas(), this); } this->enableGrDrag(false); @@ -268,7 +268,7 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) { // find out clicked item, disregarding groups item_ungrouped = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE); if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) { - sp_desktop_selection(desktop)->set(item_ungrouped); + desktop->getSelection()->set(item_ungrouped); if (this->text) { // find out click point in document coordinates Geom::Point p = desktop->w2d(Geom::Point(event->button.x, event->button.y)); @@ -425,13 +425,13 @@ static void sp_text_context_setup_text(TextTool *tc) SPItem *text_item = SP_ITEM(ec->desktop->currentLayer()->appendChildRepr(rtext)); /* fixme: Is selection::changed really immediate? */ /* yes, it's immediate .. why does it matter? */ - sp_desktop_selection(ec->desktop)->set(text_item); + ec->desktop->getSelection()->set(text_item); Inkscape::GC::release(rtext); text_item->transform = SP_ITEM(ec->desktop->currentLayer())->i2doc_affine().inverse(); text_item->updateRepr(); text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true); - DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(ec->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Create text")); } @@ -471,7 +471,7 @@ static void insert_uni_char(TextTool *const tc) tc->text_sel_start = tc->text_sel_end = sp_te_replace(tc->text, tc->text_sel_start, tc->text_sel_end, u); sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); - DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(tc->desktop->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Insert Unicode character")); } } @@ -590,8 +590,8 @@ bool TextTool::root_handler(GdkEvent* event) { // status text Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(fabs((p - this->p0)[Geom::X]), "px"); Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(fabs((p - this->p0)[Geom::Y]), "px"); - GString *xs = g_string_new(x_q.string(desktop->namedview->doc_units).c_str()); - GString *ys = g_string_new(y_q.string(desktop->namedview->doc_units).c_str()); + GString *xs = g_string_new(x_q.string(desktop->namedview->display_units).c_str()); + GString *ys = g_string_new(y_q.string(desktop->namedview->display_units).c_str()); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Flowed text frame</b>: %s × %s"), xs->str, ys->str); g_string_free(xs, FALSE); @@ -627,7 +627,7 @@ bool TextTool::root_handler(GdkEvent* event) { if (this->creating && this->within_tolerance) { /* Button 1, set X & Y & new item */ - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); this->pdoc = desktop->dt2doc(p1); this->show = TRUE; this->phase = 1; @@ -660,9 +660,9 @@ bool TextTool::root_handler(GdkEvent* event) { SPItem *ft = create_flowtext_with_internal_frame (desktop, this->p0, p1); /* Set style */ sp_desktop_apply_style_tool(desktop, ft->getRepr(), "/tools/text", true); - sp_desktop_selection(desktop)->set(ft); + desktop->getSelection()->set(ft); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Flowed text is created.")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Create flowed text")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Create flowed text")); } else { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The frame is <b>too small</b> for the current font size. Flowed text not created.")); } @@ -801,7 +801,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No-break space")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Insert no-break space")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Insert no-break space")); return TRUE; } break; @@ -837,7 +837,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_repr_css_set_property(css, "font-weight", "normal"); sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make bold")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Make bold")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -854,7 +854,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_repr_css_set_property(css, "font-style", "italic"); sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make italic")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Make italic")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -892,7 +892,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("New line")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("New line")); return TRUE; } case GDK_KEY_BackSpace: @@ -933,7 +933,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Backspace")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Backspace")); } return TRUE; case GDK_KEY_Delete: @@ -971,7 +971,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Delete")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete")); } return TRUE; case GDK_KEY_Left: @@ -987,7 +987,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*-1, 0)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorLeftWithControl(); @@ -1011,7 +1011,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*1, 0)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorRightWithControl(); @@ -1035,7 +1035,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*-1)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorUpWithControl(); @@ -1059,7 +1059,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*1)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorDownWithControl(); @@ -1117,7 +1117,7 @@ bool TextTool::root_handler(GdkEvent* event) { } Inkscape::Rubberband::get(desktop)->stop(); } else { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); } this->nascent_object = FALSE; return TRUE; @@ -1134,7 +1134,7 @@ bool TextTool::root_handler(GdkEvent* event) { } else { sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, -90); } - DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise")); + DocumentUndo::maybeDone(desktop->getDocument(), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -1154,7 +1154,7 @@ bool TextTool::root_handler(GdkEvent* event) { } else { sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, 90); } - DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise")); + DocumentUndo::maybeDone(desktop->getDocument(), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -1170,13 +1170,13 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10); else sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing")); } else { if (MOD__SHIFT(event)) sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10); else sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing")); } sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1193,13 +1193,13 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10); else sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing")); } else { if (MOD__SHIFT(event)) sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10); else sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\ + DocumentUndo::maybeDone(desktop->getDocument(), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\ } sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1328,7 +1328,7 @@ bool sp_text_paste_inline(ToolBase *ec) tc->text_sel_start = tc->text_sel_end = sp_te_insert_line(tc->text, tc->text_sel_start); begin = end + 1; } - DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(ec->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Paste text")); return true; @@ -1451,7 +1451,7 @@ bool TextTool::_styleSet(SPCSSAttr const *css) return false; // will get picked up by the parent and applied to the whole text object sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Set text style")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1614,7 +1614,7 @@ static void sp_text_context_update_text_selection(TextTool *tc) quads = sp_te_create_selection_quads(tc->text, tc->text_sel_start, tc->text_sel_end, (tc->text)->i2dt_affine()); for (unsigned i = 0 ; i < quads.size() ; i += 4) { SPCanvasItem *quad_canvasitem; - quad_canvasitem = sp_canvas_item_new(sp_desktop_controls(tc->desktop), SP_TYPE_CTRLQUADR, NULL); + quad_canvasitem = sp_canvas_item_new(tc->desktop->getControls(), SP_TYPE_CTRLQUADR, NULL); // FIXME: make the color settable in prefs // for now, use semitrasparent blue, as cairo cannot do inversion :( sp_ctrlquadr_set_rgba32(SP_CTRLQUADR(quad_canvasitem), 0x00777777); @@ -1661,7 +1661,7 @@ static void sp_text_context_forget_text(TextTool *tc) // the XML editor if ( text_repr && text_repr->parent() ) { sp_repr_unparent(text_repr); - SPDocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_CONTEXT_TEXT, + SPDocumentUndo::done(tc->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove empty text")); } } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 37ca5eeea..a07f2fb86 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -39,7 +39,7 @@ #include "xml/node-event-vector.h" #include "sp-cursor.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-events.h" #include "desktop-style.h" #include "sp-namedview.h" @@ -149,7 +149,7 @@ ToolBase::~ToolBase() { */ void ToolBase::sp_event_context_set_cursor(GdkCursorType cursor_type) { - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); GdkDisplay *display = gdk_display_get_default(); GdkCursor *cursor = gdk_cursor_new_for_display(display, cursor_type); @@ -169,7 +169,7 @@ void ToolBase::sp_event_context_set_cursor(GdkCursorType cursor_type) { * Recreates and draws cursor on desktop related to ToolBase. */ void ToolBase::sp_event_context_update_cursor() { - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); if (gtk_widget_get_window (w)) { GtkStyle *style = gtk_widget_get_style(w); @@ -530,7 +530,7 @@ bool ToolBase::root_handler(GdkEvent* event) { if (panning_cursor == 1) { panning_cursor = 0; - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); } @@ -641,7 +641,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_4: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(i, 0); @@ -654,7 +654,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_8: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(0, i); @@ -667,7 +667,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_6: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(-i, 0); @@ -680,7 +680,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_2: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(0, -i); @@ -740,7 +740,7 @@ bool ToolBase::root_handler(GdkEvent* event) { if (panning_cursor == 1) { panning_cursor = 0; - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); } @@ -1083,7 +1083,7 @@ void sp_event_root_menu_popup(SPDesktop *desktop, SPItem *item, GdkEvent *event) /* fixme: This is not what I want but works for now (Lauris) */ if (event->type == GDK_KEY_PRESS) { - item = sp_desktop_selection(desktop)->singleItem(); + item = desktop->getSelection()->singleItem(); } ContextMenu* CM = new ContextMenu(desktop, item); diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index f56975de2..5e53fdb93 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -28,7 +28,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "pixmaps/cursor-tweak-move.xpm" @@ -274,7 +274,7 @@ void TweakTool::setup() { SPCurve *c = new SPCurve(path); - this->dilate_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->dilate_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->dilate_area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->dilate_area), 0xff9900ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -1032,7 +1032,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, static bool sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point vector, bool reverse) { - Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop); + Inkscape::Selection *selection = tc->desktop->getSelection(); SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop; if (selection->isEmpty()) { @@ -1235,55 +1235,55 @@ bool TweakTool::root_handler(GdkEvent* event) { this->has_dilated = false; switch (this->mode) { case TWEAK_MODE_MOVE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move tweak")); break; case TWEAK_MODE_MOVE_IN_OUT: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move in/out tweak")); break; case TWEAK_MODE_MOVE_JITTER: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move jitter tweak")); break; case TWEAK_MODE_SCALE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Scale tweak")); break; case TWEAK_MODE_ROTATE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Rotate tweak")); break; case TWEAK_MODE_MORELESS: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Duplicate/delete tweak")); break; case TWEAK_MODE_PUSH: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Push path tweak")); break; case TWEAK_MODE_SHRINK_GROW: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Shrink/grow path tweak")); break; case TWEAK_MODE_ATTRACT_REPEL: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Attract/repel path tweak")); break; case TWEAK_MODE_ROUGHEN: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Roughen path tweak")); break; case TWEAK_MODE_COLORPAINT: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Color paint tweak")); break; case TWEAK_MODE_COLORJITTER: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Color jitter tweak")); break; case TWEAK_MODE_BLUR: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Blur tweak")); break; } diff --git a/src/ui/view/view.cpp b/src/ui/view/view.cpp index 72548e213..47e2a1e0d 100644 --- a/src/ui/view/view.cpp +++ b/src/ui/view/view.cpp @@ -20,7 +20,7 @@ #include "message-stack.h" #include "message-context.h" #include "verbs.h" -#include "inkscape-private.h" +#include "inkscape.h" namespace Inkscape { namespace UI { @@ -85,7 +85,7 @@ void View::_close() { if (_doc) { _document_uri_set_connection.disconnect(); _document_resized_connection.disconnect(); - if (inkscape_remove_document(_doc)) { + if (INKSCAPE.remove_document(_doc)) { // this was the last view of this document, so delete it delete _doc; } @@ -111,13 +111,13 @@ void View::setDocument(SPDocument *doc) { if (_doc) { _document_uri_set_connection.disconnect(); _document_resized_connection.disconnect(); - if (inkscape_remove_document(_doc)) { + if (INKSCAPE.remove_document(_doc)) { // this was the last view of this document, so delete it delete _doc; } } - inkscape_add_document(doc); + INKSCAPE.add_document(doc); _doc = doc; _document_uri_set_connection = diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp index ce665295b..0798d1c98 100644 --- a/src/ui/widget/addtoicon.cpp +++ b/src/ui/widget/addtoicon.cpp @@ -127,13 +127,12 @@ void AddToIcon::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window, #endif } -bool -AddToIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool AddToIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp index 6331d70d8..943b1bebc 100644 --- a/src/ui/widget/clipmaskicon.cpp +++ b/src/ui/widget/clipmaskicon.cpp @@ -154,13 +154,12 @@ void ClipMaskIcon::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window, #endif } -bool -ClipMaskIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool ClipMaskIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index 6b5a351f6..d4c4d394e 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -12,7 +12,7 @@ #include "color-picker.h" #include "inkscape.h" -#include "desktop-handles.h" +#include "desktop.h" #include "document.h" #include "document-undo.h" #include "ui/dialog-events.h" @@ -128,7 +128,7 @@ void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp) (ptr->_preview).setRgba32 (rgba); if (ptr->_undo && SP_ACTIVE_DESKTOP) - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE, /* TODO: annotate */ "color-picker.cpp:130"); ptr->on_changed (rgba); diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp index 52e9ea605..c5e14d4f0 100644 --- a/src/ui/widget/dock.cpp +++ b/src/ui/widget/dock.cpp @@ -119,8 +119,9 @@ Dock::Dock(Gtk::Orientation orientation) gdl_dock_bar_set_style(_gdl_dock_bar, gdl_dock_bar_style); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this); + + INKSCAPE.signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dock::hide)); + INKSCAPE.signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dock::show)); g_signal_connect(_paned->gobj(), "button-press-event", G_CALLBACK(_on_paned_button_event), (void *)this); g_signal_connect(_paned->gobj(), "button-release-event", G_CALLBACK(_on_paned_button_event), (void *)this); diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 4754b9c23..242a99073 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -13,7 +13,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "inkscape.h" diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index 8593f0bdf..09999b52d 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -147,13 +147,12 @@ void HighlightPicker::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window, #endif } -bool -HighlightPicker::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool HighlightPicker::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/imageicon.cpp b/src/ui/widget/imageicon.cpp index 22abd04ba..df261b69a 100644 --- a/src/ui/widget/imageicon.cpp +++ b/src/ui/widget/imageicon.cpp @@ -88,8 +88,9 @@ ImageIcon::~ImageIcon() */ void ImageIcon::init() { - if (!INKSCAPE) - inkscape_application_init("",false); + // \FIXME Why? + if (!Inkscape::Application::exists()) + Inkscape::Application::create("", false); document = NULL; viewerGtkmm = NULL; //set_size_request(150,150); diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index a28b0f834..9aec7d135 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -135,13 +135,12 @@ void InsertOrderIcon::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window, #endif } -bool -InsertOrderIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool InsertOrderIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index 7b1a8dbfb..dc89d233f 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -21,7 +21,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "layer-manager.h" @@ -601,7 +601,7 @@ void LayerSelector::_prepareLabelRenderer( void LayerSelector::_lockLayer(bool lock) { if ( _layer && SP_IS_ITEM(_layer) ) { SP_ITEM(_layer)->setLocked(lock); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_NONE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_NONE, lock? _("Lock layer") : _("Unlock layer")); } } @@ -609,7 +609,7 @@ void LayerSelector::_lockLayer(bool lock) { void LayerSelector::_hideLayer(bool hide) { if ( _layer && SP_IS_ITEM(_layer) ) { SP_ITEM(_layer)->setHidden(hide); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_NONE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_NONE, hide? _("Hide layer") : _("Unhide layer")); } } diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index e4cd76345..00a74c4fe 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -17,7 +17,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "document-undo.h" @@ -39,26 +39,6 @@ namespace Inkscape { namespace UI { namespace Widget { -/*void ObjectCompositeSettings::_on_desktop_activate( - InkscapeApplication *application, - SPDesktop *desktop, - ObjectCompositeSettings *w -) { - if (w->_subject) { - w->_subject->setDesktop(desktop); - } -} - -void ObjectCompositeSettings::_on_desktop_deactivate( - InkscapeApplication *application, - SPDesktop *desktop, - ObjectCompositeSettings *w -) { - if (w->_subject) { - w->_subject->setDesktop(NULL); - } -}*/ - ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char const *history_prefix, int flags) : _verb_code(verb_code), _blur_tag(Glib::ustring(history_prefix) + ":blur"), @@ -102,7 +82,6 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co ObjectCompositeSettings::~ObjectCompositeSettings() { setSubject(NULL); - g_signal_handler_disconnect(G_OBJECT(INKSCAPE), _desktop_activated); } void ObjectCompositeSettings::setSubject(StyleSubject *subject) { @@ -125,14 +104,14 @@ ObjectCompositeSettings::_blendBlurValueChanged() if (!desktop) { return; } - SPDocument *document = sp_desktop_document (desktop); + SPDocument *document = desktop->getDocument(); if (_blocked) return; _blocked = true; // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 - //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + //sp_canvas_force_full_redraw_after_interruptions(desktop->getCanvas(), 0); Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); double radius; @@ -180,7 +159,7 @@ ObjectCompositeSettings::_blendBlurValueChanged() _("Change blur")); // resume interruptibility - //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); + //sp_canvas_end_forced_full_redraws(desktop->getCanvas()); _blocked = false; } @@ -204,7 +183,7 @@ ObjectCompositeSettings::_opacityValueChanged() // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 // UPDATE: crash fixed in GTK+ 2.10.7 (bug 374378), remove this as soon as it's reasonably common // (though this only fixes the crash, not the multiple change events) - //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + //sp_canvas_force_full_redraw_after_interruptions(desktop->getCanvas(), 0); SPCSSAttr *css = sp_repr_css_attr_new (); @@ -216,11 +195,11 @@ ObjectCompositeSettings::_opacityValueChanged() sp_repr_css_attr_unref (css); - DocumentUndo::maybeDone(sp_desktop_document (desktop), _opacity_tag.c_str(), _verb_code, + DocumentUndo::maybeDone(desktop->getDocument(), _opacity_tag.c_str(), _verb_code, _("Change opacity")); // resume interruptibility - //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); + //sp_canvas_end_forced_full_redraws(desktop->getCanvas()); _blocked = false; } @@ -240,8 +219,8 @@ ObjectCompositeSettings::_subjectChanged() { return; _blocked = true; - SPStyle *query = sp_style_new (sp_desktop_document(desktop)); - int result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + SPStyle query(desktop->getDocument()); + int result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_MASTEROPACITY); switch (result) { case QUERY_STYLE_NOTHING: @@ -252,19 +231,19 @@ ObjectCompositeSettings::_subjectChanged() { case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently case QUERY_STYLE_MULTIPLE_SAME: _opacity_vbox.set_sensitive(true); - _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); + _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query.opacity.value)); break; } //query now for current filter mode and average blurring of selection - const int blend_result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_BLEND); + const int blend_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLEND); switch(blend_result) { case QUERY_STYLE_NOTHING: _fe_cb.set_sensitive(false); break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_SAME: - _fe_cb.set_blend_mode(query->filter_blend_mode.value); + _fe_cb.set_blend_mode(query.filter_blend_mode.value); _fe_cb.set_sensitive(true); break; case QUERY_STYLE_MULTIPLE_DIFFERENT: @@ -274,7 +253,7 @@ ObjectCompositeSettings::_subjectChanged() { } if(blend_result == QUERY_STYLE_SINGLE || blend_result == QUERY_STYLE_MULTIPLE_SAME) { - int blur_result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_BLUR); + int blur_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLUR); switch (blur_result) { case QUERY_STYLE_NOTHING: //no blurring _fe_cb.set_blur_sensitive(false); @@ -287,7 +266,7 @@ ObjectCompositeSettings::_subjectChanged() { double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? _fe_cb.set_blur_sensitive(true); //update blur widget value - float radius = query->filter_gaussianBlur_deviation.value; + float radius = query.filter_gaussianBlur_deviation.value; float percent = radius * 400 / perimeter; // so that for a square, 100% == half side _fe_cb.set_blur_value(percent); } @@ -295,8 +274,6 @@ ObjectCompositeSettings::_subjectChanged() { } } - sp_style_unref(query); - _blocked = false; } diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h index e375bf24a..5a723a2fd 100644 --- a/src/ui/widget/object-composite-settings.h +++ b/src/ui/widget/object-composite-settings.h @@ -66,8 +66,8 @@ private: gulong _desktop_activated; sigc::connection _subject_changed; - static void _on_desktop_activate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); - static void _on_desktop_deactivate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_activate(SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_deactivate(SPDesktop *desktop, ObjectCompositeSettings *w); void _subjectChanged(); void _blendBlurValueChanged(); void _opacityValueChanged(); diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index 89b0b8f7e..8c3b44bf5 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -32,7 +32,7 @@ #include <2geom/transforms.h> -#include "desktop-handles.h" + #include "document.h" #include "desktop.h" #include "helper/action.h" @@ -309,12 +309,12 @@ PageSizer::PageSizer(Registry & _wr) // Setting default custom unit to document unit SPDesktop *dt = SP_ACTIVE_DESKTOP; - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); _wr.setUpdating (true); - if (nv->units) { - _dimensionUnits.setUnit(nv->units->abbr); - } else if (nv->doc_units) { - _dimensionUnits.setUnit(nv->doc_units->abbr); + if (nv->page_size_units) { + _dimensionUnits.setUnit(nv->page_size_units->abbr); + } else if (nv->display_units) { + _dimensionUnits.setUnit(nv->display_units->abbr); } _wr.setUpdating (false); @@ -459,7 +459,7 @@ PageSizer::init () * \param changeList whether to modify the paper size list */ void -PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList) +PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList, bool changeSize) { static bool _called = false; if (_called) { @@ -477,14 +477,15 @@ PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool _unit = w.unit->abbr; if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) { - SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP); + SPDocument *doc = SP_ACTIVE_DESKTOP->getDocument(); Inkscape::Util::Quantity const old_height = doc->getHeight(); - doc->setWidth (w); - doc->setHeight (h); + doc->setWidthAndHeight (w, h, changeSize); // The origin for the user is in the lower left corner; this point should remain stationary when // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this - Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px")))); - doc->getRoot()->translateChildItems(vert_offset); + if (changeSize) { + Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px")))); + doc->getRoot()->translateChildItems(vert_offset); + } DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size")); } @@ -606,7 +607,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing() SPNamedView *nv; Inkscape::XML::Node *nv_repr; - if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP)) + if ((doc = SP_ACTIVE_DESKTOP->getDocument()) && (nv = sp_document_namedview(doc, 0)) && (nv_repr = nv->getRepr())) { _lockMarginUpdate = true; @@ -717,7 +718,8 @@ PageSizer::on_units_changed() if (_widgetRegistry->isUpdating()) return; _unit = _dimensionUnits.getUnit()->abbr; setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()), - Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit())); + Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()), + true, false); } } // namespace Widget diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h index f4bcae4b6..bed117e5a 100644 --- a/src/ui/widget/page-sizer.h +++ b/src/ui/widget/page-sizer.h @@ -161,7 +161,7 @@ public: * Set the page size to the given dimensions. If 'changeList' is * true, then reset the paper size list to the closest match */ - void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true); + void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true, bool changeSize=true); /** * Updates the scalar widgets for the fit margins. (Just changes the value diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp index 0abd81b16..0cff25d88 100644 --- a/src/ui/widget/panel.cpp +++ b/src/ui/widget/panel.cpp @@ -33,7 +33,8 @@ #include "panel.h" #include "icon-size.h" #include "preferences.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "inkscape.h" #include "widgets/eek-preview.h" #include "ui/previewfillable.h" @@ -293,7 +294,7 @@ void Panel::_init() signalResponse().connect(sigc::mem_fun(*this, &Panel::_handleResponse)); - signalActivateDesktop().connect(sigc::hide<0>(sigc::mem_fun(*this, &Panel::setDesktop))); + signalActivateDesktop().connect(sigc::mem_fun(*this, &Panel::setDesktop)); show_all_children(); @@ -643,13 +644,13 @@ Panel::signalDocumentReplaced() return _signal_document_replaced; } -sigc::signal<void, InkscapeApplication *, SPDesktop *> & +sigc::signal<void, SPDesktop *> & Panel::signalActivateDesktop() { return _signal_activate_desktop; } -sigc::signal<void, InkscapeApplication *, SPDesktop *> & +sigc::signal<void, SPDesktop *> & Panel::signalDeactiveDesktop() { return _signal_deactive_desktop; @@ -667,7 +668,7 @@ void Panel::_handleResponse(int response_id) Inkscape::Selection *Panel::_getSelection() { - return sp_desktop_selection(_desktop); + return _desktop->getSelection(); } } // namespace Widget diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h index 177314797..5680cac30 100644 --- a/src/ui/widget/panel.h +++ b/src/ui/widget/panel.h @@ -48,6 +48,7 @@ namespace Gtk { struct InkscapeApplication; namespace Inkscape { + class Selection; namespace UI { @@ -116,8 +117,8 @@ public: void setResponseSensitive(int response_id, bool setting); virtual sigc::signal<void, SPDesktop *, SPDocument *> &signalDocumentReplaced(); - virtual sigc::signal<void, InkscapeApplication *, SPDesktop *> &signalActivateDesktop(); - virtual sigc::signal<void, InkscapeApplication *, SPDesktop *> &signalDeactiveDesktop(); + virtual sigc::signal<void, SPDesktop *> &signalActivateDesktop(); + virtual sigc::signal<void, SPDesktop *> &signalDeactiveDesktop(); protected: /** @@ -147,8 +148,8 @@ protected: sigc::signal<void, int> _signal_response; sigc::signal<void> _signal_present; sigc::signal<void, SPDesktop *, SPDocument *> _signal_document_replaced; - sigc::signal<void, InkscapeApplication *, SPDesktop *> _signal_activate_desktop; - sigc::signal<void, InkscapeApplication *, SPDesktop *> _signal_deactive_desktop; + sigc::signal<void, SPDesktop *> _signal_activate_desktop; + sigc::signal<void, SPDesktop *> _signal_deactive_desktop; private: void _init(); diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 7f3e6cd47..98028ed78 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -34,7 +34,7 @@ #include "desktop.h" #include "enums.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "message-stack.h" #include "style.h" #include "selection.h" diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 44d8dcbf3..298377af3 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -36,6 +36,11 @@ // for interruptability bug: #include "display/sp-canvas.h" +#include "desktop.h" + + +#include "sp-root.h" + namespace Inkscape { namespace UI { namespace Widget { @@ -108,7 +113,7 @@ RegisteredToggleButton::~RegisteredToggleButton() _toggled_connection.disconnect(); } -RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) +RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& /*label*/, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) : RegisteredWidget<Gtk::ToggleButton>() , _active_str(active_str) , _inactive_str(inactive_str) @@ -203,7 +208,7 @@ RegisteredScalarUnit::~RegisteredScalarUnit() _value_changed_connection.disconnect(); } -RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in) +RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in, RSU_UserUnits user_units) : RegisteredWidget<ScalarUnit>(label, tip, UNIT_TYPE_LINEAR, "", "", rum.getUnitMenu()), _um(0) { @@ -215,6 +220,7 @@ RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Gl setUnit (rum.getUnitMenu()->getUnitAbbr()); setDigits (2); _um = rum.getUnitMenu(); + _user_units = user_units; _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed)); } @@ -233,12 +239,31 @@ RegisteredScalarUnit::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - os << getValue(""); - if (_um) - os << _um->getUnitAbbr(); + if (_user_units != RSU_none) { + // Output length in 'user units', taking into account scale in 'x' or 'y'. + double scale = 1.0; + if (doc) { + SPRoot *root = doc->getRoot(); + if (root->viewBox_set) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + scale = (root->viewBox.width() / root->width.computed + root->viewBox.height() / root->height.computed)/2.0; + } else if (_user_units == RSU_x) { + scale = root->viewBox.width() / root->width.computed; + } else { + scale = root->viewBox.height() / root->height.computed; + } + } + } + os << getValue("px") * scale; + } else { + // Output using unit identifiers. + os << getValue(""); + if (_um) + os << _um->getUnitAbbr(); + } write_to_xml(os.str().c_str()); - _wr->setUpdating (false); } @@ -397,8 +422,8 @@ RegisteredColorPicker::on_changed (guint32 rgba) SPDesktop *dt = SP_ACTIVE_DESKTOP; if (!dt) return; - local_repr = sp_desktop_namedview(dt)->getRepr(); - local_doc = sp_desktop_document(dt); + local_repr = dt->getNamedView()->getRepr(); + local_doc = dt->getDocument(); } gchar c[32]; diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 1f505a3cd..9d2489712 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -27,7 +27,7 @@ #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" #include "sp-namedview.h" #include <gtkmm/checkbutton.h> @@ -99,8 +99,8 @@ protected: if (!local_repr) { // no repr specified, use active desktop's namedview's repr SPDesktop* dt = SP_ACTIVE_DESKTOP; - local_repr = reinterpret_cast<SPObject *>(sp_desktop_namedview(dt))->getRepr(); - local_doc = sp_desktop_document(dt); + local_repr = reinterpret_cast<SPObject *>(dt->getNamedView())->getRepr(); + local_doc = dt->getDocument(); } bool saved = DocumentUndo::getUndoSensitive(local_doc); @@ -206,6 +206,14 @@ protected: void on_changed(); }; +// Allow RegisteredScalarUnit to output lengths in 'user units' (which may have direction dependent +// scale factors). +enum RSU_UserUnits { + RSU_none, + RSU_x, + RSU_y +}; + class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> { public: ~RegisteredScalarUnit(); @@ -215,12 +223,14 @@ public: const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in = NULL, - SPDocument *doc_in = NULL ); + SPDocument *doc_in = NULL, + RSU_UserUnits _user_units = RSU_none ); protected: sigc::connection _value_changed_connection; UnitMenu *_um; void on_value_changed(); + RSU_UserUnits _user_units; }; class RegisteredScalar : public RegisteredWidget<Scalar> { diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index d22c59aa4..1fc67dcef 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -20,7 +20,7 @@ #include "ui/widget/color-preview.h" #include "selection.h" -#include "desktop-handles.h" + #include "style.h" #include "desktop-style.h" #include "sp-namedview.h" @@ -480,7 +480,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) _desktop = desktop; g_object_set_data (G_OBJECT(_opacity_sb.gobj()), "dtw", _desktop->canvas); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection_changed_connection = new sigc::connection (selection->connectChanged( sigc::bind ( @@ -498,7 +498,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) this ) )); - _sw_unit = sp_desktop_namedview(desktop)->doc_units; + _sw_unit = desktop->getNamedView()->display_units; // Set the doc default unit active in the units list gint length = g_slist_length(_unit_mis); @@ -541,8 +541,7 @@ void SelectedStyle::dragDataReceived( GtkWidget */*widget*/, sp_repr_css_set_property( css, (tracker->item == SS_FILL) ? "fill":"stroke", c ); sp_desktop_set_style( tracker->parent->_desktop, css ); sp_repr_css_attr_unref( css ); - DocumentUndo::done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE, - _("Drop color")); + DocumentUndo::done( tracker->parent->_desktop->getDocument(), SP_VERB_NONE, _("Drop color")); } } break; @@ -554,7 +553,7 @@ void SelectedStyle::on_fill_remove() { sp_repr_css_set_property (css, "fill", "none"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Remove fill")); } @@ -563,7 +562,7 @@ void SelectedStyle::on_stroke_remove() { sp_repr_css_set_property (css, "stroke", "none"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Remove stroke")); } @@ -572,7 +571,7 @@ void SelectedStyle::on_fill_unset() { sp_repr_css_unset_property (css, "fill"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Unset fill")); } @@ -588,7 +587,7 @@ void SelectedStyle::on_stroke_unset() { sp_repr_css_unset_property (css, "stroke-dasharray"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Unset stroke")); } @@ -597,7 +596,7 @@ void SelectedStyle::on_fill_opaque() { sp_repr_css_set_property (css, "fill-opacity", "1"); sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Make fill opaque")); } @@ -606,7 +605,7 @@ void SelectedStyle::on_stroke_opaque() { sp_repr_css_set_property (css, "stroke-opacity", "1"); sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Make fill opaque")); } @@ -618,7 +617,7 @@ void SelectedStyle::on_fill_lastused() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to fill")); } @@ -630,7 +629,7 @@ void SelectedStyle::on_stroke_lastused() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to stroke")); } @@ -641,7 +640,7 @@ void SelectedStyle::on_fill_lastselected() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last selected color to fill")); } @@ -652,7 +651,7 @@ void SelectedStyle::on_stroke_lastselected() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last selected color to stroke")); } @@ -678,7 +677,7 @@ void SelectedStyle::on_fill_invert() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Invert fill")); } @@ -702,7 +701,7 @@ void SelectedStyle::on_stroke_invert() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Invert stroke")); } @@ -714,7 +713,7 @@ void SelectedStyle::on_fill_white() { sp_repr_css_set_property (css, "fill-opacity", "1"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("White fill")); } @@ -726,7 +725,7 @@ void SelectedStyle::on_stroke_white() { sp_repr_css_set_property (css, "stroke-opacity", "1"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("White stroke")); } @@ -738,7 +737,7 @@ void SelectedStyle::on_fill_black() { sp_repr_css_set_property (css, "fill-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Black fill")); } @@ -750,7 +749,7 @@ void SelectedStyle::on_stroke_black() { sp_repr_css_set_property (css, "stroke-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Black stroke")); } @@ -793,7 +792,7 @@ void SelectedStyle::on_fill_paste() { sp_repr_css_set_property (css, "fill", text.c_str()); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Paste fill")); } } @@ -811,7 +810,7 @@ void SelectedStyle::on_stroke_paste() { sp_repr_css_set_property (css, "stroke", text.c_str()); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Paste stroke")); } } @@ -865,7 +864,7 @@ void SelectedStyle::on_fillstroke_swap() { sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Swap fill and stroke")); } @@ -940,7 +939,7 @@ SelectedStyle::on_opacity_click(GdkEventButton *event) sp_repr_css_set_property (css, "opacity", opacity); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); return true; } @@ -967,7 +966,7 @@ void SelectedStyle::on_popup_preset(int i) { // FIXME: update dash patterns! sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_SWATCHES, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_SWATCHES, _("Change stroke width")); } @@ -978,7 +977,7 @@ SelectedStyle::update() return; // create temporary style - SPStyle *query = sp_style_new (sp_desktop_document(_desktop)); + SPStyle query(_desktop->getDocument()); for (int i = SS_FILL; i <= SS_STROKE; i++) { Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place; @@ -996,7 +995,7 @@ SelectedStyle::update() _popup_copy[i].set_sensitive(false); // query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style (_desktop, query, + int result = sp_desktop_query_style (_desktop, &query, (i == SS_FILL)? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); switch (result) { case QUERY_STYLE_NOTHING: @@ -1021,12 +1020,12 @@ SelectedStyle::update() } SPIPaint *paint; if (i == SS_FILL) { - paint = &(query->fill); + paint = &(query.fill); } else { - paint = &(query->stroke); + paint = &(query.stroke); } if (paint->set && paint->isPaintserver()) { - SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query); + SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (&query) : SP_STYLE_STROKE_SERVER (&query); if ( server ) { Inkscape::XML::Node *srepr = server->getRepr(); _paintserver_id[i] += "url(#"; @@ -1063,7 +1062,7 @@ SelectedStyle::update() } } else if (paint->set && paint->isColor()) { guint32 color = paint->value.color.toRGBA32( - SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value)); + SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query.fill_opacity.value : query.stroke_opacity.value)); _lastselected[i] = _thisselected[i]; _thisselected[i] = color; // include opacity ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color); @@ -1106,7 +1105,7 @@ SelectedStyle::update() clearTooltip(_opacity_place); clearTooltip(_opacity_sb); - int result = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + int result = sp_desktop_query_style (_desktop, &query, QUERY_STYLE_PROPERTY_MASTEROPACITY); switch (result) { case QUERY_STYLE_NOTHING: @@ -1123,16 +1122,16 @@ SelectedStyle::update() _opacity_blocked = true; _opacity_sb.set_sensitive(true); #if WITH_GTKMM_3_0 - _opacity_adjustment->set_value(SP_SCALE24_TO_FLOAT(query->opacity.value) * 100); + _opacity_adjustment->set_value(SP_SCALE24_TO_FLOAT(query.opacity.value) * 100); #else - _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value) * 100); + _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query.opacity.value) * 100); #endif _opacity_blocked = false; break; } // Now query stroke_width - int result_sw = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_sw = sp_desktop_query_style (_desktop, &query, QUERY_STYLE_PROPERTY_STROKEWIDTH); switch (result_sw) { case QUERY_STYLE_NOTHING: _stroke_width.set_markup(""); @@ -1144,9 +1143,9 @@ SelectedStyle::update() { double w; if (_sw_unit) { - w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", _sw_unit); + w = Inkscape::Util::Quantity::convert(query.stroke_width.computed, "px", _sw_unit); } else { - w = query->stroke_width.computed; + w = query.stroke_width.computed; } current_stroke_width = w; @@ -1169,8 +1168,6 @@ SelectedStyle::update() default: break; } - - sp_style_unref(query); } void SelectedStyle::opacity_0(void) {_opacity_sb.set_value(0);} @@ -1241,13 +1238,13 @@ void SelectedStyle::on_opacity_changed () // me. As a result, scrolling the spinbutton once results in runaway change until it hits 1.0 // or 0.0. (And no, this is not a race with ::update, I checked that.) // Sigh. So we disable interruptibility while we're setting the new value. - sp_desktop_canvas(_desktop)->forceFullRedrawAfterInterruptions(0); + _desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::maybeDone(sp_desktop_document(_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::maybeDone(_desktop->getDocument(), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); // resume interruptibility - sp_desktop_canvas(_desktop)->endForcedFullRedraws(); + _desktop->getCanvas()->endForcedFullRedraws(); spinbutton_defocus(GTK_WIDGET(_opacity_sb.gobj())); _opacity_blocked = false; } @@ -1385,25 +1382,25 @@ RotateableSwatch::do_motion(double by, guint modifier) { diff = color_adjust(hsla, by, cc, modifier); if (modifier == 3) { // alpha - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust alpha"))); double ch = hsla[3]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>alpha</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 2) { // saturation - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation"))); double ch = hsla[1]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 1) { // lightness - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness"))); double ch = hsla[2]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else { // hue - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue"))); double ch = hsla[0]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff); @@ -1440,18 +1437,18 @@ RotateableSwatch::do_release(double by, guint modifier) { } if (modifier == 3) { // alpha - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust alpha")); } else if (modifier == 2) { // saturation - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation")); } else if (modifier == 1) { // lightness - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust lightness")); } else { // hue - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust hue")); } @@ -1523,7 +1520,7 @@ RotateableStrokeWidth::do_motion(double by, guint modifier) { if (modifier == 3) { // Alt, do nothing } else { double diff = value_adjust(startvalue, by, modifier, false); - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>stroke width</b>: was %.3g, now <b>%.3g</b> (diff %.3g)"), startvalue, startvalue + diff, diff); } @@ -1537,7 +1534,7 @@ RotateableStrokeWidth::do_release(double by, guint modifier) { } else { value_adjust(startvalue, by, modifier, true); startvalue_set = false; - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); } diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp index d9bf7e2aa..a48370d9b 100644 --- a/src/ui/widget/style-subject.cpp +++ b/src/ui/widget/style-subject.cpp @@ -11,7 +11,7 @@ #include "sp-object.h" #include "xml/sp-css-attr.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "selection.h" #include "style.h" @@ -49,7 +49,7 @@ StyleSubject::Selection::~Selection() { Inkscape::Selection *StyleSubject::Selection::_getSelection() const { SPDesktop *desktop = getDesktop(); if (desktop) { - return sp_desktop_selection(desktop); + return desktop->getSelection(); } else { return NULL; } @@ -88,7 +88,7 @@ void StyleSubject::Selection::_afterDesktopSwitch(SPDesktop *desktop) { _sel_modified.disconnect(); if (desktop) { _subsel_changed = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged))); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection) { _sel_changed = selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged))); _sel_modified = selection->connectModified(sigc::hide(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged)))); diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 157fd2ad9..fa8543c46 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -260,13 +260,12 @@ void StyleSwatch::setStyle(SPCSSAttr *css) Glib::ustring css_string; sp_repr_css_write_string (_css, css_string); - SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); + + SPStyle style(SP_ACTIVE_DOCUMENT); if (!css_string.empty()) { - sp_style_merge_from_style_string (temp_spstyle, css_string.c_str()); + style.mergeString(css_string.c_str()); } - - setStyle (temp_spstyle); - sp_style_unref (temp_spstyle); + setStyle (&style); } void StyleSwatch::setStyle(SPStyle *query) diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index aac7451f4..ff525c679 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -28,7 +28,8 @@ #include "inkscape.h" #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "sp-namedview.h" #include "registry.h" @@ -195,10 +196,10 @@ void ToleranceSlider::update (double val) _wr->setUpdating (true); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); + Inkscape::XML::Node *repr = dt->getNamedView()->getRepr(); repr->setAttribute(_key.c_str(), os.str().c_str()); DocumentUndo::setUndoSensitive(doc, saved); diff --git a/src/util/units.cpp b/src/util/units.cpp index eb4a313e0..2c72ec3ae 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -16,11 +16,14 @@ #include <cmath> #include <cerrno> #include <iomanip> +#include <iostream> #include <glib.h> #include <glibmm/regex.h> #include <glibmm/fileutils.h> #include <glibmm/markup.h> +#include <2geom/coord.h> + #include "util/units.h" #include "path-prefix.h" #include "streq.h" @@ -44,6 +47,7 @@ enum UnitCode { UNIT_CODE_CM = MAKE_UNIT_CODE('c','m'), UNIT_CODE_IN = MAKE_UNIT_CODE('i','n'), UNIT_CODE_FT = MAKE_UNIT_CODE('f','t'), + UNIT_CODE_MT = MAKE_UNIT_CODE('m',' '), UNIT_CODE_EM = MAKE_UNIT_CODE('e','m'), UNIT_CODE_EX = MAKE_UNIT_CODE('e','x'), UNIT_CODE_PERCENT = MAKE_UNIT_CODE('%',0) @@ -71,6 +75,7 @@ unsigned const svg_length_lookup[] = { UNIT_CODE_CM, UNIT_CODE_IN, UNIT_CODE_FT, + UNIT_CODE_MT, UNIT_CODE_EM, UNIT_CODE_EX, UNIT_CODE_PERCENT @@ -206,7 +211,6 @@ bool Unit::compatibleWith(Unit const *u) const } bool Unit::compatibleWith(Glib::ustring const &u) const { - static UnitTable unit_table; return compatibleWith(unit_table.getUnit(u)); } @@ -280,6 +284,28 @@ Unit const *UnitTable::getUnit(SVGLength::Unit u) const return &_empty_unit; } +Unit const *UnitTable::findUnit(double factor, UnitType type) const +{ + const double eps = factor * 0.01; // allow for 1% deviation + + UnitCodeMap::const_iterator cit = _unit_map.begin(); + while (cit != _unit_map.end()) { + if (cit->second->type == type) { + if (Geom::are_near(cit->second->factor, factor, eps)) { + // unit found! + break; + } + } + ++cit; + } + + if (cit != _unit_map.end()) { + return cit->second; + } else { + return getUnit(_primary_unit[type]); + } +} + Quantity UnitTable::parseQuantity(Glib::ustring const &q) const { Glib::MatchInfo match_info; diff --git a/src/util/units.h b/src/util/units.h index efe1dbec7..13777fd1b 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -141,6 +141,9 @@ public: /** Retrieve a given unit based on its string identifier */ Unit const *getUnit(Glib::ustring const &name) const; Unit const *getUnit(char const *name) const; + + /** Try to find a unit based on its conversion factor to the primary */ + Unit const *findUnit(double factor, UnitType type) const; /** Retrieve a given unit based on its SVGLength unit */ Unit const *getUnit(SVGLength::Unit u) const; diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 13dd03ee3..b62aacbc5 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -16,7 +16,7 @@ #include <glibmm/i18n.h> #include "vanishing-point.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/sp-canvas-item.h" #include "display/sp-ctrlline.h" @@ -94,7 +94,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g Geom::Point p = ppointer; // FIXME: take from prefs - double snap_dist = SNAP_DIST / inkscape_active_desktop()->current_zoom(); + double snap_dist = SNAP_DIST / SP_ACTIVE_DESKTOP->current_zoom(); /* * We use dragging_started to indicate if we have already checked for the need to split Draggers up. @@ -110,7 +110,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g for (std::set<VanishingPoint*, less_ptr>::iterator vp = sel_vps.begin(); vp != sel_vps.end(); ++vp) { // for each VP that has selected boxes: Persp3D *old_persp = (*vp)->get_perspective(); - sel_boxes = (*vp)->selectedBoxes(sp_desktop_selection(inkscape_active_desktop())); + sel_boxes = (*vp)->selectedBoxes(SP_ACTIVE_DESKTOP->getSelection()); // we create a new perspective ... Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp->perspective_impl); @@ -129,7 +129,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g } // FIXME: Do we need to create a new dragger as well? dragger->updateZOrders (); - DocumentUndo::done(sp_desktop_document (inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Split vanishing points")); return; } @@ -174,7 +174,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g // deleted according to changes in the svg representation, not based on any user input // as is currently the case. - DocumentUndo::done(sp_desktop_document (inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Merge vanishing points")); return; @@ -182,7 +182,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g } // We didn't snap to another dragger, so we'll try a regular snap - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); @@ -277,7 +277,7 @@ VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) if (vp.is_finite()) { // create the knot - this->knot = new SPKnot(inkscape_active_desktop(), NULL); + this->knot = new SPKnot(SP_ACTIVE_DESKTOP, NULL); this->knot->setMode(SP_KNOT_MODE_XOR); this->knot->setFill(VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL); this->knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff); @@ -394,7 +394,7 @@ VPDragger::VPsOfSelectedBoxes() { std::set<VanishingPoint*, less_ptr> sel_vps; VanishingPoint *vp; // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference. - Inkscape::Selection *sel = sp_desktop_selection(inkscape_active_desktop()); + Inkscape::Selection *sel = SP_ACTIVE_DESKTOP->getSelection(); for (GSList const* i = sel->itemList(); i != NULL; i = i->next) { SPItem *item = static_cast<SPItem *>(i->data); SPBox3D *box = dynamic_cast<SPBox3D *>(item); @@ -488,7 +488,7 @@ VPDragger::printVPs() { VPDrag::VPDrag (SPDocument *document) { this->document = document; - this->selection = sp_desktop_selection(inkscape_active_desktop()); + this->selection = SP_ACTIVE_DESKTOP->getSelection(); this->draggers = NULL; this->lines = NULL; @@ -635,7 +635,7 @@ VPDrag::updateBoxHandles () return; } - Inkscape::UI::Tools::ToolBase *ec = inkscape_active_event_context(); + Inkscape::UI::Tools::ToolBase *ec = INKSCAPE.active_event_context(); g_assert (ec != NULL); if (ec->shape_editor != NULL) { ec->shape_editor->update_knotholder(); @@ -708,7 +708,7 @@ void VPDrag::drawLinesForFace(const SPBox3D *box, Proj::Axis axis) //, guint cor // draw perspective lines for infinite VPs boost::optional<Geom::Point> pt1, pt2, pt3, pt4; Persp3D *persp = box3d_get_perspective(box); - SPDesktop *desktop = inkscape_active_desktop (); // FIXME: Store the desktop in VPDrag + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: Store the desktop in VPDrag Box3D::PerspectiveLine pl (corner1, axis, persp); pt1 = pl.intersection_with_viewbox(desktop); @@ -782,7 +782,7 @@ VPDrag::swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1) void VPDrag::addLine(Geom::Point const &p1, Geom::Point const &p2, Inkscape::CtrlLineType type) { - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(inkscape_active_desktop()), p1, p2, type); + SPCtrlLine *line = ControlManager::getManager().createControlLine(SP_ACTIVE_DESKTOP->getControls(), p1, p2, type); sp_canvas_item_show(line); this->lines = g_slist_append(this->lines, line); } diff --git a/src/verbs.cpp b/src/verbs.cpp index b4743751e..5febeeb7c 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -41,7 +41,7 @@ #include <gtkmm/stock.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/curve.h" #include "document.h" #include "ui/tools/freehand-base.h" @@ -52,7 +52,7 @@ #include "helper/action.h" #include "helper/action-context.h" #include "help.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "ui/interface.h" #include "layer-fns.h" #include "layer-manager.h" @@ -906,10 +906,10 @@ void FileVerb::perform(SPAction *action, void *data) // sp_file_export_to_ocal(*parent); // break; case SP_VERB_FILE_NEXT_DESKTOP: - inkscape_switch_desktops_next(); + INKSCAPE.switch_desktops_next(); break; case SP_VERB_FILE_PREV_DESKTOP: - inkscape_switch_desktops_prev(); + INKSCAPE.switch_desktops_prev(); break; case SP_VERB_FILE_CLOSE_VIEW: sp_ui_close_view(NULL); @@ -948,10 +948,10 @@ void EditVerb::perform(SPAction *action, void *data) switch (reinterpret_cast<std::size_t>(data)) { case SP_VERB_EDIT_UNDO: - sp_undo(dt, sp_desktop_document(dt)); + sp_undo(dt, dt->getDocument()); break; case SP_VERB_EDIT_REDO: - sp_redo(dt, sp_desktop_document(dt)); + sp_redo(dt, dt->getDocument()); break; case SP_VERB_EDIT_CUT: sp_selection_cut(dt); @@ -1203,11 +1203,11 @@ void SelectionVerb::perform(SPAction *action, void *data) SelectionHelper::reverse(dt); break; case SP_VERB_SELECTION_TRACE: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("Trace"); break; case SP_VERB_SELECTION_PIXEL_ART: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("PixelArt"); break; case SP_VERB_SELECTION_CREATE_BITMAP: @@ -1221,7 +1221,7 @@ void SelectionVerb::perform(SPAction *action, void *data) sp_selected_path_break_apart(dt); break; case SP_VERB_SELECTION_ARRANGE: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("TileDialog"); //FIXME: denis: What's this string (to be changed) break; default: @@ -1256,7 +1256,7 @@ void LayerVerb::perform(SPAction *action, void *data) SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { dt->setCurrentLayer(next); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_NEXT, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_NEXT, _("Switch to next layer")); dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Switched to next layer.")); } else { @@ -1268,7 +1268,7 @@ void LayerVerb::perform(SPAction *action, void *data) SPObject *prev=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (prev) { dt->setCurrentLayer(prev); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_PREV, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_PREV, _("Switch to previous layer")); dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Switched to previous layer.")); } else { @@ -1338,7 +1338,7 @@ void LayerVerb::perform(SPAction *action, void *data) description = _("Lower layer"); break; }; - DocumentUndo::done(sp_desktop_document(dt), verb, description); + DocumentUndo::done(dt->getDocument(), verb, description); if (message) { dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message); g_free((void *) message); @@ -1384,7 +1384,7 @@ void LayerVerb::perform(SPAction *action, void *data) dt->setCurrentLayer(new_layer); } #endif - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_DUPLICATE, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_DUPLICATE, _("Duplicate layer")); // TRANSLATORS: this means "The layer has been duplicated." @@ -1396,7 +1396,7 @@ void LayerVerb::perform(SPAction *action, void *data) } case SP_VERB_LAYER_DELETE: { if ( dt->currentLayer() != dt->currentRoot() ) { - sp_desktop_selection(dt)->clear(); + dt->getSelection()->clear(); SPObject *old_layer=dt->currentLayer(); sp_object_ref(old_layer, NULL); @@ -1420,7 +1420,7 @@ void LayerVerb::perform(SPAction *action, void *data) dt->setCurrentLayer(survivor); } - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_DELETE, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_DELETE, _("Delete layer")); // TRANSLATORS: this means "The layer has been deleted." @@ -1435,23 +1435,23 @@ void LayerVerb::perform(SPAction *action, void *data) dt->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No current layer.")); } else { dt->toggleLayerSolo( dt->currentLayer() ); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_SOLO, _("Toggle layer solo")); } break; } case SP_VERB_LAYER_SHOW_ALL: { dt->toggleHideAllLayers( false ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:showall", SP_VERB_LAYER_SHOW_ALL, _("Show all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:showall", SP_VERB_LAYER_SHOW_ALL, _("Show all layers")); break; } case SP_VERB_LAYER_HIDE_ALL: { dt->toggleHideAllLayers( true ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:hideall", SP_VERB_LAYER_HIDE_ALL, _("Hide all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:hideall", SP_VERB_LAYER_HIDE_ALL, _("Hide all layers")); break; } case SP_VERB_LAYER_LOCK_ALL: { dt->toggleLockAllLayers( true ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:lockall", SP_VERB_LAYER_LOCK_ALL, _("Lock all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:lockall", SP_VERB_LAYER_LOCK_ALL, _("Lock all layers")); break; } case SP_VERB_LAYER_LOCK_OTHERS: { @@ -1459,13 +1459,13 @@ void LayerVerb::perform(SPAction *action, void *data) dt->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No current layer.")); } else { dt->toggleLockOtherLayers( dt->currentLayer() ); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); } break; } case SP_VERB_LAYER_UNLOCK_ALL: { dt->toggleLockAllLayers( false ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:unlockall", SP_VERB_LAYER_UNLOCK_ALL, _("Unlock all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:unlockall", SP_VERB_LAYER_UNLOCK_ALL, _("Unlock all layers")); break; } case SP_VERB_LAYER_TOGGLE_LOCK: @@ -1548,12 +1548,12 @@ void ObjectVerb::perform( SPAction *action, void *data) break; case SP_VERB_OBJECT_FLIP_HORIZONTAL: sp_selection_scale_relative(sel, center, Geom::Scale(-1.0, 1.0)); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_OBJECT_FLIP_HORIZONTAL, + DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_HORIZONTAL, _("Flip horizontally")); break; case SP_VERB_OBJECT_FLIP_VERTICAL: sp_selection_scale_relative(sel, center, Geom::Scale(1.0, -1.0)); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_OBJECT_FLIP_VERTICAL, + DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_VERTICAL, _("Flip vertically")); break; case SP_VERB_OBJECT_SET_MASK: @@ -1592,10 +1592,6 @@ void TagVerb::perform( SPAction *action, void *data) if (!dt) return; - //Inkscape::UI::Tools::ToolBase *ec = dt->event_context; - - Inkscape::Selection *sel = sp_desktop_selection(dt); - Inkscape::XML::Document * doc; Inkscape::XML::Node * repr; gchar *id; @@ -1835,7 +1831,7 @@ void TextVerb::perform(SPAction *action, void */*data*/) g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); (void)doc; Inkscape::XML::Node *repr = dt->namedview->getRepr(); (void)repr; @@ -1850,7 +1846,7 @@ void ZoomVerb::perform(SPAction *action, void *data) SPDesktop *dt = sp_action_get_desktop(action); Inkscape::UI::Tools::ToolBase *ec = dt->event_context; - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); Inkscape::XML::Node *repr = dt->namedview->getRepr(); @@ -1860,7 +1856,7 @@ void ZoomVerb::perform(SPAction *action, void *data) double zcorr = 1.0; Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit"); - if (dt->namedview->doc_units && dt->namedview->doc_units->abbr == abbr) + if (dt->namedview->display_units && (dt->namedview->display_units->abbr == abbr)) zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); Geom::Rect const d = dt->get_display_area(); @@ -2006,7 +2002,7 @@ void ZoomVerb::perform(SPAction *action, void *data) dt->toggleColorProfAdjust(); break; case SP_VERB_VIEW_ICON_PREVIEW: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("IconPreviewPanel"); break; @@ -2025,7 +2021,7 @@ void DialogVerb::perform(SPAction *action, void *data) { if (reinterpret_cast<std::size_t>(data) != SP_VERB_DIALOG_TOGGLE) { // unhide all when opening a new dialog - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); } g_return_if_fail(ensure_desktop_valid(action)); @@ -2088,7 +2084,7 @@ void DialogVerb::perform(SPAction *action, void *data) dt->_dlg_mgr->showDialog("UndoHistory"); break; case SP_VERB_DIALOG_TOGGLE: - inkscape_dialogs_toggle(); + INKSCAPE.dialogs_toggle(); break; case SP_VERB_DIALOG_CLONETILER: //clonetiler_dialog(); @@ -2166,7 +2162,7 @@ void HelpVerb::perform(SPAction *action, void *data) */ case SP_VERB_HELP_MEMORY: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("Memory"); break; default: @@ -2330,7 +2326,7 @@ void FitCanvasVerb::perform(SPAction *action, void *data) { g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); if (!doc) return; switch (reinterpret_cast<std::size_t>(data)) { @@ -2396,7 +2392,7 @@ void LockAndHideVerb::perform(SPAction *action, void *data) { g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); if (!doc) return; switch (reinterpret_cast<std::size_t>(data)) { @@ -2432,7 +2428,7 @@ Verb *Verb::_base_verbs[] = { new Verb(SP_VERB_NONE, "None", NC_("Verb", "None"), N_("Does nothing"), NULL, NULL), // File - new FileVerb(SP_VERB_FILE_NEW, "FileNew", N_("Default"), N_("Create new document from the default template"), + new FileVerb(SP_VERB_FILE_NEW, "FileNew", N_("_New"), N_("Create new document from the default template"), INKSCAPE_ICON("document-new")), new FileVerb(SP_VERB_FILE_OPEN, "FileOpen", N_("_Open..."), N_("Open an existing document"), INKSCAPE_ICON("document-open")), @@ -2462,7 +2458,7 @@ Verb *Verb::_base_verbs[] = { new FileVerb(SP_VERB_FILE_CLOSE_VIEW, "FileClose", N_("_Close"), N_("Close this document window"), INKSCAPE_ICON("window-close")), new FileVerb(SP_VERB_FILE_QUIT, "FileQuit", N_("_Quit"), N_("Quit Inkscape"), INKSCAPE_ICON("application-exit")), - new FileVerb(SP_VERB_FILE_TEMPLATES, "FileTemplates", N_("_Templates..."), + new FileVerb(SP_VERB_FILE_TEMPLATES, "FileTemplates", N_("New from _Template..."), N_("Create new project from template"), INKSCAPE_ICON("dialog-templates")), // Edit diff --git a/src/viewbox.cpp b/src/viewbox.cpp index 662b05686..d04d25eb0 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -164,20 +164,24 @@ void SPViewBox::set_preserveAspectRatio(const gchar* value) { void SPViewBox::apply_viewbox(const Geom::Rect& in) { /* Determine actual viewbox in viewport coordinates */ - /* These are floats since SVGLength is a float: See bug 1374614 */ - float x = 0.0; - float y = 0.0; - float width = in.width(); - float height = in.height(); - // std::cout << " width: " << width << " height: " << height << std::endl; - - if (this->aspect_align != SP_ASPECT_NONE) { - /* Things are getting interesting */ - double scalex = in.width() / ((float) this->viewBox.width()); - double scaley = in.height() / ((float) this->viewBox.height()); - double scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley); - width = this->viewBox.width() * scale; - height = this->viewBox.height() * scale; + double x = 0.0; + double y = 0.0; + double scalex = in.width() / this->viewBox.width(); + double scaley = in.height() / this->viewBox.height(); + double scale = 1.0; // uniform scale factor + + if (Geom::are_near(scalex / scaley, 1.0, Geom::EPSILON)) { + // scaling is already uniform, reduce numerical error + scale = (scalex + scaley)/2.0; + scalex = scale; + scaley = scale; + } else if (this->aspect_align != SP_ASPECT_NONE) { + // scaling is not uniform, but force it to be + scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley); + scalex = scale; + scaley = scale; + double width = this->viewBox.width() * scale; + double height = this->viewBox.height() * scale; /* Now place viewbox to requested position */ switch (this->aspect_align) { @@ -218,12 +222,12 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in) { /* Viewbox transform from scale and position */ Geom::Affine q; - q[0] = width / ((float) this->viewBox.width()); + q[0] = scalex; q[1] = 0.0; q[2] = 0.0; - q[3] = height / ((float) this->viewBox.height()); - q[4] = x - q[0] * ((float) this->viewBox.left()); - q[5] = y - q[3] * ((float) this->viewBox.top()); + q[3] = scaley; + q[4] = x - scalex * this->viewBox.left(); + q[5] = y - scaley * this->viewBox.top(); // std::cout << " q\n" << q << std::endl; diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index ca582924b..8a64854be 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "arc-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -81,7 +81,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj)); } @@ -97,7 +97,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -128,7 +128,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) ); if (modmade) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), value_name, SP_VERB_CONTEXT_ARC, + DocumentUndo::maybeDone(desktop->getDocument(), value_name, SP_VERB_CONTEXT_ARC, _("Arc: Change start/end")); } @@ -150,7 +150,7 @@ static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); } @@ -166,7 +166,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) bool modmade = false; if ( ege_select_one_action_get_active(act) != 0 ) { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -179,7 +179,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } } } else { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -194,7 +194,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, _("Arc: Change open/closed")); } @@ -413,8 +413,8 @@ static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBa static sigc::connection changed; if (SP_IS_ARC_CONTEXT(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); - sp_arc_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); + sp_arc_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index 02d102a11..26e914070 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -32,7 +32,7 @@ #include "box3d-toolbar.h" #include "box3d.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "document.h" @@ -195,7 +195,7 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); } - inkscape_active_document()->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); + SP_ACTIVE_DOCUMENT->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); @@ -208,7 +208,7 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); // quit if run by the attr_changed or selection changed listener if (g_object_get_data( dataKludge, "freeze" )) { @@ -218,7 +218,7 @@ static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, P // in turn, prevent listener from responding g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList(); + std::list<Persp3D *> sel_persps = desktop->getSelection()->perspList(); if (sel_persps.empty()) { // this can happen when the document is created; we silently ignore it return; @@ -255,7 +255,7 @@ static void box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge) static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction * /*box3d_angle*/, Proj::Axis axis ) { // TODO: Take all selected perspectives into account - std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList(); + std::list<Persp3D *> sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); if (sel_persps.empty()) { // this can happen when the document is created; we silently ignore it return; @@ -287,7 +287,7 @@ void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); EgeAdjustmentAction* eact = 0; - SPDocument *document = sp_desktop_document (desktop); + SPDocument *document = desktop->getDocument(); Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); EgeAdjustmentAction* box3d_angle_x = 0; @@ -420,8 +420,8 @@ static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::Tool { static sigc::connection changed; if (SP_IS_BOX3D_CONTEXT(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); - box3d_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); + box3d_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 6ce926dc1..c906f7de4 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -32,7 +32,7 @@ #include "connector-toolbar.h" #include "conn-avoid-ref.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -76,8 +76,8 @@ static void sp_connector_path_set_ignore(void) static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection * selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -126,8 +126,8 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection * selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -176,7 +176,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -233,11 +233,11 @@ static void sp_connector_graph_layout(void) int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList()); + graphlayout(SP_ACTIVE_DESKTOP->getSelection()->itemList()); prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); } static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) @@ -402,7 +402,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); } // Avoid overlaps toggle button diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp index 479895022..9d591d33d 100644 --- a/src/widgets/dash-selector.cpp +++ b/src/widgets/dash-selector.cpp @@ -118,18 +118,18 @@ void SPDashSelector::init_dashes() { int pos = 0; if (!dash_prefs.empty()) { - SPStyle *style = sp_style_new (NULL); + SPStyle style; dashes = g_new (double *, dash_prefs.size() + 2); // +1 for custom slot, +1 for terminator slot for (std::vector<Glib::ustring>::iterator i = dash_prefs.begin(); i != dash_prefs.end(); ++i) { - sp_style_read_from_prefs(style, *i); + style.readFromPrefs( *i ); - if (!style->stroke_dasharray.values.empty()) { - dashes[pos] = g_new (double, style->stroke_dasharray.values.size() + 1); + if (!style.stroke_dasharray.values.empty()) { + dashes[pos] = g_new (double, style.stroke_dasharray.values.size() + 1); double *d = dashes[pos]; unsigned i = 0; - for (; i < style->stroke_dasharray.values.size(); i++) { - d[i] = style->stroke_dasharray.values[i]; + for (; i < style.stroke_dasharray.values.size(); i++) { + d[i] = style.stroke_dasharray.values[i]; } d[i] = -1; } else { diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 9c8dac7dc..fd3756220 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -32,7 +32,7 @@ #include "conn-avoid-ref.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-widget.h" #include "display/sp-canvas.h" #include "display/canvas-arena.h" @@ -45,7 +45,7 @@ #include "helper/action-context.h" #include "util/units.h" #include "ui/widget/unit-tracker.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "ui/interface.h" #include "macros.h" #include "preferences.h" @@ -795,7 +795,7 @@ static void sp_desktop_widget_dispose(GObject *object) dtw->layer_selector->setDesktop(NULL); dtw->layer_selector->unreference(); - inkscape_remove_desktop (dtw->desktop); // clears selection too + INKSCAPE.remove_desktop (dtw->desktop); // clears selection too dtw->modified_connection.disconnect(); dtw->desktop->destroy(); Inkscape::GC::release (dtw->desktop); @@ -1091,7 +1091,7 @@ SPDesktopWidget::shutdown() { g_assert(desktop != NULL); - if (inkscape_is_sole_desktop_for_document(*desktop)) { + if (INKSCAPE.sole_desktop_for_document(*desktop)) { SPDocument *doc = desktop->doc(); if (doc->isModifiedSinceSave()) { GtkWidget *dialog; @@ -1665,14 +1665,14 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) { SPDesktopWidget *dtw = static_cast<SPDesktopWidget*>(g_object_new(SP_TYPE_DESKTOP_WIDGET, NULL)); - dtw->dt2r = 1. / namedview->doc_units->factor; + dtw->dt2r = 1. / namedview->display_units->factor; dtw->ruler_origin = Geom::Point(0,0); //namedview->gridorigin; Why was the grid origin used here? dtw->desktop = new SPDesktop(); dtw->stub = new SPDesktopWidget::WidgetStub (dtw); dtw->desktop->init (namedview, dtw->canvas, dtw->stub); - inkscape_add_desktop (dtw->desktop); + INKSCAPE.add_desktop (dtw->desktop); // Add the shape geometry to libavoid for autorouting connectors. // This needs desktop set for its spacing preferences. @@ -1737,11 +1737,11 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) SPNamedView *nv=SP_NAMEDVIEW(obj); if (flags & SP_OBJECT_MODIFIED_FLAG) { - this->dt2r = 1. / nv->doc_units->factor; + this->dt2r = 1. / nv->display_units->factor; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? - sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDefaultUnit()); - sp_ruler_set_unit(SP_RULER (this->hruler), nv->getDefaultUnit()); + sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDisplayUnit()); + sp_ruler_set_unit(SP_RULER (this->hruler), nv->getDisplayUnit()); /* This loops through all the grandchildren of aux toolbox, * and for each that it finds, it performs an sp_search_by_data_recursive(), @@ -1771,14 +1771,14 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) if (tracker == NULL) // it's null when inkscape is first opened continue; - tracker->setActiveUnit( nv->doc_units ); + tracker->setActiveUnit( nv->display_units ); } // grandchildren } // if child is a container } // children } // if aux_toolbox is a container - gtk_widget_set_tooltip_text(this->hruler_box, gettext(nv->doc_units->name_plural.c_str())); - gtk_widget_set_tooltip_text(this->vruler_box, gettext(nv->doc_units->name_plural.c_str())); + gtk_widget_set_tooltip_text(this->hruler_box, gettext(nv->display_units->name_plural.c_str())); + gtk_widget_set_tooltip_text(this->vruler_box, gettext(nv->display_units->name_plural.c_str())); sp_desktop_widget_update_rulers(this); ToolboxFactory::updateSnapToolbox(this->desktop, 0, this->snap_toolbox); @@ -1818,7 +1818,7 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*) } } - inkscape_activate_desktop (desktop); + INKSCAPE.activate_desktop (desktop); return false; } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index f547cbd8b..1f79b50f2 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -32,7 +32,7 @@ #include "eraser-toolbar.h" #include "calligraphy-toolbar.h" // TODO: needed for update_presets_list -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -61,7 +61,7 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); bool eraserMode = ege_select_one_action_get_active( act ) != 0; - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/eraser/mode", eraserMode ); } diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index d1d318abe..d60a92b8b 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -35,7 +35,7 @@ #include "desktop.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/sp-canvas.h" #include "document-private.h" @@ -252,13 +252,13 @@ void FillNStroke::performUpdate() update = true; // create temporary style - SPStyle *query = sp_style_new(desktop->doc()); + SPStyle query(desktop->doc()); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); + int result = sp_desktop_query_style(desktop, &query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; - SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity; + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; + SPIScale24 &targOpacity = (kind == FILL) ? query.fill_opacity : query.stroke_opacity; switch (result) { case QUERY_STYLE_NOTHING: @@ -272,11 +272,11 @@ void FillNStroke::performUpdate() case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector case QUERY_STYLE_MULTIPLE_SAME: { - SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind); + SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(query, kind); psel->setMode(pselmode); if (kind == FILL) { - psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO? + psel->setFillrule(query.fill_rule.computed == ART_WIND_RULE_NONZERO? SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD); } @@ -284,7 +284,7 @@ void FillNStroke::performUpdate() psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value)); } else if (targPaint.set && targPaint.isPaintserver()) { - SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer(); + SPPaintServer *server = (kind == FILL) ? query.getFillPaintServer() : query.getStrokePaintServer(); if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) { SPGradient *vector = SP_GRADIENT(server)->getVector(); @@ -318,8 +318,6 @@ void FillNStroke::performUpdate() } } - sp_style_unref(query); - update = false; } @@ -480,8 +478,8 @@ void FillNStroke::updateFromPaint() } update = true; - SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); @@ -516,18 +514,18 @@ void FillNStroke::updateFromPaint() { if (kind == FILL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events - sp_desktop_canvas(desktop)->forceFullRedrawAfterInterruptions(0); + desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); } psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" ); - DocumentUndo::maybeDone(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::maybeDone(desktop->getDocument(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, (kind == FILL) ? _("Set fill color") : _("Set stroke color")); if (kind == FILL) { // resume interruptibility - sp_desktop_canvas(desktop)->endForcedFullRedraws(); + desktop->getCanvas()->endForcedFullRedraws(); } // on release, toggle undo_label so that the next drag will not be lumped with this one @@ -562,10 +560,10 @@ void FillNStroke::updateFromPaint() if (!vector) { /* No vector in paint selector should mean that we just changed mode */ - SPStyle *query = sp_style_new(desktop->doc()); - int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL); + SPStyle query(desktop->doc()); + int result = objects_query_fillstroke(const_cast<GSList *>(items), &query, kind == FILL); if (result == QUERY_STYLE_MULTIPLE_SAME) { - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; SPColor common; if (!targPaint.isColor()) { common = sp_desktop_get_color(desktop, kind == FILL); @@ -577,7 +575,6 @@ void FillNStroke::updateFromPaint() vector->setSwatch(); } } - sp_style_unref(query); for (GSList const *i = items; i != NULL; i = i->next) { //FIXME: see above diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index b6378b251..ea009c048 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -18,7 +18,7 @@ #include "ui/widget/color-preview.h" #include <glibmm/i18n.h> -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "document.h" @@ -128,7 +128,7 @@ gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection return sensitive; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); GtkTreeIter iter; GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box)); @@ -356,7 +356,7 @@ static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args if (selection) { ToolBase *ev = desktop->getEventContext(); GrDrag *drag = NULL; @@ -560,7 +560,7 @@ static void gr_add_stop(GtkWidget * /*button*/, GtkWidget *vb) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) { return; } @@ -582,7 +582,7 @@ static void gr_remove_stop(GtkWidget * /*button*/, GtkWidget *vb) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args if (!selection) { return; } @@ -918,12 +918,12 @@ static void gr_gradient_combo_changed(EgeSelectOneAction *act, gpointer data) gr = sp_gradient_ensure_vector_normalized(gr); SPDesktop *desktop = static_cast<SPDesktop *>(data); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); ToolBase *ev = desktop->getEventContext(); gr_apply_gradient(selection, ev? ev->get_drag() : NULL, gr); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Assign gradient to object")); } @@ -936,7 +936,7 @@ static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) } SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPGradient *gradient = 0; gr_get_dt_selected_gradient(selection, gradient); @@ -945,7 +945,7 @@ static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) gradient->setSpread(spread); gradient->updateRepr(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Set gradient repeat")); } } @@ -1246,8 +1246,8 @@ static void gradient_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::T static sigc::connection connDefsModified; if (SP_IS_GRADIENT_CONTEXT(ec)) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); // connect to selection modified and changed signals connChanged = selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), holder)); diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 6607c90d2..d2c46ffec 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -1012,13 +1012,28 @@ GtkWidget * sp_gradient_vector_editor_new(SPGradient *gradient, SPStop *stop) sp_transientize(dlg); wd.win = dlg; wd.stop = 0; - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_transientize_callback), &wd); - g_signal_connect(G_OBJECT(dlg), "event", G_CALLBACK(sp_dialog_event_handler), dlg); - g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(sp_gradient_vector_dialog_destroy), dlg); - g_signal_connect(G_OBJECT(dlg), "delete_event", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); - g_signal_connect(G_OBJECT(INKSCAPE), "shut_down", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); - g_signal_connect( G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(sp_dialog_hide), dlg ); - g_signal_connect( G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(sp_dialog_unhide), dlg ); + + GObject *obj = G_OBJECT(dlg); + sigc::connection *conn = NULL; + + conn = new sigc::connection(INKSCAPE.signal_activate_desktop.connect(sigc::bind(sigc::ptr_fun(&sp_transientize_callback), &wd))); + g_object_set_data(obj, "desktop-activate-connection", conn); + + g_signal_connect(obj, "event", G_CALLBACK(sp_dialog_event_handler), dlg); + g_signal_connect(obj, "destroy", G_CALLBACK(sp_gradient_vector_dialog_destroy), dlg); + g_signal_connect(obj, "delete_event", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); + + conn = new sigc::connection(INKSCAPE.signal_shut_down.connect( + sigc::hide_return( + sigc::bind(sigc::ptr_fun(&sp_gradient_vector_dialog_delete), (GtkWidget *) NULL, (GdkEvent *) NULL, (GtkWidget *) NULL) + ))); + g_object_set_data(obj, "shutdown-connection", conn); + + conn = new sigc::connection(INKSCAPE.signal_dialogs_hide.connect(sigc::bind(sigc::ptr_fun(>k_widget_hide), dlg))); + g_object_set_data(obj, "dialog-hide-connection", conn); + + conn = new sigc::connection(INKSCAPE.signal_dialogs_unhide.connect(sigc::bind(sigc::ptr_fun(>k_widget_show), dlg))); + g_object_set_data(obj, "dialog-unhide-connection", conn); gtk_container_set_border_width(GTK_CONTAINER(dlg), PAD); @@ -1141,7 +1156,29 @@ static void sp_gradient_vector_dialog_destroy(GtkWidget * /*object*/, gpointer / static void sp_gradient_vector_dialog_destroy(GtkObject * /*object*/, gpointer /*data*/) #endif { - sp_signal_disconnect_by_data(INKSCAPE, dlg); + GObject *obj = G_OBJECT(dlg); + assert(obj != NULL); + + sigc::connection *conn = static_cast<sigc::connection *>(g_object_get_data(obj, "desktop-activate-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "shutdown-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "dialog-hide-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "dialog-unhide-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + wd.win = dlg = NULL; wd.stop = 0; } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index a6e53d638..afc4fcfb0 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -1261,7 +1261,7 @@ std::list<gchar*> &IconImpl::icons_svg_paths() static bool initialized = false; if (!initialized) { // Fall back from user prefs dir into system locations. - gchar *userdir = profile_path("icons"); + gchar *userdir = Inkscape::Application::profile_path("icons"); sources.push_back(g_build_filename(userdir,"icons.svg", NULL)); sources.push_back(g_build_filename(INKSCAPE_PIXMAPDIR, "icons.svg", NULL)); g_free(userdir); @@ -1572,7 +1572,7 @@ void IconImpl::addPreRender( GtkIconSize lsize, gchar const *name ) } gboolean IconImpl::prerenderTask(gpointer /*data*/) { - if ( inkscapeIsCrashing() ) { + if ( Inkscape::Application::isCrashing() ) { // stop } else if (!pendingRenders.empty()) { bool workDone = false; @@ -1584,7 +1584,7 @@ gboolean IconImpl::prerenderTask(gpointer /*data*/) { } while (!pendingRenders.empty() && !workDone); } - if (!inkscapeIsCrashing() && !pendingRenders.empty()) { + if (!Inkscape::Application::isCrashing() && !pendingRenders.empty()) { return TRUE; } else { callbackHooked = false; diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index a85f3ae78..387bf6dee 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -30,7 +30,7 @@ #include "live_effects/lpe-line_segment.h" #include "lpe-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-select-one-action.h" @@ -91,7 +91,7 @@ static void sp_lpetool_mode_changed(EgeSelectOneAction *act, GObject *tbl) SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type; } - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt( "/tools/lpetool/mode", mode ); } @@ -280,7 +280,7 @@ static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBas void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->setActiveUnit(sp_desktop_namedview(desktop)->doc_units); + tracker->setActiveUnit(desktop->getNamedView()->display_units); g_object_set_data(holder, "tracker", tracker); Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); @@ -413,9 +413,9 @@ static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::To if (SP_IS_LPETOOL_CONTEXT(ec)) { // Watch selection - c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); - sp_lpetool_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); + sp_lpetool_toolbox_sel_changed(desktop->getSelection(), holder); } else { if (c_selection_modified) c_selection_modified.disconnect(); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 1a4678332..5a4785b1f 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "measure-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -55,7 +55,7 @@ sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt(Glib::ustring("/tools/measure/fontsize"), gtk_adjustment_get_value(adj)); diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 897d84278..674d0f350 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -38,7 +38,7 @@ #include "document-private.h" #include "document-undo.h" #include "desktop.h" -#include "desktop-handles.h" + #include <glibmm/i18n.h> #include "ui/tools/gradient-tool.h" @@ -74,34 +74,119 @@ static bool blocked = false; //######################## /* + * Get the current selection and dragger status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMeshGradient *&ms_selected, + bool &ms_selected_multi, + SPMeshSmooth &ms_smooth, + bool &ms_smooth_multi ) +{ + + // Read desktop selection + bool first = true; + ms_smooth = SP_MESH_SMOOTH_NONE; + + for (GSList const* i = selection->itemList(); i; i = i->next) { + SPItem *item = SP_ITEM(i->data); + SPStyle *style = item->style; + + if (style && (style->fill.isPaintserver())) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_MESHGRADIENT(server) ) { + + SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); + SPMeshSmooth smooth = gradient->smooth; + bool smooth_set = gradient->smooth_set; + + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } + } + if( smooth != ms_smooth ) { + if (ms_smooth != SP_MESH_SMOOTH_NONE && !first) { + ms_smooth_multi = true; + } else { + ms_smooth = smooth; + } + } + first = false; + } + } + + if (style && (style->stroke.isPaintserver())) { + SPPaintServer *server = item->style->getStrokePaintServer(); + if ( SP_IS_MESHGRADIENT(server) ) { + + SPMeshGradient *gradient = SP_MESHGRADIENT(server); // ->getVector(); + SPMeshSmooth smooth = gradient->smooth; + bool smooth_set = gradient->smooth_set; + + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } + } + if( smooth != ms_smooth ) { + if (ms_smooth != SP_MESH_SMOOTH_NONE && !first) { + ms_smooth_multi = true; + } else { + ms_smooth = smooth; + } + } + first = false; + } + } + } + } + +/* * Core function, setup all the widgets whenever something changes on the desktop */ -static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer /*data*/) +static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data) { - // DOES NOTHING AT MOMENT // std::cout << "ms_tb_selection_changed" << std::endl; - // if (blocked) - // return; - - // GtkWidget *widget = GTK_WIDGET(data); + if (blocked) + return; - // SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); - // if (!desktop) { - // return; - // } + GtkWidget *widget = GTK_WIDGET(data); - // Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args - // if (selection) { - // ToolBase *ev = sp_desktop_event_context(desktop); - // GrDrag *drag = NULL; - // if (ev) { - // drag = ev->get_drag(); - // // Hide/show handles? - // } + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); + if (!desktop) { + return; + } - // } + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args + if (selection) { + // ToolBase *ev = sp_desktop_event_context(desktop); + // GrDrag *drag = NULL; + // if (ev) { + // drag = ev->get_drag(); + // // Hide/show handles? + // } + + SPMeshGradient *ms_selected = 0; + SPMeshSmooth ms_smooth = SP_MESH_SMOOTH_NONE; + bool ms_selected_multi = false; + bool ms_smooth_multi = false; + ms_read_selection( selection, ms_selected, ms_selected_multi, ms_smooth, ms_smooth_multi ); + // std::cout << " smooth: " << ms_smooth << std::endl; + + EgeSelectOneAction* smooth = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_smooth_action"); + gtk_action_set_sensitive( GTK_ACTION(smooth), (ms_selected && !ms_selected_multi) ); + if (ms_selected) { + blocked = TRUE; + ege_select_one_action_set_active( smooth, ms_smooth ); + blocked = FALSE; + } + } } @@ -126,6 +211,33 @@ static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widg ms_tb_selection_changed(NULL, widget); } +void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMeshGradient *&ms_selected) +{ + SPMeshGradient *gradient = 0; + + for (GSList const* i = selection->itemList(); i; i = i->next) { + SPItem *item = SP_ITEM(i->data); // get the items gradient, not the getVector() version + SPStyle *style = item->style; + SPPaintServer *server = 0; + + if (style && (style->fill.isPaintserver())) { + server = item->style->getFillPaintServer(); + } + if (style && (style->stroke.isPaintserver())) { + server = item->style->getStrokePaintServer(); + } + + if ( SP_IS_MESHGRADIENT(server) ) { + gradient = SP_MESHGRADIENT(server); + } + } + + if (gradient) { + ms_selected = gradient; + } +} + + /* * Callback functions for user actions */ @@ -178,6 +290,30 @@ static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) blocked = FALSE; } +static void ms_smooth_changed(EgeSelectOneAction *act, GtkWidget *widget) +{ + // std::cout << "ms_smooth_changed" << std::endl; + if (blocked) { + return; + } + + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); + Inkscape::Selection *selection = desktop->getSelection(); + SPMeshGradient *gradient = 0; + ms_get_dt_selected_gradient(selection, gradient); + + if (gradient) { + SPMeshSmooth smooth = (SPMeshSmooth) ege_select_one_action_get_active(act); + // std::cout << " smooth: " << smooth << std::endl; + gradient->smooth = smooth; + gradient->smooth_set = true; + gradient->updateRepr(); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, + _("Set mesh smoothing")); + } +} + static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); /** @@ -322,6 +458,56 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj g_object_set_data(holder, "desktop", desktop); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder)); + + /* Warning */ + { + GtkAction* act = gtk_action_new( "MeshWarningAction", + _("WARNING: Mesh SVG Syntax Subject to Change, Smoothing Experimental"), NULL, NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Smoothing method */ + { + GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); + + GtkTreeIter iter; + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, C_("Smoothing", "None"), 1, SP_MESH_SMOOTH_NONE, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Default"), 1, SP_MESH_SMOOTH_SMOOTH, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth1"), 1, SP_MESH_SMOOTH_SMOOTH1, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth2"), 1, SP_MESH_SMOOTH_SMOOTH2, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth3"), 1, SP_MESH_SMOOTH_SMOOTH3, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth4"), 1, SP_MESH_SMOOTH_SMOOTH4, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth5"), 1, SP_MESH_SMOOTH_SMOOTH5, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth6"), 1, SP_MESH_SMOOTH_SMOOTH6, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Smooth7"), 1, SP_MESH_SMOOTH_SMOOTH7, -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "MeshSmoothAction", _("None"), + _("If the mesh should be smoothed across patch boundaries."), + NULL, GTK_TREE_MODEL(model) ); + g_object_set( act, "short_label", _("Smoothing:"), NULL ); + ege_select_one_action_set_appearance( act, "compact" ); + gtk_action_set_sensitive( GTK_ACTION(act), FALSE ); + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(ms_smooth_changed), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "mesh_select_smooth_action", act ); + } } static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) @@ -334,8 +520,8 @@ static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_MESH_CONTEXT(ec)) { // connect to selection modified and changed signals - Inkscape::Selection *selection = sp_desktop_selection (desktop); - SPDocument *document = sp_desktop_document (desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder)); c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder)); diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 467325d08..113061519 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -31,7 +31,7 @@ #include "ui/tool/multi-path-manipulator.h" #include <glibmm/i18n.h> #include "node-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -264,7 +264,7 @@ static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::D } Unit const *unit = tracker->getActiveUnit(); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } @@ -330,7 +330,7 @@ static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Unit doc_units = *sp_desktop_namedview(desktop)->doc_units; + Unit doc_units = *desktop->getNamedView()->display_units; tracker->setActiveUnit(&doc_units); g_object_set_data( holder, "tracker", tracker ); @@ -614,7 +614,7 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_action_group_add_action( mainActions, act ); } - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder)); } // end of sp_node_toolbox_prep() @@ -627,11 +627,11 @@ static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (INK_IS_NODE_TOOL(ec)) { // watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); - c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder)); - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); } else { if (c_selection_changed) c_selection_changed.disconnect(); diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index e1ce01eaf..016aa4987 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "rect-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -90,7 +90,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); @@ -105,11 +105,11 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_RECT(items->data)) { if (gtk_adjustment_get_value(adj) != 0) { - (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, sp_desktop_namedview(desktop)->doc_units)); + (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, desktop->getNamedView()->svg_units)); } else { SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); } @@ -120,7 +120,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * sp_rtb_sensitivize( tbl ); if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_RECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Change rectangle")); } @@ -181,7 +181,7 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); Unit const *unit = tracker->getActiveUnit(); - Unit const *doc_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units; + Unit const *svg_unit = SP_ACTIVE_DESKTOP->getNamedView()->svg_units; g_return_if_fail(unit != NULL); gpointer item = g_object_get_data( tbl, "item" ); @@ -190,28 +190,28 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); gdouble rx = SP_RECT(item)->getVisibleRx(); - gtk_adjustment_set_value(adj, Quantity::convert(rx, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(rx, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); gdouble ry = SP_RECT(item)->getVisibleRy(); - gtk_adjustment_set_value(adj, Quantity::convert(ry, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(ry, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); gdouble width = SP_RECT(item)->getVisibleWidth(); - gtk_adjustment_set_value(adj, Quantity::convert(width, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(width, svg_unit, unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); gdouble height = SP_RECT(item)->getVisibleHeight(); - gtk_adjustment_set_value(adj, Quantity::convert(height, doc_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(height, svg_unit, unit)); } } @@ -307,7 +307,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); //tracker->addUnit( SP_UNIT_PERCENT, 0 ); // fixme: add % meaning per cent of the width/height - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); + tracker->setActiveUnit( desktop->getNamedView()->display_units ); g_object_set_data( holder, "tracker", tracker ); /* W */ @@ -404,11 +404,20 @@ static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB { static sigc::connection changed; - if (SP_IS_RECT_CONTEXT(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + // use of dynamic_cast<> seems wrong here -- we just need to check the current tool + + if (dynamic_cast<Inkscape::UI::Tools::RectTool *>(ec)) { + Inkscape::Selection *sel = desktop->getSelection(); + + changed = sel->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + + // Synthesize an emission to trigger the update + sp_rect_toolbox_selection_changed(sel, holder); } else { - if (changed) + if (changed) { changed.disconnect(); + purge_repr_listener(NULL, holder); + } } } diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 08a46354e..e49c4c00a 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -21,7 +21,7 @@ #include "ui/widget/spinbutton.h" #include <glibmm/i18n.h> #include "select-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/sp-canvas.h" #include "document-undo.h" @@ -106,7 +106,7 @@ static void sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); - if ((sp_desktop_selection(desktop) == selection) // only respond to changes in our desktop + if ((desktop->getSelection() == selection) // only respond to changes in our desktop && (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG ))) @@ -119,7 +119,7 @@ static void sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); - if (sp_desktop_selection(desktop) == selection) { // only respond to changes in our desktop + if (desktop->getSelection() == selection) { // only respond to changes in our desktop gboolean setActive = (selection && !selection->isEmpty()); std::vector<GtkAction*> *contextActions = reinterpret_cast<std::vector<GtkAction*> *>(g_object_get_data(G_OBJECT(spw), "contextActions")); if ( contextActions ) { @@ -153,8 +153,8 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); document->ensureUpToDate (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -241,7 +241,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) if (actionkey != NULL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed - sp_desktop_canvas(desktop)->forceFullRedrawAfterInterruptions(0); + desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); bool transform_stroke = prefs->getBool("/options/transform/stroke", true); bool preserve = prefs->getBool("/options/preservetransform/value", false); @@ -262,7 +262,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) _("Transform by toolbar")); // resume interruptibility - sp_desktop_canvas(desktop)->endForcedFullRedraws(); + desktop->getCanvas()->endForcedFullRedraws(); } g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); @@ -470,10 +470,10 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb contextActions->push_back( act ); // Create the parent widget for x y w h tracker. - GtkWidget *spw = sp_widget_new_global(INKSCAPE); + GtkWidget *spw = sp_widget_new_global(); // Remember the desktop's canvas widget, to be used for defocusing. - g_object_set_data(G_OBJECT(spw), "dtw", sp_desktop_canvas(desktop)); + g_object_set_data(G_OBJECT(spw), "dtw", desktop->getCanvas()); // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. #if GTK_CHECK_VERSION(3,0,0) @@ -488,7 +488,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // Create the units menu. UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); tracker->addUnit(unit_table.getUnit("%")); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); + tracker->setActiveUnit( desktop->getNamedView()->display_units ); g_object_set_data( G_OBJECT(spw), "tracker", tracker ); g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); @@ -546,7 +546,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_signal_connect(G_OBJECT(spw), "change_selection", G_CALLBACK(sp_selection_layout_widget_change_selection), desktop); // Update now. - sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? sp_desktop_selection(SP_ACTIVE_DESKTOP) : NULL); + sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? SP_ACTIVE_DESKTOP->getSelection() : NULL); for ( std::vector<GtkAction*>::iterator iter = contextActions->begin(); iter != contextActions->end(); ++iter) { diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index fdf5ec500..5ab6b1bb5 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -15,6 +15,7 @@ #include "macros.h" #include "document.h" +#include "inkscape.h" #include "sp-widget.h" #include "helper/sp-marshal.h" @@ -55,15 +56,15 @@ public: #endif static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation); - static void modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw); - static void changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); - static void setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); + static void modifySelectionCB(Selection *selection, guint flags, SPWidget *spw); + static void changeSelectionCB(Selection *selection, SPWidget *spw); + static void setSelectionCB(Selection *selection, SPWidget *spw); - static GtkWidget *constructGlobal(SPWidget *spw, InkscapeApplication *inkscape); + static GtkWidget *constructGlobal(SPWidget *spw); - void modifySelection(Application *inkscape, Selection *selection, guint flags); - void changeSelection(Application *inkscape, Selection *selection); - void setSelection(Application *inkscape, Selection *selection); + void modifySelection(Selection *selection, guint flags); + void changeSelection(Selection *selection); + void setSelection(Selection *selection); private: SPWidget &_target; @@ -132,7 +133,6 @@ sp_widget_class_init(SPWidgetClass *klass) static void sp_widget_init(SPWidget *spw) { - spw->inkscape = NULL; spw->_impl = new SPWidgetImpl(*spw); // ctor invoked after all other init } @@ -151,16 +151,12 @@ void SPWidgetImpl::dispose(GObject *object) { SPWidget *spw = reinterpret_cast<SPWidget *>(object); - if (spw->inkscape) { - // Disconnect signals - - // the checks are necessary because when destroy is caused by the program shutting down, - // the inkscape object may already be (partly?) invalid --bb - if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(spw->inkscape)) { - sp_signal_disconnect_by_data(spw->inkscape, spw); - } - spw->inkscape = NULL; - } + // Disconnect signals + if (Application::exists()) { + spw->selModified.disconnect(); + spw->selChanged.disconnect(); + spw->selSet.disconnect(); + } delete spw->_impl; spw->_impl = 0; @@ -174,11 +170,20 @@ void SPWidgetImpl::show(GtkWidget *widget) { SPWidget *spw = SP_WIDGET(widget); - if (spw->inkscape) { + if (Application::exists()) { // Connect signals - g_signal_connect(spw->inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw); - g_signal_connect(spw->inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw); - g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); + spw->selModified = INKSCAPE.signal_selection_modified.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw) + ); + spw->selChanged = INKSCAPE.signal_selection_changed.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw) + ); + spw->selSet = INKSCAPE.signal_selection_set.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw) + ); } if (GTK_WIDGET_CLASS(sp_widget_parent_class)->show) { @@ -190,9 +195,11 @@ void SPWidgetImpl::hide(GtkWidget *widget) { SPWidget *spw = SP_WIDGET (widget); - if (spw->inkscape) { + if (Application::exists()) { // Disconnect signals - sp_signal_disconnect_by_data(spw->inkscape, spw); + spw->selModified.disconnect(); + spw->selChanged.disconnect(); + spw->selSet.disconnect(); } if (GTK_WIDGET_CLASS(sp_widget_parent_class)->hide) { @@ -264,15 +271,21 @@ void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation) } } -GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *inkscape) +GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw) { - g_return_val_if_fail(!spw->inkscape, NULL); - - spw->inkscape = inkscape; if (gtk_widget_get_visible(GTK_WIDGET(spw))) { - g_signal_connect(inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw); - g_signal_connect(inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw); - g_signal_connect(inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); + spw->selModified = INKSCAPE.signal_selection_modified.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw) + ); + spw->selChanged = INKSCAPE.signal_selection_changed.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw) + ); + spw->selSet = INKSCAPE.signal_selection_set.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw) + ); } g_signal_emit(spw, signals[CONSTRUCT], 0); @@ -280,32 +293,32 @@ GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *ink return GTK_WIDGET(spw); } -void SPWidgetImpl::modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw) +void SPWidgetImpl::modifySelectionCB(Selection *selection, guint flags, SPWidget *spw) { - spw->_impl->modifySelection(inkscape, selection, flags); + spw->_impl->modifySelection(selection, flags); } -void SPWidgetImpl::changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw) +void SPWidgetImpl::changeSelectionCB(Selection *selection, SPWidget *spw) { - spw->_impl->changeSelection(inkscape, selection); + spw->_impl->changeSelection(selection); } -void SPWidgetImpl::setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw) +void SPWidgetImpl::setSelectionCB(Selection *selection, SPWidget *spw) { - spw->_impl->setSelection(inkscape, selection); + spw->_impl->setSelection(selection); } -void SPWidgetImpl::modifySelection(Application * /*inkscape*/, Selection *selection, guint flags) +void SPWidgetImpl::modifySelection(Selection *selection, guint flags) { g_signal_emit(&_target, signals[MODIFY_SELECTION], 0, selection, flags); } -void SPWidgetImpl::changeSelection(Application * /*inkscape*/, Selection *selection) +void SPWidgetImpl::changeSelection(Selection *selection) { g_signal_emit(&_target, signals[CHANGE_SELECTION], 0, selection); } -void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection) +void SPWidgetImpl::setSelection(Selection *selection) { // Emit "set_selection" signal g_signal_emit(&_target, signals[SET_SELECTION], 0, selection); @@ -316,11 +329,11 @@ void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection // Methods -GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape) +GtkWidget *sp_widget_new_global() { SPWidget *spw = reinterpret_cast<SPWidget*>(g_object_new(SP_TYPE_WIDGET, NULL)); - if (!SPWidgetImpl::constructGlobal(spw, inkscape)) { + if (!SPWidgetImpl::constructGlobal(spw)) { g_object_unref(spw); spw = 0; } diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index 6227c3a72..a53062cf4 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -16,6 +16,7 @@ */ #include <gtk/gtk.h> +#include "inkscape.h" #define SP_TYPE_WIDGET (sp_widget_get_type()) #define SP_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_WIDGET, SPWidget)) @@ -23,9 +24,8 @@ #define SP_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_WIDGET)) #define SP_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_WIDGET)) -struct InkscapeApplication; - namespace Inkscape { + class Selection; class SPWidgetImpl; } @@ -33,10 +33,15 @@ class SPWidgetImpl; struct SPWidget { friend class Inkscape::SPWidgetImpl; + static GType getType(); + GtkBin bin; - InkscapeApplication *inkscape; Inkscape::SPWidgetImpl *_impl; +private: + sigc::connection selModified; + sigc::connection selChanged; + sigc::connection selSet; }; struct SPWidgetClass { @@ -53,7 +58,7 @@ struct SPWidgetClass { GType sp_widget_get_type(); /** Generic constructor for global widget. */ -GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape); +GtkWidget *sp_widget_new_global(); #endif // SEEN_SP_WIDGET_H /* diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp index 9243760bd..a1d8475ba 100644 --- a/src/widgets/sp-xmlview-content.cpp +++ b/src/widgets/sp-xmlview-content.cpp @@ -15,7 +15,7 @@ #include "xml/node-event-vector.h" #include "sp-xmlview-content.h" -#include "desktop-handles.h" +#include "desktop.h" #include "document-private.h" #include "document-undo.h" #include "inkscape.h" @@ -147,7 +147,7 @@ sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text) text->repr->setContent(data); g_free (data); text->blocked = FALSE; - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_XML_EDITOR, _("Type text in a text node")); } } diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index e85b024ed..3fb0015c1 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "spiral-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -62,7 +62,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/spiral/" + value_name, gtk_adjustment_get_value(adj)); @@ -79,7 +79,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -96,7 +96,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr g_free(namespaced_name); if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, _("Change spiral")); } @@ -296,7 +296,7 @@ void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 6213263fc..cf12391c1 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "star-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -64,7 +64,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { // do not remember prefs if this call is initiated by an undo change, because undoing object // creation sets bogus values to its attributes before it is deleted Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -82,7 +82,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem*>(items->data); @@ -99,7 +99,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change number of corners")); } @@ -110,7 +110,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { if (!IS_NAN(gtk_adjustment_get_value(adj))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/proportion", @@ -127,7 +127,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -152,7 +152,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change spoke ratio")); } @@ -164,7 +164,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); bool flat = ege_select_one_action_get_active( act ) == 0; - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/shapes/star/isflatsided", flat); } @@ -177,7 +177,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d // in turn, prevent listener from responding g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); bool modmade = false; @@ -197,7 +197,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, flat ? _("Make polygon") : _("Make star")); } @@ -208,7 +208,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/rounded", (gdouble) gtk_adjustment_get_value(adj)); } @@ -223,7 +223,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem*>(items->data); @@ -236,7 +236,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change rounding")); } @@ -247,7 +247,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/randomized", (gdouble) gtk_adjustment_get_value(adj)); @@ -263,7 +263,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -276,7 +276,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change randomization")); } @@ -582,8 +582,8 @@ static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB static sigc::connection changed; if (dynamic_cast<Inkscape::UI::Tools::StarTool const*>(ec) != NULL) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)); - sp_star_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)); + sp_star_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp index 23da54e94..e273faad7 100644 --- a/src/widgets/stroke-marker-selector.cpp +++ b/src/widgets/stroke-marker-selector.cpp @@ -26,7 +26,7 @@ #include "style.h" #include "ui/dialog-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "preferences.h" #include "path-prefix.h" @@ -64,8 +64,8 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) : sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("no-marker") ) ) ); sandbox = ink_markers_preview_doc (); - desktop = inkscape_active_desktop(); - doc = sp_desktop_document(desktop); + desktop = SP_ACTIVE_DESKTOP; + doc = desktop->getDocument(); modified_connection = doc->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&MarkerComboBox::handleDefsModified), this))) ); @@ -92,7 +92,7 @@ void MarkerComboBox::setDesktop(SPDesktop *desktop) } this->desktop = desktop; - doc = sp_desktop_document(desktop); + doc = desktop->getDocument(); if (doc) { modified_connection = doc->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&MarkerComboBox::handleDefsModified), this))) ); @@ -578,25 +578,25 @@ gboolean MarkerComboBox::separator_cb (GtkTreeModel *model, GtkTreeIter *iter, g */ SPDocument *MarkerComboBox::ink_markers_preview_doc () { -gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" +gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" id=\"MarkerSample\">" " <defs id=\"defs\" />" " <g id=\"marker-start\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\"" " d=\"M 12.5,13 L 25,13\" id=\"path1\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect2\"" " width=\"25\" height=\"25\" x=\"0\" y=\"0\" />" " </g>" " <g id=\"marker-mid\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\"" " d=\"M 0,113 L 12.5,113 L 25,113\" id=\"path11\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect22\"" " width=\"25\" height=\"25\" x=\"0\" y=\"100\" />" " </g>" " <g id=\"marker-end\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\"" " d=\"M 0,213 L 12.5,213\" id=\"path111\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect222\"" " width=\"25\" height=\"25\" x=\"0\" y=\"200\" />" diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 02dd5df6e..5ca06a795 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -204,8 +204,8 @@ StrokeStyle::StrokeStyle() : unitSelector->addUnit(*unit_table.getUnit("%")); _old_unit = unitSelector->getUnit(); if (desktop) { - unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); - _old_unit = sp_desktop_namedview(desktop)->doc_units; + unitSelector->setUnit(desktop->getNamedView()->display_units->abbr); + _old_unit = desktop->getNamedView()->display_units; } widthSpin->setUnitMenu(unitSelector); unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB)); @@ -456,7 +456,7 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, spw->update = true; - SPDocument *document = sp_desktop_document(spw->desktop); + SPDocument *document = spw->desktop->getDocument(); if (!document) { return; } @@ -471,10 +471,10 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, // Also update the marker combobox, so the document's markers // show up at the top of the combobox -// sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL); +// sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? desktop->getSelection() : NULL); //spw->updateMarkerHist(which); - Inkscape::Selection *selection = sp_desktop_selection(spw->desktop); + Inkscape::Selection *selection = spw->desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -810,18 +810,18 @@ StrokeStyle::updateLine() update = true; - Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; + Inkscape::Selection *sel = desktop ? desktop->getSelection() : NULL; FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // query into it - int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); - int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); - int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP); - int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN); - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; + int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); + int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKECAP); + int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEJOIN); + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; if (!sel || sel->isEmpty()) { // Nothing selected, grey-out all controls in the stroke-style dialog @@ -839,14 +839,14 @@ StrokeStyle::updateLine() // same width, or only one object; no sense to keep percent, switch to absolute Inkscape::Util::Unit const *tempunit = unitSelector->getUnit(); if (tempunit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { - unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); + unitSelector->setUnit(SP_ACTIVE_DESKTOP->getNamedView()->display_units->abbr); } } Inkscape::Util::Unit const *unit = unitSelector->getUnit(); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", unit); + double avgwidth = Inkscape::Util::Quantity::convert(query.stroke_width.computed, "px", unit); #if WITH_GTKMM_3_0 (*widthAdj)->set_value(avgwidth); #else @@ -879,27 +879,25 @@ StrokeStyle::updateLine() if (result_ml != QUERY_STYLE_NOTHING) #if WITH_GTKMM_3_0 - (*miterLimitAdj)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + (*miterLimitAdj)->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? #else - miterLimitAdj->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + miterLimitAdj->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? #endif if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT && result_join != QUERY_STYLE_NOTHING ) { - setJoinType(query->stroke_linejoin.value); + setJoinType(query.stroke_linejoin.value); } else { setJoinButtons(NULL); } if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT && result_cap != QUERY_STYLE_NOTHING ) { - setCapType (query->stroke_linecap.value); + setCapType (query.stroke_linecap.value); } else { setCapButtons(NULL); } - sp_style_unref(query); - if (!sel || sel->isEmpty()) return; @@ -957,8 +955,8 @@ StrokeStyle::scaleLine() update = true; - SPDocument *document = sp_desktop_document (desktop); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); @@ -1113,8 +1111,7 @@ void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) sp_repr_css_attr_unref(css); css = 0; - DocumentUndo::done(sp_desktop_document(spw->desktop), SP_VERB_DIALOG_FILL_STROKE, - _("Set stroke style")); + DocumentUndo::done(spw->desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Set stroke style")); } } @@ -1200,7 +1197,7 @@ StrokeStyle::updateAllMarkers(GSList const *objects) if (update) { setMarkerColor(marker, combo->get_loc(), SP_ITEM(object)); - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set marker color")); } diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index 15e394097..83048cb76 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -33,7 +33,6 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" #include "desktop-style.h" #include "ui/dialog-events.h" #include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index d62bb8027..3d2e6eef8 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -31,7 +31,7 @@ #include "libnrtype/font-lister.h" #include <glibmm/i18n.h> #include "text-toolbar.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "desktop.h" #include "document-undo.h" @@ -165,7 +165,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); } @@ -220,21 +220,19 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje sp_desktop_set_style (desktop, css, true, true); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:size", SP_VERB_NONE, _("Text: Change font size")); } - sp_style_unref(query); - sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -267,7 +265,7 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj sp_desktop_set_style (desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change font style")); } @@ -292,8 +290,8 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) #endif // Query baseline - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); bool setSuper = false; bool setSub = false; @@ -307,14 +305,14 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) } } else { // Superscript - gboolean superscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + gboolean superscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); // Subscript - gboolean subscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + gboolean subscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); setSuper = !superscriptSet && prop == 0; setSub = !subscriptSet && prop == 1; @@ -345,7 +343,7 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) // Save for undo if(result_baseline != QUERY_STYLE_NOTHING) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:script", SP_VERB_NONE, _("Text: Change superscript or subscript")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -367,7 +365,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) SPDesktop *desktop = SP_ACTIVE_DESKTOP; // move the x of all texts to preserve the same bbox - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_TEXT(SP_ITEM(items->data))) { SPItem *item = SP_ITEM(items->data); @@ -473,10 +471,9 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) } } - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, update default style. if (result_numbers == QUERY_STYLE_NOTHING) @@ -485,12 +482,10 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) prefs->mergeStyle("/tools/text/style", css); } - sp_style_unref(query); - sp_desktop_set_style (desktop, css, true, true); if (result_numbers != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change alignment")); } sp_repr_css_attr_unref (css); @@ -521,7 +516,7 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Until deprecated sodipodi:linespacing purged: - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); bool modmade = false; for (; items != NULL; items = items->next) { @@ -533,20 +528,19 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Save for undo if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); } // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } - sp_style_unref(query); sp_repr_css_attr_unref (css); @@ -573,19 +567,18 @@ static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl sp_desktop_set_style (desktop, css, true, false); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:word-spacing", SP_VERB_NONE, _("Text: Change word-spacing")); } - sp_style_unref(query); sp_repr_css_attr_unref (css); @@ -612,9 +605,9 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb sp_desktop_set_style (desktop, css, true, false); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -623,12 +616,10 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:letter-spacing", SP_VERB_NONE, _("Text: Change letter-spacing")); } - sp_style_unref(query); - sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -663,7 +654,7 @@ static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) if(modmade) { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dx", SP_VERB_NONE, _("Text: Change dx (kern)")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -697,7 +688,7 @@ static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) if(modmade) { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dy", SP_VERB_NONE, _("Text: Change dy")); } @@ -732,7 +723,7 @@ static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) // Save for undo if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:rotate", SP_VERB_NONE, _("Text: Change rotate")); } @@ -765,10 +756,9 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * } } - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, update default style. if (result_numbers == QUERY_STYLE_NOTHING) @@ -780,7 +770,7 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); if(result_numbers != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change orientation")); } sp_repr_css_attr_unref (css); @@ -829,7 +819,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; std::cout << " Selected items:" << std::endl; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); items != NULL; items = items->next) { @@ -860,7 +850,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); if (!subselection) { - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); } fontlister->selection_update(); @@ -873,7 +863,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Only flowed text can be justified, only normal text can be kerned... // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); items != NULL; items = items->next) { // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); @@ -892,11 +882,11 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) * Font specification (Inkscape private attribute) */ - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); /* * If no text in selection (querying returned nothing), read the style from @@ -905,14 +895,13 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ */ if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { // There are no texts in selection, read from preferences. - sp_style_read_from_prefs(query, "/tools/text"); + query.readFromPrefs("/tools/text"); #ifdef DEBUG_TEXT std::cout << " read style from prefs:" << std::endl; - sp_print_font( query ); + sp_print_font( &query ); #endif if (g_object_get_data(tbl, "text_style_from_prefs")) { // Do not reset the toolbar style from prefs if we already did it last time - sp_style_unref(query); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); #ifdef DEBUG_TEXT std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; @@ -937,7 +926,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); //gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; //g_ascii_dtostr (size_text, sizeof (size_text), size); @@ -961,9 +950,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Superscript gboolean superscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); @@ -972,9 +961,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Subscript gboolean subscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); @@ -1001,26 +990,26 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // ege_select_one_action_set_sensitive( textAlignAction, 3, isFlow ); int activeButton = 0; - if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) + if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { activeButton = 3; } else { - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; } ege_select_one_action_set_active( textAlignAction, activeButton ); // Line height (spacing) double height; - if (query->line_height.normal) { + if (query.line_height.normal) { height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; } else { - if (query->line_height.unit == SP_CSS_UNIT_PERCENT) { - height = query->line_height.value; + if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { + height = query.line_height.value; } else { - height = query->line_height.computed; + height = query.line_height.computed; } } @@ -1032,8 +1021,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Word spacing double wordSpacing; - if (query->word_spacing.normal) wordSpacing = 0.0; - else wordSpacing = query->word_spacing.computed; // Assume no units (change in desktop-style.cpp) + if (query.word_spacing.normal) wordSpacing = 0.0; + else wordSpacing = query.word_spacing.computed; // Assume no units (change in desktop-style.cpp) GtkAction* wordSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextWordSpacingAction" ) ); GtkAdjustment *wordSpacingAdjustment = @@ -1043,8 +1032,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Letter spacing double letterSpacing; - if (query->letter_spacing.normal) letterSpacing = 0.0; - else letterSpacing = query->letter_spacing.computed; // Assume no units (change in desktop-style.cpp) + if (query.letter_spacing.normal) letterSpacing = 0.0; + else letterSpacing = query.letter_spacing.computed; // Assume no units (change in desktop-style.cpp) GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); GtkAdjustment *letterSpacingAdjustment = @@ -1053,7 +1042,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Orientation - int activeButton2 = (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); + int activeButton2 = (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); EgeSelectOneAction* textOrientationAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextOrientationAction" ) ); @@ -1064,27 +1053,25 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ #ifdef DEBUG_TEXT std::cout << " GUI: fontfamily.value: " - << (query->font_family.value ? query->font_family.value : "No value") + << (query.font_family.value ? query.font_family.value : "No value") << std::endl; - std::cout << " GUI: font_size.computed: " << query->font_size.computed << std::endl; - std::cout << " GUI: font_weight.computed: " << query->font_weight.computed << std::endl; - std::cout << " GUI: font_style.computed: " << query->font_style.computed << std::endl; - std::cout << " GUI: text_anchor.computed: " << query->text_anchor.computed << std::endl; - std::cout << " GUI: text_align.computed: " << query->text_align.computed << std::endl; - std::cout << " GUI: line_height.computed: " << query->line_height.computed - << " line_height.value: " << query->line_height.value - << " line_height.unit: " << query->line_height.unit << std::endl; - std::cout << " GUI: word_spacing.computed: " << query->word_spacing.computed - << " word_spacing.value: " << query->word_spacing.value - << " word_spacing.unit: " << query->word_spacing.unit << std::endl; - std::cout << " GUI: letter_spacing.computed: " << query->letter_spacing.computed - << " letter_spacing.value: " << query->letter_spacing.value - << " letter_spacing.unit: " << query->letter_spacing.unit << std::endl; - std::cout << " GUI: writing_mode.computed: " << query->writing_mode.computed << std::endl; + std::cout << " GUI: font_size.computed: " << query.font_size.computed << std::endl; + std::cout << " GUI: font_weight.computed: " << query.font_weight.computed << std::endl; + std::cout << " GUI: font_style.computed: " << query.font_style.computed << std::endl; + std::cout << " GUI: text_anchor.computed: " << query.text_anchor.computed << std::endl; + std::cout << " GUI: text_align.computed: " << query.text_align.computed << std::endl; + std::cout << " GUI: line_height.computed: " << query.line_height.computed + << " line_height.value: " << query.line_height.value + << " line_height.unit: " << query.line_height.unit << std::endl; + std::cout << " GUI: word_spacing.computed: " << query.word_spacing.computed + << " word_spacing.value: " << query.word_spacing.value + << " word_spacing.unit: " << query.word_spacing.unit << std::endl; + std::cout << " GUI: letter_spacing.computed: " << query.letter_spacing.computed + << " letter_spacing.value: " << query.letter_spacing.value + << " letter_spacing.unit: " << query.letter_spacing.unit << std::endl; + std::cout << " GUI: writing_mode.computed: " << query.writing_mode.computed << std::endl; #endif - sp_style_unref(query); - // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); @@ -1169,7 +1156,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p GSList *selectList = NULL; SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = sp_desktop_document( desktop ); + SPDocument *document = desktop->getDocument(); GSList *allList = get_all_items(NULL, document->getRoot(), desktop, false, false, true, NULL); for (GSList *i = allList; i != NULL; i = i->next) { @@ -1196,7 +1183,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p } // Update selection - Inkscape::Selection *selection = sp_desktop_selection (desktop ); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; selection->setList(selectList); @@ -1214,7 +1201,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje { // Font list Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); GtkListStore* model = store->gobj(); @@ -1623,7 +1610,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje } // Is this necessary to call? Shouldn't hurt. - sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + sp_text_toolbox_selection_changed(desktop->getSelection(), holder); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder)); @@ -1642,8 +1629,8 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_TEXT_CONTEXT(ec)) { // Watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); - c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); + c_selection_modified = desktop->getSelection()->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); } else { if (c_selection_changed) diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 9e55d1cf6..5d52db6f2 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -40,7 +40,6 @@ #include <glibmm/i18n.h> #include "../desktop.h" -#include "../desktop-handles.h" #include "../desktop-style.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -522,6 +521,8 @@ static gchar const * ui_descr = // " <toolitem action='MeshEditFillAction' />" // " <toolitem action='MeshEditStrokeAction' />" // " <toolitem action='MeshShowHandlesAction' />" + " <toolitem action='MeshWarningAction' />" + " <toolitem action='MeshSmoothAction' />" " <separator />" " </toolbar>" @@ -1511,7 +1512,7 @@ static void toggle_snap_callback(GtkToggleAction *act, gpointer data) //data poi g_assert(ptr != NULL); SPDesktop *dt = reinterpret_cast<SPDesktop*>(ptr); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); SPDocument *doc = nv->document; if (dt == NULL || nv == NULL) { @@ -1871,7 +1872,7 @@ void ToolboxFactory::updateSnapToolbox(SPDesktop *desktop, ToolBase * /*eventcon g_assert(desktop != NULL); g_assert(toolbox != NULL); - SPNamedView *nv = sp_desktop_namedview(desktop); + SPNamedView *nv = desktop->getNamedView(); if (nv == NULL) { g_warning("Namedview cannot be retrieved (in updateSnapToolbox)!"); return; diff --git a/src/xml/node.h b/src/xml/node.h index 8bb70acc0..29cfdab46 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -469,6 +469,8 @@ public: * @deprecated Use synthesizeEvents(NodeObserver &) instead */ virtual void synthesizeEvents(NodeEventVector const *vector, void *data)=0; + + virtual void recursivePrintTree(unsigned level)=0; /*@}*/ diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 4965f81c8..3cbedc80b 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -606,6 +606,26 @@ void SimpleNode::synthesizeEvents(NodeObserver &observer) { synthesizeEvents(&OBSERVER_EVENT_VECTOR, &observer); } +void SimpleNode::recursivePrintTree(unsigned level) { + + if (level == 0) { + std::cout << "XML Node Tree" << std::endl; + } + std::cout << "XML: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + char const *id=attribute("id"); + if (id) { + std::cout << id << std::endl; + } else { + std::cout << name() << std::endl; + } + for (SimpleNode *child = _first_child; child != NULL; child = child->_next) { + child->recursivePrintTree( level+1 ); + } +} + Node *SimpleNode::root() { Node *parent=this; while (parent->parent()) { diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index 1fcb9193b..d09392249 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -19,6 +19,7 @@ #define SEEN_INKSCAPE_XML_SIMPLE_NODE_H #include <cassert> +#include <iostream> #include "xml/node.h" #include "xml/attribute-record.h" @@ -120,6 +121,8 @@ public: _subtree_observers.remove(observer); } + void recursivePrintTree(unsigned level = 0); + protected: SimpleNode(int code, Document *document); SimpleNode(SimpleNode const &repr, Document *document); |
