diff options
| author | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-03-26 01:00:24 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-03-26 01:00:24 +0000 |
| commit | a5c919f46c359f26433cb42a82bb99fbb729a467 (patch) | |
| tree | a9d00aafdfa2cb160257d25ebeae78f6a6d6ca30 /src | |
| parent | tiny bugfix for Taper Strokes (diff) | |
| parent | make it easier for people to build with -Werror on Windows (diff) | |
| download | inkscape-a5c919f46c359f26433cb42a82bb99fbb729a467.tar.gz inkscape-a5c919f46c359f26433cb42a82bb99fbb729a467.zip | |
Update to trunk
Massive cleanup of outlining code
(bzr r13090.1.31)
Diffstat (limited to 'src')
34 files changed, 670 insertions, 1184 deletions
diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index 41eaf59b0..f6d4718de 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -274,10 +274,12 @@ public: /** @brief Union with another interval, gracefully handling empty ones. */ void unionWith(GenericOptInterval<C> const &a) { - if (*this) { // check that we are not empty - (*this)->unionWith(*a); - } else if (a) { - *this = *a; + if (a) { + if (*this) { // check that we are not empty + (*this)->unionWith(*a); + } else { + *this = *a; + } } } void intersectWith(GenericOptInterval<C> const &o) { diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 4ec6ae1c8..c09b8e9c8 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -72,8 +72,8 @@ #include <cairo-ft.h> #endif #ifdef CAIRO_HAS_WIN32_FONT -#include <cairo-win32.h> #include <pango/pangowin32.h> +#include <cairo-win32.h> #endif #include <pango/pangofc-fontmap.h> diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 4bb892821..ed25bf767 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -915,17 +915,13 @@ int PrintEmf::vector_rect_alignment(double angle, Geom::Point vtest){ are slightly displaced. */ Geom::Point PrintEmf::get_pathrect_corner(Geom::Path pathRect, double angle, int corner){ - Geom::Point v1 = Geom::Point(1,0) * Geom::Rotate(-angle); // unit horizontal side (sign change because Y increases DOWN) - Geom::Point v2 = Geom::Point(0,1) * Geom::Rotate(-angle); // unit vertical side (sign change because Y increases DOWN) - Geom::Point center, P1; - int LR; // 1 if Left, 0 if Right - int UL; // 1 if Lower, 0 if Upper (as viewed on screen, y coordinates increase downwards) - center = Geom::Point(0,0); - Geom::Path::const_iterator cit = pathRect.begin(); - for(; cit != pathRect.end_open();++cit) { + Geom::Point center(0,0); + for(Geom::Path::const_iterator cit = pathRect.begin(); cit != pathRect.end_open(); ++cit) { center += cit->initialPoint()/4.0; } + int LR; // 1 if Left, 0 if Right + int UL; // 1 if Lower, 0 if Upper (as viewed on screen, y coordinates increase downwards) switch(corner){ case 1: //UR LR = 0; @@ -944,11 +940,15 @@ Geom::Point PrintEmf::get_pathrect_corner(Geom::Path pathRect, double angle, int UL = 0; break; } - cit = pathRect.begin(); - for(int i; cit != pathRect.end_open();++cit,i++) { + + Geom::Point v1 = Geom::Point(1,0) * Geom::Rotate(-angle); // unit horizontal side (sign change because Y increases DOWN) + Geom::Point v2 = Geom::Point(0,1) * Geom::Rotate(-angle); // unit vertical side (sign change because Y increases DOWN) + Geom::Point P1; + for(Geom::Path::const_iterator cit = pathRect.begin(); cit != pathRect.end_open(); ++cit) { P1 = cit->initialPoint(); - if((LR == (dot(P1 - center,v1)> 0 ? 0 : 1)) && - (UL == (dot(P1 - center,v2)> 0 ? 1 : 0)))break; + + if ( ( LR == (dot(P1 - center,v1) > 0 ? 0 : 1) ) + && ( UL == (dot(P1 - center,v2) > 0 ? 1 : 0) ) ) break; } return(P1); } diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 30e120d26..b398486e6 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -76,10 +76,6 @@ extern "C" { // Operator table //------------------------------------------------------------------------ -#ifdef WIN32 // this works around a bug in the VC7 compiler -# pragma optimize("",off) -#endif - PdfOperator PdfParser::opTab[] = { {"\"", 3, {tchkNum, tchkNum, tchkString}, &PdfParser::opMoveSetShowText}, @@ -249,10 +245,6 @@ PdfOperator PdfParser::opTab[] = { &PdfParser::opCurveTo2} }; -#ifdef WIN32 // this works around a bug in the VC7 compiler -# pragma optimize("",on) -#endif - #define numOps (sizeof(opTab) / sizeof(PdfOperator)) //------------------------------------------------------------------------ diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 6773069de..8a0d7ee26 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -2387,7 +2387,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, &moving); Geom::LineSegment ls(low_lim, high_lim); - Geom::Point p = ls.pointAt(ls.nearestPoint(dragger->point + p)); + Geom::Point p = ls.pointAt(ls.nearestPoint(dragger->point + Geom::Point(x,y))); Geom::Point displacement = p - dragger->point; for (GSList const* i = moving; i != NULL; i = i->next) { diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 8c4ba5695..54451aba4 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -32,7 +32,10 @@ # define HAS_PROC_SELF_EXE //to get path of executable #else -#define _WIN32_IE 0x0400 +#if !defined(_WIN32_IE) || (_WIN32_IE < 0x0400) +# undef _WIN32_IE +# define _WIN32_IE 0x0400 +#endif //#define HAS_SHGetSpecialFolderPath #define HAS_SHGetSpecialFolderLocation #define HAS_GetModuleFileName diff --git a/src/libcroco/cr-om-parser.c b/src/libcroco/cr-om-parser.c index ea622e35c..c1acb855c 100644 --- a/src/libcroco/cr-om-parser.c +++ b/src/libcroco/cr-om-parser.c @@ -39,6 +39,9 @@ struct _CROMParserPriv { #define PRIVATE(a_this) ((a_this)->priv) +// Unfortunately, C does not allow unnamed function arguments, so use this macro instead... +#define UNUSED(x) (void)(x) + /* *Forward declaration of a type defined later *in this file. @@ -207,6 +210,8 @@ static void start_font_face (CRDocHandler * a_this, CRParsingLocation *a_location) { + UNUSED(a_location); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -302,6 +307,8 @@ static void charset (CRDocHandler * a_this, CRString * a_charset, CRParsingLocation *a_location) { + UNUSED(a_location); + enum CRStatus status = CR_OK; CRStatement *stmt = NULL, *stmt2 = NULL; @@ -340,6 +347,8 @@ start_page (CRDocHandler * a_this, CRString * a_pseudo, CRParsingLocation *a_location) { + UNUSED(a_location); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -381,6 +390,9 @@ end_page (CRDocHandler * a_this, CRString * a_page, CRString * a_pseudo_page) { + UNUSED(a_page); + UNUSED(a_pseudo_page); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -407,8 +419,6 @@ end_page (CRDocHandler * a_this, cr_statement_destroy (ctxt->cur_stmt); ctxt->cur_stmt = NULL; } - a_page = NULL; /*keep compiler happy */ - a_pseudo_page = NULL; /*keep compiler happy */ } static void @@ -416,6 +426,8 @@ start_media (CRDocHandler * a_this, GList * a_media_list, CRParsingLocation *a_location) { + UNUSED(a_location); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -444,6 +456,8 @@ start_media (CRDocHandler * a_this, static void end_media (CRDocHandler * a_this, GList * a_media_list) { + UNUSED(a_media_list); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -470,7 +484,6 @@ end_media (CRDocHandler * a_this, GList * a_media_list) ctxt->cur_stmt = NULL ; ctxt->cur_media_stmt = NULL ; - a_media_list = NULL; } static void @@ -480,6 +493,9 @@ import_style (CRDocHandler * a_this, CRString * a_uri_default_ns, CRParsingLocation *a_location) { + UNUSED(a_uri_default_ns); + UNUSED(a_location); + enum CRStatus status = CR_OK; CRString *uri = NULL; CRStatement *stmt = NULL, @@ -530,7 +546,6 @@ import_style (CRDocHandler * a_this, cr_statement_destroy (stmt); stmt = NULL; } - a_uri_default_ns = NULL; /*keep compiler happy */ } static void @@ -557,6 +572,8 @@ start_selector (CRDocHandler * a_this, CRSelector * a_selector_list) static void end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) { + UNUSED(a_selector_list); + enum CRStatus status = CR_OK; ParsingContext *ctxt = NULL; ParsingContext **ctxtptr = NULL; @@ -604,7 +621,6 @@ end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) } } - a_selector_list = NULL; /*keep compiler happy */ } static void diff --git a/src/libcroco/cr-parser.c b/src/libcroco/cr-parser.c index 41d3eab5a..69b521496 100644 --- a/src/libcroco/cr-parser.c +++ b/src/libcroco/cr-parser.c @@ -78,7 +78,7 @@ typedef struct _CRParserError CRParserError; *parsing routines. */ struct _CRParserError { - guchar *msg; + gchar *msg; enum CRStatus status; glong line; glong column; @@ -374,11 +374,11 @@ static enum CRStatus cr_parser_parse_simple_selector (CRParser * a_this, static enum CRStatus cr_parser_parse_simple_sels (CRParser * a_this, CRSimpleSel ** a_sel); -static CRParserError *cr_parser_error_new (const guchar * a_msg, +static CRParserError *cr_parser_error_new (const gchar * a_msg, enum CRStatus); static void cr_parser_error_set_msg (CRParserError * a_this, - const guchar * a_msg); + const gchar * a_msg); static void cr_parser_error_dump (CRParserError * a_this); @@ -392,7 +392,7 @@ static void cr_parser_error_destroy (CRParserError * a_this); static enum CRStatus cr_parser_push_error (CRParser * a_this, - const guchar * a_msg, + const gchar * a_msg, enum CRStatus a_status); static enum CRStatus cr_parser_dump_err_stack (CRParser * a_this, @@ -411,7 +411,7 @@ static enum CRStatus *@return the newly built instance of #CRParserError. */ static CRParserError * -cr_parser_error_new (const guchar * a_msg, enum CRStatus a_status) +cr_parser_error_new (const gchar * a_msg, enum CRStatus a_status) { CRParserError *result = NULL; @@ -436,7 +436,7 @@ cr_parser_error_new (const guchar * a_msg, enum CRStatus a_status) *@param a_msg the new message. */ static void -cr_parser_error_set_msg (CRParserError * a_this, const guchar * a_msg) +cr_parser_error_set_msg (CRParserError * a_this, const gchar * a_msg) { g_return_if_fail (a_this); @@ -515,7 +515,7 @@ cr_parser_error_destroy (CRParserError * a_this) */ static enum CRStatus cr_parser_push_error (CRParser * a_this, - const guchar * a_msg, enum CRStatus a_status) + const gchar * a_msg, enum CRStatus a_status) { enum CRStatus status = CR_OK; @@ -2430,14 +2430,14 @@ cr_parser_parse_stylesheet (CRParser * a_this) import_string, NULL, &location) ; - if ((PRIVATE (a_this)->sac_handler->resolve_import == TRUE)) { + if (PRIVATE (a_this)->sac_handler->resolve_import == TRUE) { /* *TODO: resolve the *import rule. */ } - if ((PRIVATE (a_this)->sac_handler->import_style_result)) { + if (PRIVATE (a_this)->sac_handler->import_style_result) { PRIVATE (a_this)->sac_handler->import_style_result (PRIVATE (a_this)->sac_handler, media_list, import_string, diff --git a/src/libgdl/gdl-dock-item-button-image.c b/src/libgdl/gdl-dock-item-button-image.c index 31613a898..77cfe5d6c 100644 --- a/src/libgdl/gdl-dock-item-button-image.c +++ b/src/libgdl/gdl-dock-item-button-image.c @@ -135,8 +135,8 @@ static void gdl_dock_item_button_image_class_init ( GdlDockItemButtonImageClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); + //GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + //GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); widget_class->expose_event = diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 2c3ec061e..d23eb7f98 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -536,10 +536,9 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GdlDockItemGrip *grip; - GtkRequisition close_requisition = { 0, }; - GtkRequisition iconify_requisition = { 0, }; + GtkRequisition close_requisition = { 0, 0 }; + GtkRequisition iconify_requisition = { 0, 0 }; GtkAllocation child_allocation; - GdkRectangle label_area; guint border_width; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); diff --git a/src/libgdl/gdl-dock-object.c b/src/libgdl/gdl-dock-object.c index a362d277a..4092ecc9f 100644 --- a/src/libgdl/gdl-dock-object.c +++ b/src/libgdl/gdl-dock-object.c @@ -869,7 +869,7 @@ gdl_dock_param_get_type (void) static GType our_type = 0; if (our_type == 0) { - GTypeInfo tinfo = { 0, }; + GTypeInfo tinfo = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; our_type = g_type_register_static (G_TYPE_STRING, "GdlDockParam", &tinfo, 0); /* register known transform functions */ diff --git a/src/libgdl/gdl-dock-paned.c b/src/libgdl/gdl-dock-paned.c index 42212d489..5b4561ef3 100644 --- a/src/libgdl/gdl-dock-paned.c +++ b/src/libgdl/gdl-dock-paned.c @@ -436,20 +436,20 @@ gdl_dock_paned_dock_request (GdlDockObject *object, my_request.target = object; /* See if it's in the border_width band. */ - if (rel_x < bw) { + if (rel_x < (gint)bw) { my_request.position = GDL_DOCK_LEFT; my_request.rect.width *= SPLIT_RATIO; divider = other.width; - } else if (rel_x > alloc.width - bw) { + } else if (rel_x > alloc.width - (gint)bw) { my_request.position = GDL_DOCK_RIGHT; my_request.rect.x += my_request.rect.width * (1 - SPLIT_RATIO); my_request.rect.width *= SPLIT_RATIO; divider = MAX (0, my.width - other.width); - } else if (rel_y < bw) { + } else if (rel_y < (gint)bw) { my_request.position = GDL_DOCK_TOP; my_request.rect.height *= SPLIT_RATIO; divider = other.height; - } else if (rel_y > alloc.height - bw) { + } else if (rel_y > alloc.height - (gint)bw) { my_request.position = GDL_DOCK_BOTTOM; my_request.rect.y += my_request.rect.height * (1 - SPLIT_RATIO); my_request.rect.height *= SPLIT_RATIO; diff --git a/src/libgdl/gdl-dock.c b/src/libgdl/gdl-dock.c index 6225864f0..c87468e5c 100644 --- a/src/libgdl/gdl-dock.c +++ b/src/libgdl/gdl-dock.c @@ -311,8 +311,6 @@ gdl_dock_constructor (GType type, } if (dock->_priv->floating) { - GdlDockObject *controller; - /* create floating window for this dock */ dock->_priv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_object_set_data (G_OBJECT (dock->_priv->window), "dock", dock); @@ -832,17 +830,17 @@ gdl_dock_dock_request (GdlDockObject *object, my_request.target = dock->root; /* See if it's in the border_width band. */ - if (rel_x < bw) { + if (rel_x < (gint)bw) { my_request.position = GDL_DOCK_LEFT; my_request.rect.width *= SPLIT_RATIO; - } else if (rel_x > alloc.width - bw) { + } else if (rel_x > alloc.width - (gint)bw) { my_request.position = GDL_DOCK_RIGHT; my_request.rect.x += my_request.rect.width * (1 - SPLIT_RATIO); my_request.rect.width *= SPLIT_RATIO; - } else if (rel_y < bw) { + } else if (rel_y < (gint)bw) { my_request.position = GDL_DOCK_TOP; my_request.rect.height *= SPLIT_RATIO; - } else if (rel_y > alloc.height - bw) { + } else if (rel_y > alloc.height - (gint)bw) { my_request.position = GDL_DOCK_BOTTOM; my_request.rect.y += my_request.rect.height * (1 - SPLIT_RATIO); my_request.rect.height *= SPLIT_RATIO; @@ -1215,7 +1213,6 @@ gdl_dock_add_item (GdlDock *dock, /* Non-floating item. */ if (dock->root) { GdlDockPlacement local_placement; - GtkRequisition preferred_size; best_dock_item = gdl_dock_find_best_placement_item (GDL_DOCK_ITEM (dock->root), diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index 780438886..53a4b1989 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -255,12 +255,12 @@ button_toggled_callback (GtkToggleButton *toggle_button, static int layout_buttons (GdlSwitcher *switcher) { - GtkRequisition client_requisition = {0,}; + GtkRequisition client_requisition = {0,0}; GtkAllocation allocation; GdlSwitcherStyle switcher_style; gboolean icons_only; int num_btns = g_slist_length (switcher->priv->buttons); - int btns_per_row; + unsigned int btns_per_row; GSList **rows, *p; Button *button; int row_number; @@ -790,7 +790,6 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, GdkPixbuf *pixbuf_icon, gint switcher_id, GtkWidget* page) { - GtkWidget *event_box; GtkWidget *button_widget; GtkWidget *hbox; GtkWidget *icon_widget; diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index f05b75aaa..7c0b4ffba 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -8,12 +8,14 @@ * */ -#define PANGO_ENABLE_ENGINE - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + #include <glibmm/i18n.h> #include <pango/pangoft2.h> #include "libnrtype/FontFactory.h" diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index a5b782344..20eca6740 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -8,12 +8,14 @@ * */ -#define PANGO_ENABLE_ENGINE - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + #include <ft2build.h> #include FT_OUTLINE_H #include FT_BBOX_H diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index c7b0948e8..cb3e6f620 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -9,7 +9,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef PANGO_ENABLE_ENGINE #define PANGO_ENABLE_ENGINE +#endif #include <gtk/gtk.h> #include "Layout-TNG.h" @@ -25,8 +31,10 @@ namespace Text { void Layout::_clearInputObjects() { - for(std::vector<InputStreamItem*>::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) + for(std::vector<InputStreamItem*>::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) { delete *it; + } + _input_stream.clear(); _input_wrap_shapes.clear(); } diff --git a/src/libuemf/uemf_endian.c b/src/libuemf/uemf_endian.c index f025416c3..f5dcf829a 100644 --- a/src/libuemf/uemf_endian.c +++ b/src/libuemf/uemf_endian.c @@ -36,6 +36,10 @@ extern "C" { #include "uemf.h" #include "uemf_endian.h" +// Unfortunately, C does not allow unnamed function arguments, so use this macro instead... +#define UNUSED(x) (void)(x) + + // hide almost everuything in here from Doxygen //! \cond @@ -425,7 +429,8 @@ by end user code and to further that end prototypes are NOT provided and they ar // all core*_swap call this, U_EMRSETMARGN_swap and some others all it directly // numbered as core5 to be consistent with uemf.c, but must appear before the others as there is no prototype void core5_swap(char *record, int torev){ - torev = torev; // shuts up compiler warnings about unused parameters + UNUSED(torev); + PU_ENHMETARECORD pEMR = (PU_ENHMETARECORD)(record); U_swap4(pEMR,2); // iType nSize } diff --git a/src/libuemf/uemf_utf.c b/src/libuemf/uemf_utf.c index bce60af4d..0c07148a4 100644 --- a/src/libuemf/uemf_utf.c +++ b/src/libuemf/uemf_utf.c @@ -49,11 +49,14 @@ void U_swap2(void *ul, unsigned int count); on another funky system this code may need to be modified, or define ICONV_CAST on the compile line(but it may be tricky). */ +#if _LIBICONV_VERSION == 0x0109 +# define ICONV_CAST (const char **) +#endif // _LIBICONV_VERSION 0x0109 #ifdef SOL8 -#define ICONV_CAST (const char **) +# define ICONV_CAST (const char **) #endif //SOL8 #if !defined(ICONV_CAST) -#define ICONV_CAST (char **) +# define ICONV_CAST (char **) #endif //ICONV_CAST /** \endcond */ diff --git a/src/libuemf/uwmf_endian.c b/src/libuemf/uwmf_endian.c index 6caa24d8f..5fbb450dc 100644 --- a/src/libuemf/uwmf_endian.c +++ b/src/libuemf/uwmf_endian.c @@ -24,6 +24,8 @@ extern "C" { #include "uwmf.h" #include "uwmf_endian.h" +#define UNUSED(x) (void)(x) + // hide almost everything in this file from Doxygen //! \cond /* Prototypes for functions used here and defined in uemf_endian.c, but which are not supposed @@ -282,7 +284,7 @@ by end user code and to further that end prototypes are NOT provided and they ar /* Size16 EVERY record type should call this, directly or indirectly*/ void U_WMRCORE_SIZE16_swap(char *record, int torev){ - torev = torev; // shuts up compiler warnings about unused parameters + UNUSED(torev); U_swap4(record, 1); /* Size16_4 is at offset 0 in U_METARECORD */ } @@ -307,7 +309,7 @@ void U_WMRCORE_U16_N16_swap(char *record, int torev){ /* all records that specify palette objects */ void U_WMRCORE_PALETTE_swap(char *record, int torev){ - torev = torev; // shuts up compiler warnings about unused parameters + UNUSED(torev); U_WMRCORE_SIZE16_swap(record, torev); palette_swap(record + offsetof(U_WMRANIMATEPALETTE,Palette)); } @@ -700,7 +702,7 @@ void U_WMRDIBCREATEPATTERNBRUSH_swap(char *record, int torev){ } void U_WMRSTRETCHDIB_swap(char *record, int torev){ - torev = torev; + UNUSED(torev); U_WMRCORE_U32_N16_swap(record,9,torev); dibheader_swap(record + offsetof(U_WMRSTRETCHDIB,dib), torev); } diff --git a/src/libvpsc/CMakeLists.txt b/src/libvpsc/CMakeLists.txt index 4099900b5..aa693670c 100644 --- a/src/libvpsc/CMakeLists.txt +++ b/src/libvpsc/CMakeLists.txt @@ -3,7 +3,6 @@ set(libvpsc_SRC block.cpp blocks.cpp constraint.cpp - csolve_VPSC.cpp generate-constraints.cpp remove_rectangle_overlap.cpp solve_VPSC.cpp @@ -16,7 +15,6 @@ set(libvpsc_SRC block.h blocks.h constraint.h - csolve_VPSC.h generate-constraints.h pairingheap/PairingHeap.h pairingheap/dsexceptions.h diff --git a/src/libvpsc/Makefile_insert b/src/libvpsc/Makefile_insert index 4af86324e..cb05be6c0 100644 --- a/src/libvpsc/Makefile_insert +++ b/src/libvpsc/Makefile_insert @@ -11,7 +11,6 @@ libvpsc_libvpsc_a_SOURCES = libvpsc/block.cpp\ libvpsc/pairingheap/PairingHeap.cpp\ libvpsc/remove_rectangle_overlap.cpp\ libvpsc/solve_VPSC.cpp\ - libvpsc/csolve_VPSC.cpp\ libvpsc/variable.cpp\ libvpsc/block.h\ libvpsc/blocks.h\ @@ -21,5 +20,4 @@ libvpsc_libvpsc_a_SOURCES = libvpsc/block.cpp\ libvpsc/pairingheap/dsexceptions.h\ libvpsc/remove_rectangle_overlap.h\ libvpsc/solve_VPSC.h\ - libvpsc/csolve_VPSC.h\ libvpsc/variable.h diff --git a/src/libvpsc/csolve_VPSC.cpp b/src/libvpsc/csolve_VPSC.cpp deleted file mode 100644 index 60e88a50b..000000000 --- a/src/libvpsc/csolve_VPSC.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Bridge for C programs to access solve_VPSC (which is in C++). - * - * Authors: - * Tim Dwyer <tgdwyer@gmail.com> - * - * Copyright (C) 2005 Authors - * - * Released under GNU LGPL. Read the file 'COPYING' for more information. - */ -#include <glib.h> -#include <iostream> -#include <cassert> -#include <cstdlib> -#include "variable.h" -#include "constraint.h" -#include "generate-constraints.h" -#include "solve_VPSC.h" -#include "csolve_VPSC.h" -using namespace vpsc; -extern "C" { -Variable* newVariable(int id, double desiredPos, double weight) { - return new Variable(id,desiredPos,weight); -} -Constraint* newConstraint(Variable* left, Variable* right, double gap) { - return new Constraint(left,right,gap); -} -Solver* newSolver(int n, Variable* vs[], int m, Constraint* cs[]) { - return new Solver(n,vs,m,cs); -} -Solver* newIncSolver(int n, Variable* vs[], int m, Constraint* cs[]) { - return (Solver*)new vpsc::IncSolver(n,vs,m,cs); -} - -int genXConstraints(int n, boxf* bb, Variable** vs, Constraint*** cs,int transitiveClosure) { - Rectangle* rs[n]; - for(int i=0;i<n;i++) { - rs[i]=new Rectangle(bb[i].LL.x,bb[i].UR.x,bb[i].LL.y,bb[i].UR.y); - } - int m = generateXConstraints(n,rs,vs,*cs,transitiveClosure); - for(int i=0;i<n;i++) { - delete rs[i]; - } - return m; -} -int genYConstraints(int n, boxf* bb, Variable** vs, Constraint*** cs) { - g_assert(n > 0); - Rectangle* rs[n]; - for(int i=0;i<n;i++) { - rs[i]=new Rectangle(bb[i].LL.x,bb[i].UR.x,bb[i].LL.y,bb[i].UR.y); - } - int m = generateYConstraints(n,rs,vs,*cs); - for(int i=0;i<n;i++) { - delete rs[i]; - } - return m; -} - -Constraint** newConstraints(int m) { - return new Constraint*[m]; -} -void deleteConstraints(int m, Constraint **cs) { - for(int i=0;i<m;i++) { - delete cs[i]; - } - delete [] cs; -} -void deleteConstraint(Constraint* c) { - delete c; -} -void deleteVariable(Variable* v) { - delete v; -} -void satisfyVPSC(Solver* vpsc) { - try { - vpsc->satisfy(); - } catch(const char *e) { - std::cerr << e << std::endl; - exit(1); - } -} -int getSplitCnt(IncSolver *vpsc) { - return vpsc->splitCnt; -} -void deleteVPSC(Solver *vpsc) { - assert(vpsc!=NULL); - delete vpsc; -} -void solveVPSC(Solver* vpsc) { - vpsc->solve(); -} -void splitIncVPSC(IncSolver* vpsc) { - vpsc->splitBlocks(); -} -void setVariableDesiredPos(Variable *v, double desiredPos) { - v->desiredPosition = desiredPos; -} -double getVariablePos(Variable *v) { - return v->position(); -} -void remapInConstraints(Variable *u, Variable *v, double dgap) { - for(Constraints::iterator i=u->in.begin();i!=u->in.end();i++) { - Constraint* c=*i; - c->right=v; - c->gap+=dgap; - v->in.push_back(c); - } - u->in.clear(); -} -void remapOutConstraints(Variable *u, Variable *v, double dgap) { - for(Constraints::iterator i=u->out.begin();i!=u->out.end();i++) { - Constraint* c=*i; - c->left=v; - c->gap+=dgap; - v->out.push_back(c); - } - u->out.clear(); -} -int getLeftVarID(Constraint *c) { - return c->left->id; -} -int getRightVarID(Constraint *c){ - return c->right->id; -} -double getSeparation(Constraint *c){ - return c->gap; -} -} diff --git a/src/libvpsc/csolve_VPSC.h b/src/libvpsc/csolve_VPSC.h deleted file mode 100644 index edfd16657..000000000 --- a/src/libvpsc/csolve_VPSC.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file - * Bridge for C programs to access solve_VPSC (which is in C++). - */ -/* - * Authors: - * Tim Dwyer <tgdwyer@gmail.com> - * - * Copyright (C) 2005 Authors - * - * Released under GNU LGPL. Read the file 'COPYING' for more information. - */ -#ifndef CSOLVE_VPSC_H_ -#define CSOLVE_VPSC_H_ -#ifdef __cplusplus -namespace vpsc -{ - class Variable; - class Constraint; - class Solver; - class IncSolver; -} -/* TODO 'using' should never be in a .h file. We need a different approach here. */ -using vpsc::Variable; -using vpsc::Constraint; -using vpsc::Solver; -using vpsc::IncSolver; -extern "C" { -#else -typedef struct Variable Variable; -typedef struct Constraint Constraint; -typedef struct Solver Solver; -typedef struct IncSolver IncSolver; -#endif - -Variable* newVariable(int id, double desiredPos, double weight); -void setVariableDesiredPos(Variable *, double desiredPos); -double getVariablePos(Variable*); - -Constraint* newConstraint(Variable* left, Variable* right, double gap); - -Solver* newSolver(int n, Variable* vs[], int m, Constraint* cs[]); -void deleteSolver(Solver*); -void deleteConstraint(Constraint*); -void deleteVariable(Variable*); -Constraint** newConstraints(int m); -void deleteConstraints(int m,Constraint**); -void remapInConstraints(Variable *u, Variable *v, double dgap); -void remapOutConstraints(Variable *u, Variable *v, double dgap); -int getLeftVarID(Constraint *c); -int getRightVarID(Constraint *c); -double getSeparation(Constraint *c); - -#ifndef HAVE_POINTF_S -typedef struct pointf_s { double x, y; } pointf; -typedef struct { pointf LL, UR; } boxf; -#endif -int genXConstraints(int n, boxf[], Variable** vs, Constraint*** cs, - int transitiveClosure); -int genYConstraints(int n, boxf[], Variable** vs, Constraint*** cs); - -void satisfyVPSC(Solver*); -void deleteVPSC(Solver*); -void solveVPSC(Solver*); -void splitIncVPSC(IncSolver*); -Solver* newIncSolver(int n, Variable* vs[], int m, Constraint* cs[]); -void splitIncSolver(IncSolver*); -int getSplitCnt(IncSolver *vpsc); -#ifdef __cplusplus -} -#endif -#endif /* CSOLVE_VPSC_H_ */ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d6840e5b8..337fe631f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects +#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 93e645783..3b2887bb5 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -158,46 +158,13 @@ void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem) } } - +//NOTE: I originally had all the outliner functions defined in here, but they were actually useful +//enough for other LPEs so I moved them all into pathoutlineprovider.cpp. The code here is just a +//wrapper around it. std::vector<Geom::Path> LPEJoinType::doEffect_path(std::vector<Geom::Path> const & path_in) -{ - std::vector<Geom::Path> path_out = std::vector<Geom::Path>(); - if (path_in.empty()) - { - return path_out; - } - Path p = Path(); - Path outlinepath = Path(); - for (unsigned i = 0; i < path_in.size(); i++) - { - p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); - } - - #define miter_lim ( (attempt_force_join) ? std::numeric_limits<double>::max() : fabs(line_width * miter_limit)) - - //magic! - if (linejoin_type.get_value() <= 2) - { - p.Outline(&outlinepath, line_width / 2, static_cast<JoinType>( linejoin_type.get_value() ), - static_cast<ButtType>( linecap_type.get_value() ), miter_lim); - //fix memory leak - std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector(); - path_out = *pv_p; - delete pv_p; - - } else if (linejoin_type.get_value() == 3) { - //reflected arc join - path_out = Outline::outlinePath(path_in, line_width, static_cast<JoinType>( linejoin_type.get_value() ), - static_cast<ButtType>( linecap_type.get_value() ), miter_lim); - - } else if (linejoin_type.get_value() == 4) { - //extrapolated arc join - path_out = Outline::outlinePath_extr(path_in, line_width, LINEJOIN_STRAIGHT, static_cast<ButtType>(linecap_type.get_value()), miter_lim); - - } - - #undef miter_lim - return path_out; +{ + return Outline::PathVectorOutline(path_in, line_width, static_cast<ButtType>(linecap_type.get_value()), + static_cast<LineJoinType>(linejoin_type.get_value()), miter_limit); } } //namespace LivePathEffect diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index f6bc1de65..d17def471 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -380,7 +380,6 @@ static Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise<Geom::D2<Geom:: Geom::Piecewise<Geom::SBasis> const & y, // width path LineJoinType jointype, double miter_limit, - bool /*forward_direction*/, double tol=Geom::EPSILON) { /* per definition, each discontinuity should be fixed with a join-ending, as defined by linejoin_type @@ -683,7 +682,7 @@ LPEPowerStroke::doEffect_path (std::vector<Geom::Path> const & path_in) Piecewise<D2<SBasis> > pwd2_out = compose(pwd2_in,x) + y*compose(n,x); Piecewise<D2<SBasis> > mirrorpath = reverse(compose(pwd2_in,x) - y*compose(n,x)); - Geom::Path fixed_path = path_from_piecewise_fix_cusps( pwd2_out, y, jointype, miter_limit, LPE_CONVERSION_TOLERANCE); + Geom::Path fixed_path = path_from_piecewise_fix_cusps( pwd2_out, y, jointype, miter_limit, LPE_CONVERSION_TOLERANCE); Geom::Path fixed_mirrorpath = path_from_piecewise_fix_cusps( mirrorpath, reverse(y), jointype, miter_limit, LPE_CONVERSION_TOLERANCE); if (path_in[0].closed()) { diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 0e709f3ac..91b8fd7bc 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -232,52 +232,21 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler return path_out; } -Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first) -{ - //the only reason for this function is the lack of a subdivide function in the Curve class. - //you have to cast to Beziers to be able to use subdivide(t) - unsigned order = Outline::bezierOrder(curve_in); - Geom::Curve* curve_out = curve_in->duplicate(); - switch (order) - { - //these need to be scoped because of the variable 'c' - case 3: - { - Geom::CubicBezier c = first ? (dynamic_cast<Geom::CubicBezier*> (curve_out))->subdivide(time).first : - (dynamic_cast<Geom::CubicBezier*> (curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - case 2: - { - Geom::QuadraticBezier c = first ? (dynamic_cast<Geom::QuadraticBezier*>(curve_out))->subdivide(time).first : - (dynamic_cast<Geom::QuadraticBezier*>(curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - case 1: - { - Geom::BezierCurveN<1> c = first ? (dynamic_cast<Geom::BezierCurveN<1>* >(curve_out))->subdivide(time).first : - (dynamic_cast<Geom::BezierCurveN<1>* >(curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - } - return curve_out; -} - +Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first); Geom::Piecewise<Geom::D2<Geom::SBasis> > stretch_along(Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in, Geom::Path pattern, double width); Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { + Geom::Path first_cusp = return_at_first_cusp(path_in[0]); + Geom::Path last_cusp = return_at_first_cusp(path_in[0].reverse()); + + bool zeroStart = false; + bool zeroEnd = false; //there is a pretty good chance that people will try to drag the knots //on top of each other, so block it unsigned size = path_in[0].size(); - if (size == return_at_first_cusp(path_in[0]).size()) { + if (size == first_cusp.size()) { //check to see if the knots were dragged over each other //if so, reset the end offset if ( attach_start >= (size - attach_end) ) { @@ -287,176 +256,213 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //don't ever let it be zero if (attach_start <= 0) { - attach_start.param_set_value( 0.0001 ); + attach_start.param_set_value( 0.00000001 ); } if (attach_end <= 0) { - attach_end.param_set_value( 0.0001 ); + attach_end.param_set_value( 0.00000001 ); } //don't let it be integer if (double(unsigned(attach_start)) == attach_start) { - attach_start.param_set_value(attach_start - 0.0001); + attach_start.param_set_value(attach_start - 0.00000001); + zeroStart = true; } if (double(unsigned(attach_end)) == attach_end) { - attach_end.param_set_value(attach_end - 0.0001); + attach_end.param_set_value(attach_end - 0.00000001); + zeroStart = true; } - unsigned allowed_start = return_at_first_cusp(path_in[0]).size(); - - unsigned allowed_end = return_at_first_cusp(path_in[0].reverse()).size(); + unsigned allowed_start = first_cusp.size(); + unsigned allowed_end = last_cusp.size(); + //don't let the knots be farther than they are allowed to be if ((unsigned)attach_start >= allowed_start) { - attach_start.param_set_value((double)allowed_start - 0.0001); + attach_start.param_set_value((double)allowed_start - 0.00000001); } if ((unsigned)attach_end >= allowed_end) { - attach_end.param_set_value((double)allowed_end - 0.0001); + attach_end.param_set_value((double)allowed_end - 0.00000001); } - //Path::operator () means get point at time t - start_attach_point = return_at_first_cusp(path_in[0])(attach_start); - end_attach_point = return_at_first_cusp(path_in[0].reverse())(attach_end); + //remember, Path::operator () means get point at time t + start_attach_point = first_cusp(attach_start); + end_attach_point = last_cusp(attach_end); Geom::PathVector pathv_out; + //the following function just splits it up into three pieces. pathv_out = doEffect_simplePath(path_in); + //now for the actual tapering. We use a Pattern Along Path method to get this done. - //now for the fun stuff. Right? RIGHT? - - if (true) { - Geom::PathVector real_pathv; - Geom::Path real_path; + Geom::PathVector real_pathv; + Geom::Path real_path; + Geom::PathVector pat_vec; + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2; + Geom::Path throwaway_path; + + if (!zeroStart) { + //Construct the pattern (pat_str stands for pattern string) (yes, this is easier, trust me) + std::stringstream pat_str; + pat_str << "M 1,0 1,1 C " << 1 - (double)smoothing << ",1 0,0.5 0,0.5 0,0.5 " << 1 - double(smoothing) << ",0 1,0"; + + pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); - //Construct the pattern (pat_str stands for pattern string) - std::stringstream pat_str; - pat_str << "M 1,0 1,1 C " << 1 - (double)smoothing << ",1 0,0.5 0,0.5 0,0.5 " << 1 - double(smoothing) << ",0 1,0"; - - Geom::PathVector pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); + pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2; - pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); + throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0].reverse(); + throwaway_path.erase_last(); //wtf - Geom::Path throwaway_path = path_from_piecewise(pwd2, 0.001)[0].reverse(); - throwaway_path.erase_last(); - - real_path.append(throwaway_path); //wtf - - throwaway_path = Outline::PathOutsideOutline(pathv_out[1], - line_width, static_cast<LineJoinType>(join_type.get_value()), miter_limit); + real_path.append(throwaway_path); + } + //append the outside outline of the path (with direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1], + line_width, static_cast<LineJoinType>(join_type.get_value()), miter_limit); - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); - - std::stringstream pat_str_1; - pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; - pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); - - pwd2 = Geom::Piecewise<Geom::D2<Geom::SBasis> > (); - pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], line_width)); + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + + if (!zeroEnd) { + //append the ending taper + std::stringstream pat_str_1; + pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; + pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); - throwaway_path = Geom::Path(); - throwaway_path = path_from_piecewise(pwd2, 0.001)[0]; - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); + pwd2 = Geom::Piecewise<Geom::D2<Geom::SBasis> > (); + pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], line_width)); - throwaway_path = Geom::Path(); - throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), - line_width, static_cast<LineJoinType>(join_type.get_value()), miter_limit); - - //throwaway_path = throwaway_path.reverse(); - throwaway_path.setInitial(real_path.finalPoint()); + throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + } + //append the inside outline of the path (against direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), + line_width, static_cast<LineJoinType>(join_type.get_value()), miter_limit); - real_path.append(throwaway_path); - //real_path.close(); + throwaway_path.setInitial(real_path.finalPoint()); - real_pathv.push_back(real_path); + real_path.append(throwaway_path); + real_path.close(); - //real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0].reverse()); + real_pathv.push_back(real_path); - return real_pathv; - } - - return pathv_out; + return real_pathv; } //in all cases, this should return a PathVector with three elements. Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & path_in) { - unsigned size = path_in[0].size(); + unsigned size = path_in[0].size(); - //do subdivision and get out - unsigned loc = (unsigned)attach_start; - Geom::Curve * curve_start = path_in[0] [loc].duplicate(); + //do subdivision and get out + unsigned loc = (unsigned)attach_start; + Geom::Curve * curve_start = path_in[0] [loc].duplicate(); - std::vector<Geom::Path> pathv_out; - Geom::Path path_out = Geom::Path(); + std::vector<Geom::Path> pathv_out; + Geom::Path path_out = Geom::Path(); - Geom::Path trimmed_start = Geom::Path(); - Geom::Path trimmed_end = Geom::Path(); + Geom::Path trimmed_start = Geom::Path(); + Geom::Path trimmed_end = Geom::Path(); - for (unsigned i = 0; i < loc; i++) { - trimmed_start.append(path_in[0] [i]); - } + for (unsigned i = 0; i < loc; i++) { + trimmed_start.append(path_in[0] [i]); + } - #define OVERLAP 0 /*(0.001 / (line_width < 1 ? 1 : line_width))*/ - trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc) + OVERLAP, true)); - curve_start = subdivide_at(curve_start, attach_start - loc, false); + trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc), true)); + curve_start = subdivide_at(curve_start, attach_start - loc, false); - //special case: path is one segment long - //special case: what if the two knots occupy the same segment? - if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) - { - Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); - //it is just a dumb segment - //we have to do some shifting here because the value changed when we reduced the length - //of the previous segment. - trimmed_end.append(*subdivide_at(curve_start, t - OVERLAP, false)); - for (unsigned j = (size - attach_end) + 1; j < size; j++) { - trimmed_end.append(path_in[0] [j]); - } - - curve_start = subdivide_at(curve_start, t, true); - path_out.append(*curve_start); - pathv_out.push_back(trimmed_start); - pathv_out.push_back(path_out); - pathv_out.push_back(trimmed_end); - return pathv_out; + //special case: path is one segment long + //special case: what if the two knots occupy the same segment? + if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) + { + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); + //it is just a dumb segment + //we have to do some shifting here because the value changed when we reduced the length + //of the previous segment. + trimmed_end.append(*subdivide_at(curve_start, t, false)); + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); } - + + curve_start = subdivide_at(curve_start, t, true); + path_out.append(*curve_start); pathv_out.push_back(trimmed_start); + pathv_out.push_back(path_out); + pathv_out.push_back(trimmed_end); + return pathv_out; + } - //append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute) - path_out.append(*curve_start); + pathv_out.push_back(trimmed_start); + + //append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute) + path_out.append(*curve_start); - for (unsigned k = loc + 1; k < (size - unsigned(attach_end)) - 1; k++) { - path_out.append(path_in[0] [k]); - } + for (unsigned k = loc + 1; k < (size - unsigned(attach_end)) - 1; k++) { + path_out.append(path_in[0] [k]); + } - //deal with the last segment in a very similar fashion to the first - loc = size - attach_end; + //deal with the last segment in a very similar fashion to the first + loc = size - attach_end; - Geom::Curve * curve_end = path_in[0] [loc].duplicate(); + Geom::Curve * curve_end = path_in[0] [loc].duplicate(); - Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); - trimmed_end.append(*subdivide_at(curve_end, t - OVERLAP, false)); - curve_end = subdivide_at(curve_end, t, true); + trimmed_end.append(*subdivide_at(curve_end, t, false)); + curve_end = subdivide_at(curve_end, t, true); - for (unsigned j = (size - attach_end) + 1; j < size; j++) { - trimmed_end.append(path_in[0] [j]); - } + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); + } - path_out.append(*curve_end); - pathv_out.push_back(path_out); + path_out.append(*curve_end); + pathv_out.push_back(path_out); - pathv_out.push_back(trimmed_end); + pathv_out.push_back(trimmed_end); - if (curve_end) delete curve_end; - if (curve_start) delete curve_start; - return pathv_out; + if (curve_end) delete curve_end; + if (curve_start) delete curve_start; + return pathv_out; +} + +Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first) +{ + //the only reason for this function is the lack of a subdivide function in the Curve class. + //you have to cast to Beziers to be able to use subdivide(t) + unsigned order = Outline::bezierOrder(curve_in); + Geom::Curve* curve_out = curve_in->duplicate(); + switch (order) + { + //these need to be scoped because of the variable 'c' + case 3: + { + Geom::CubicBezier c = first ? (dynamic_cast<Geom::CubicBezier*> (curve_out))->subdivide(time).first : + (dynamic_cast<Geom::CubicBezier*> (curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + case 2: + { + Geom::QuadraticBezier c = first ? (dynamic_cast<Geom::QuadraticBezier*>(curve_out))->subdivide(time).first : + (dynamic_cast<Geom::QuadraticBezier*>(curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + case 1: + { + Geom::BezierCurveN<1> c = first ? (dynamic_cast<Geom::BezierCurveN<1>* >(curve_out))->subdivide(time).first : + (dynamic_cast<Geom::BezierCurveN<1>* >(curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + } + return curve_out; } + //most of the below code is verbatim from Pattern Along Path. However, it needed a little //tweaking to get it to work right in this case. Geom::Piecewise<Geom::D2<Geom::SBasis> > stretch_along(Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in, Geom::Path pattern, double prop_scale) diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 302756c7c..3565fabec 100755 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -141,721 +141,392 @@ typedef Geom::Piecewise<D2SB> PWD2; unsigned bezierOrder (const Geom::Curve* curve_in)
{
- using namespace Geom;
- //cast it
- const CubicBezier *cbc = dynamic_cast<const CubicBezier*>(curve_in);
- if (cbc) return 3;
- const QuadraticBezier * qbc = dynamic_cast<const QuadraticBezier*>(curve_in);
- if (qbc) return 2;
- const BezierCurveN<1U> * lbc = dynamic_cast<const BezierCurveN<1U> *>(curve_in);
- if (lbc) return 1;
- return 0;
+ using namespace Geom;
+ //cast it
+ const CubicBezier *cbc = dynamic_cast<const CubicBezier*>(curve_in);
+ if (cbc) return 3;
+ const QuadraticBezier * qbc = dynamic_cast<const QuadraticBezier*>(curve_in);
+ if (qbc) return 2;
+ const BezierCurveN<1U> * lbc = dynamic_cast<const BezierCurveN<1U> *>(curve_in);
+ if (lbc) return 1;
+ return 0;
}
//returns true if the angle formed by the curves and their handles
//is >180 clockwise, otherwise false.
bool outside_angle (const Geom::Curve* cbc1, const Geom::Curve* cbc2)
{
- Geom::Point start_point = cbc1->initialPoint();
- Geom::Point end_point = cbc2->finalPoint();
- unsigned order = bezierOrder(cbc1);
- switch (order)
- {
- case 3:
- start_point = ( dynamic_cast<const Geom::CubicBezier*>(cbc1) )->operator [] (2);
- break;
- case 2:
- start_point = ( dynamic_cast<const Geom::QuadraticBezier*>(cbc1) )->operator [] (1);
- break;
- }
- order = bezierOrder(cbc2);
- switch (order)
- {
- case 3:
- end_point = ( dynamic_cast<const Geom::CubicBezier*>(cbc2) )->operator [] (1);
- break;
- case 2:
- end_point = ( dynamic_cast<const Geom::QuadraticBezier*>(cbc2) )->operator[] (1);
- break;
- }
- return false;
+ Geom::Point start_point = cbc1->initialPoint();
+ Geom::Point end_point = cbc2->finalPoint();
+ unsigned order = bezierOrder(cbc1);
+ switch (order) {
+ case 3:
+ start_point = ( dynamic_cast<const Geom::CubicBezier*>(cbc1) )->operator [] (2);
+ break;
+ case 2:
+ start_point = ( dynamic_cast<const Geom::QuadraticBezier*>(cbc1) )->operator [] (1);
+ break;
+ }
+ order = bezierOrder(cbc2);
+ switch (order) {
+ case 3:
+ end_point = ( dynamic_cast<const Geom::CubicBezier*>(cbc2) )->operator [] (1);
+ break;
+ case 2:
+ end_point = ( dynamic_cast<const Geom::QuadraticBezier*>(cbc2) )->operator[] (1);
+ break;
+ }
+ return false;
}
-void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit)
+void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit)
{
-
- Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
- if (cross.empty())
- {
- Geom::Path pth;
- pth.append(*cbc1);
-
- //Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1);
- pth = Geom::Path();
- pth.append( *cbc2 );
- Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0);
+ Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
+ if (cross.empty()) {
+ Geom::Path pth;
+ pth.append(*cbc1);
+
+ //Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1);
+
+ pth = Geom::Path();
+ pth.append( *cbc2 );
+ Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0);
+
+
+ Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.);
+ Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0);
+
+ Geom::Point points[2];
+ int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]);
+ if (solutions == 2) {
+ Geom::Point sol(0,0);
+ if ( dot(tang2,points[0]-endPt) > 0 ) {
+ // points[0] is bad, choose points[1]
+ sol = points[1];
+ } else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1]
+ // points[1] is bad, choose points[0]
+ sol = points[0];
+ } else {
+ // both points are good, choose nearest
+ sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ?
+ points[0] : points[1];
+ }
+ Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true);
+ Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true);
+
+ if (arc0) {
+ path_builder.append (arc0->toSBasis());
+ delete arc0;
+ arc0 = NULL;
+ }
+
+ if (arc1) {
+ path_builder.append (arc1->toSBasis());
+ delete arc1;
+ arc1 = NULL;
+ }
+ } else {
+ path_builder.appendNew<Geom::LineSegment> (endPt);
+ }
+ } else {
+ path_builder.appendNew<Geom::LineSegment> (endPt);
+ }
+}
+void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit)
+{
+ //the most important work for the reflected join is done here
- Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.);
- Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0);
+ //determine where we are in the path. If we're on the inside, ignore
+ //and just lineTo. On the outside, we'll do a little reflection magic :)
+
+ //note: this is TERRIBLY inaccurate.
+ Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
+ if (cross.empty()) {
+ //probably on the outside of the corner
+ Geom::Path pth;
+ pth.append(*cbc1);
+
+ Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1);
+
+ //reflect curves along the bevel
+ D2SB newcurve1 = pth.toPwSb()[0] *
+ Geom::reflection ( -Geom::rot90(tang1) ,
+ cbc1->finalPoint() );
+
+ Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1));
+
+ pth = Geom::Path();
+ pth.append( *cbc2 );
+ Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0);
+
+ D2SB newcurve2 = pth.toPwSb()[0] *
+ Geom::reflection ( -Geom::rot90(tang2) ,
+ cbc2->initialPoint() );
+ Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2));
+
+ cross = Geom::crossings(bzr1, bzr2);
+ if ( cross.empty() ) {
+ //curves didn't cross; default to miter
+ /*boost::optional <Geom::Point> p = intersection_point (cbc1->finalPoint(), tang1,
+ cbc2->initialPoint(), tang2);
+ if (p)
+ {
+ path_builder.appendNew<Geom::LineSegment> (*p);
+ }*/
+ //bevel
+ path_builder.appendNew<Geom::LineSegment>( endPt );
+ } else {
+ //join
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> sub1 = bzr1.subdivide(cross[0].ta);
+ std::pair<Geom::CubicBezier, Geom::CubicBezier> sub2 = bzr2.subdivide(cross[0].tb);
+
+ //@TODO joins have a strange tendency to cross themselves twice. Check this.
+
+ //sections commented out are for general stability
+ path_builder.appendNew <Geom::CubicBezier> (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] );
+ path_builder.appendNew <Geom::CubicBezier> (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt );
+ }
+ } else { // cross.empty()
+ //probably on the inside of the corner
+ path_builder.appendNew<Geom::LineSegment> ( endPt );
+ }
+}
- Geom::Point points[2];
- int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]);
- if (solutions == 2)
- {
- Geom::Point sol(0,0);
- if ( dot(tang2,points[0]-endPt) > 0 )
- {
- // points[0] is bad, choose points[1]
- sol = points[1];
- }
- else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1]
- // points[1] is bad, choose points[0]
- sol = points[0];
- }
- else
- {
- // both points are good, choose nearest
- sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ?
- points[0] : points[1];
- }
- Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true);
- Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true);
-
- if (arc0)
- {
- path_builder.append (arc0->toSBasis());
- delete arc0;
- arc0 = NULL;
- }
-
- if (arc1)
- {
- path_builder.append (arc1->toSBasis());
- delete arc1;
- arc1 = NULL;
- }
- }
- else
- {
- path_builder.appendNew<Geom::LineSegment> (endPt);
- }
- }
- else
- {
- path_builder.appendNew<Geom::LineSegment> (endPt);
- }
+/** @brief Converts a path to one half of an outline.
+* path_in: The input path to use. (To create the other side use path_in.reverse() )
+* line_width: the line width to use (usually you want to divide this by 2)
+* miter_limit: the miter parameter
+* extrapolate: whether the join should be extrapolated instead of reflected
+*/
+Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double miter_limit, bool extrapolate = false)
+{
+ // NOTE: it is important to notice the distinction between a Geom::Path and a livarot Path here!
+ // if you do not see "Geom::" there is a different function set!
+ Geom::PathVector pv = split_at_cusps(path_in);
+
+ Path to_outline;
+ Path outlined_result;
+
+ Geom::Path path_builder = Geom::Path(); //the path to store the result in
+ Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer
+
+ const unsigned k = path_in.size();
+
+ for (unsigned u = 0; u < k; u+=2)
+ {
+ to_outline = Path();
+ outlined_result = Path();
+
+ to_outline.LoadPath(pv[u], Geom::Affine(), false, false);
+ to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
+ //now a curve has been outside outlined and loaded into outlined_result
+
+ //get the Geom::Path
+ path_vec = outlined_result.MakePathVector();
+
+ //thing to do on the first run through
+ if (u == 0) {
+ //I could use the pv->operator[] (0) notation but that looks terrible
+ path_builder.start( (*path_vec)[0].initialPoint() );
+ } else {
+ //get the curves ready for the operation
+ Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate();
+ Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate();
+
+ //do the reflection/extrapolation:
+ if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit); }
+ else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit); }
+ }
+
+ path_builder.append( (*path_vec)[0] );
+
+ //outline the next segment, but don't store it yet
+ if (path_vec) delete path_vec;
+
+ if (u < k - 1) {
+ outlined_result = Path();
+ to_outline = Path();
+
+ to_outline.LoadPath(pv[u+1], Geom::Affine(), false, false);
+ to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10);
+
+ path_vec = outlined_result.MakePathVector();
+
+ //get the curves ready for the operation
+ Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate();
+ Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate();
+
+ //do the reflection/extrapolation:
+ if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit); }
+ else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit); }
+
+ //Now we can store it.
+ path_builder.append( (*path_vec)[0] );
+
+ if (cbc1) delete cbc1;
+ if (cbc2) delete cbc2;
+ if (path_vec) delete path_vec;
+ }
+ }
+
+ return path_builder;
}
- Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit)
- {
- Geom::PathVector pv = split_at_cusps(path_in);
- unsigned m;
- Path path_outline = Path();
- Path path_tangent = Path();
-
- Geom::Point initialPoint;
- Geom::Point endPoint;
-
- Geom::Path path_builder = Geom::Path();
- Geom::PathVector * pathvec;
-
- //load the first portion in before the loop starts
- {
- path_outline = Path();
- path_outline.LoadPath(pv[0], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
- //now half of first cusp has been loaded
-
- pathvec = path_tangent.MakePathVector();
- path_tangent = Path();
-
- //instead of array accessing twice, dereferencing used for clarity
- initialPoint = (*pathvec)[0].initialPoint();
-
- path_builder.start(initialPoint);
- path_builder.append( (*pathvec)[0] );
-
- path_outline = Path();
- path_outline.LoadPath(pv[1], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
-
- delete pathvec; pathvec = NULL;
- pathvec = path_tangent.MakePathVector();
- path_tangent = Path();
-
- Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate();
- Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate();
-
- extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit );
-
- path_builder.append( (*pathvec)[0] );
-
- //always set pointers null after deleting
- delete pathvec; pathvec = NULL;
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
-
- for (m = 2; m < pv.size(); m++)
- {
- path_outline = Path();
- path_outline.LoadPath(pv[m], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
-
- delete pathvec; pathvec = NULL;
- pathvec = path_tangent.MakePathVector();
-
- Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate();
- Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate();
-
- extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit );
- path_builder.append( (*pathvec)[0] );
-
- delete pathvec; pathvec = NULL;
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
-
- return path_builder;
- }
- //Create a reflected outline join.
- //Note: it is generally recommended to let half_outline do this for you!
- //path_builder: the path to append the curves to
- //cbc1: the curve before the join
- //cbc2: the curve after the join
- //endPt: the point to end at
- //miter_limit: the miter parameter
- void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit)
- {
- //the most important work for the reflected join is done here
+Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join,
+ ButtType butt, double miter_lim, bool extrapolate)
+{
+ Geom::PathVector path_out;
+
+ unsigned pv_size = path_in.size();
+ for (unsigned i = 0; i < pv_size; i++) {
+
+ if (path_in[i].size() > 1) {
+ //since you've made it this far, hopefully all this is obvious :P
+ Geom::Path with_direction;
+ Geom::Path against_direction;
+
+ with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate );
+ against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, extrapolate );
+
+ Geom::PathBuilder pb;
+
+ //add in the...do I really need to say this?
+ pb.moveTo(with_direction.initialPoint());
+ pb.append(with_direction);
+
+ //add in our line caps
+ if (!path_in[i].closed()) {
+ switch (butt) {
+ case butt_straight:
+ pb.lineTo(against_direction.initialPoint());
+ break;
+ case butt_round:
+ pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() );
+ break;
+ case butt_pointy:
+ //I have ZERO idea what to do here.
+ pb.lineTo(against_direction.initialPoint());
+ break;
+ case butt_square:
+ pb.lineTo(against_direction.initialPoint());
+ break;
+ }
+ } else {
+ pb.moveTo(against_direction.initialPoint());
+ }
+
+ pb.append(against_direction);
+
+ //cap (if necessary)
+ if (!path_in[i].closed()) {
+ switch (butt) {
+ case butt_straight:
+ pb.lineTo(with_direction.initialPoint());
+ break;
+ case butt_round:
+ pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() );
+ break;
+ case butt_pointy:
+ //I have ZERO idea what to do here.
+ pb.lineTo(with_direction.initialPoint());
+ break;
+ case butt_square:
+ pb.lineTo(with_direction.initialPoint());
+ break;
+ }
+ }
+ pb.flush();
+ for (unsigned m = 0; i < pb.peek().size(); i++) {
+ path_out.push_back(pb.peek()[m]);
+ }
+ } else {
+ Path p = Path();
+ Path outlinepath = Path();
+
+ p.LoadPath(path_in[i], Geom::Affine(), false, false);
+ p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(join), butt, miter_lim);
+ Geom::PathVector *pv_p = outlinepath.MakePathVector();
+ //somewhat hack-ish
+ path_out.push_back( (*pv_p)[0].reverse() );
+ if (pv_p) delete pv_p;
+ }
+ }
+ return path_out;
+}
- //determine where we are in the path. If we're on the inside, ignore
- //and just lineTo. On the outside, we'll do a little reflection magic :)
- Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
- if (cross.empty())
- {
- //probably on the outside of the corner
- Geom::Path pth;
- pth.append(*cbc1);
-
- Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1);
-
- //reflect curves along the bevel
- D2SB newcurve1 = pth.toPwSb()[0] *
- Geom::reflection ( -Geom::rot90(tang1) ,
- cbc1->finalPoint() );
-
- Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1));
-
- pth = Geom::Path();
- pth.append( *cbc2 );
- Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0);
-
- D2SB newcurve2 = pth.toPwSb()[0] *
- Geom::reflection ( -Geom::rot90(tang2) ,
- cbc2->initialPoint() );
- Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2));
-
- cross = Geom::crossings(bzr1, bzr2);
- if ( cross.empty() )
- {
- //std::cout << "Oops, no crossings!" << std::endl;
- //curves didn't cross; default to miter
- /*boost::optional <Geom::Point> p = intersection_point (cbc1->finalPoint(), tang1,
- cbc2->initialPoint(), tang2);
- if (p)
- {
- path_builder.appendNew<Geom::LineSegment> (*p);
- }*/
- //bevel
- path_builder.appendNew<Geom::LineSegment>( endPt );
- }
- else
- {
- //join
- std::pair<Geom::CubicBezier, Geom::CubicBezier> sub1 = bzr1.subdivide(cross[0].ta);
- std::pair<Geom::CubicBezier, Geom::CubicBezier> sub2 = bzr2.subdivide(cross[0].tb);
-
- //@TODO joins have a strange tendency to cross themselves twice. Check this.
-
- //sections commented out are for general stability
- path_builder.appendNew <Geom::CubicBezier> (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] );
- path_builder.appendNew <Geom::CubicBezier> (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt );
- }
- }
- else // cross.empty()
- {
- //probably on the inside of the corner
- path_builder.appendNew<Geom::LineSegment> ( endPt );
- }
- }
+Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtType linecap_type,
+ LineJoinType linejoin_type, double miter_limit)
+{
+ std::vector<Geom::Path> path_out = std::vector<Geom::Path>();
+ if (path_in.empty()) {
+ return path_out;
+ }
+ Path p = Path();
+ Path outlinepath = Path();
+ for (unsigned i = 0; i < path_in.size(); i++) {
+ p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true));
+ }
- /** @brief Converts a path to one half of an outline.
- * path_in: The input path to use. (To create the other side use path_in.reverse() )
- * line_width: the line width to use (usually you want to divide this by 2)
- * linecap_type: (not used here) the cap to apply. Passed to libvarot.
- * miter_limit: the miter parameter
- */
- Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit)
- {
- Geom::PathVector pv = split_at_cusps(path_in);
- unsigned m;
- Path path_outline = Path();
- Path path_tangent = Path();
- //needed for closing the path
- Geom::Point initialPoint;
- Geom::Point endPoint;
-
- //some issues prevented me from using a PathBuilder here
- //it seems like PathBuilder::peek() gave me a null reference exception
- //and I was unable to get a stack trace on Windows, so had to switch to Linux
- //to see what the hell was wrong. :(
- //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows
-
- /*Program received signal SIGSEGV, Segmentation fault.
- 0x00000000006539ac in get_curves (this=0x0)
- at /usr/include/c++/4.6/bits/locale_facets.h:1077
- 1077 { return __c; }
- */
-
- Geom::Path path_builder = Geom::Path();
- Geom::PathVector * pathvec;
-
- //load the first portion in before the loop starts
- {
- path_outline = Path();
- path_outline.LoadPath(pv[0], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
- //now half of first cusp has been loaded
-
- pathvec = path_tangent.MakePathVector();
- path_tangent = Path();
-
- //instead of array accessing twice, dereferencing used for clarity
- initialPoint = (*pathvec)[0].initialPoint();
-
- path_builder.start(initialPoint);
- path_builder.append( (*pathvec)[0] );
-
- path_outline = Path();
- path_outline.LoadPath(pv[1], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
-
- delete pathvec; pathvec = NULL;
- pathvec = path_tangent.MakePathVector();
- path_tangent = Path();
-
- Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate();
- Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate();
-
- reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit );
-
- path_builder.append( (*pathvec)[0] );
-
- //always set pointers null after deleting
- delete pathvec; pathvec = NULL;
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
-
- for (m = 2; m < pv.size(); m++)
- {
- path_outline = Path();
- path_outline.LoadPath(pv[m], Geom::Affine(), false, false);
- path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10);
-
- delete pathvec; pathvec = NULL;
- pathvec = path_tangent.MakePathVector();
-
- Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate();
- Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate();
-
- reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit );
- path_builder.append( (*pathvec)[0] );
-
- delete pathvec; pathvec = NULL;
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
-
- return path_builder;
- }
+#define miter_lim fabs(line_width * miter_limit)
- Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim)
- {
- Path p = Path();
- Path outlinepath = Path();
- for (unsigned i = 0; i < path_in.size(); i++)
- {
- p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true));
- }
+ //magic!
+ if (linejoin_type <= 2) {
+ p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(linejoin_type),
+ linecap_type, miter_lim);
+ //fix memory leak
+ std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
+ path_out = *pv_p;
+ delete pv_p;
- Geom::PathVector path_out;
- for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++)
- {
- if (path_in[lmnop].size() > 1)
- {
- Geom::Path p_init;
- Geom::Path p_rev;
- Geom::PathBuilder pb = Geom::PathBuilder();
-
- if ( !path_in[lmnop].closed() )
- {
- p_init = Outline::half_outline( path_in[lmnop], -line_width, butt,
- miter_lim );
- p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt,
- miter_lim );
-
- pb.moveTo(p_init.initialPoint() );
- pb.append(p_init);
-
- //cap
- if (butt == butt_straight) {
- pb.lineTo(p_rev.initialPoint() );
- } else if (butt == butt_round) {
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() );
- } else if (butt == butt_square) {
- //don't know what to do
- pb.lineTo(p_rev.initialPoint() );
- } else if (butt == butt_pointy) {
- //don't know what to do
- pb.lineTo(p_rev.initialPoint() );
- }
-
- pb.append(p_rev);
-
- if (butt == butt_straight) {
- pb.lineTo(p_init.initialPoint() );
- } else if (butt == butt_round) {
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() );
- } else if (butt == butt_square) {
- //don't know what to do
- pb.lineTo(p_init.initialPoint() );
- } else if (butt == butt_pointy) {
- //don't know what to do
- //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0);
- //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint());
-
- pb.lineTo(p_init.initialPoint() );
- }
- }
- else
- {
- //final join
- //refer to half_outline for documentation
- Geom::Path p_almost = path_in[lmnop];
- p_almost.appendNew<Geom::LineSegment> ( path_in[lmnop].initialPoint() );
- p_init = Outline::half_outline( p_almost, -line_width, butt,
- miter_lim );
- p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt,
- miter_lim );
- p.LoadPath(path_in[lmnop], Geom::Affine(), false, false);
-
- //this is a kludge, because I can't find how to make this work properly
- bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(),
- path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) ==
- (path_in[lmnop] [path_in[lmnop].size()].length()));
-
- p_almost = p_init;
- if (lastIsLinear)
- {
- p_almost.erase_last(); p_almost.erase_last();
- }
-
- //outside test
- Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate();
- Geom::Curve* cbc2 = p_almost[0].duplicate();
-
- Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
-
- if (cross.empty())
- {
- //this is the outside path
-
- //reuse the old one
- p_init = p_almost;
- Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim );
- pb.moveTo(p_init.initialPoint()); pb.append(p_init);
- }
- else
- {
- //inside, carry on :-)
- pb.moveTo(p_almost.initialPoint()); pb.append(p_almost);
- }
-
- p_almost = p_rev;
- if (lastIsLinear)
- {
- p_almost.erase(p_almost.begin() );
- p_almost.erase(p_almost.begin() );
- }
-
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
-
- cbc1 = p_almost[p_almost.size() - 1].duplicate();
- cbc2 = p_almost[0].duplicate();
-
- cross = Geom::crossings(*cbc1, *cbc2);
-
- if (cross.empty())
- {
- //outside path
-
- p_init = p_almost;
- reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim );
- pb.moveTo(p_init.initialPoint()); pb.append(p_init);
- }
- else
- {
- //inside
- pb.moveTo(p_almost.initialPoint()); pb.append(p_almost);
- }
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
- //pb.closePath();
- pb.flush();
- Geom::PathVector pv_np = pb.peek();
- //hack
- for (unsigned abcd = 0; abcd < pv_np.size(); abcd++)
- {
- path_out.push_back( pv_np[abcd] );
- }
- }
- else
- {
- p.LoadPath(path_in[lmnop], Geom::Affine(), false, false);
- p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim);
- std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
- //hack
- path_out.push_back( (*pv_p)[0].reverse() );
- delete pv_p;
- }
- }
- return path_out;
- }
- Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim)
- {
- Path p = Path();
- Path outlinepath = Path();
- for (unsigned i = 0; i < path_in.size(); i++)
- {
- p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true));
- }
+ } else if (linejoin_type == 3) {
+ //reflected arc join
+ path_out = outlinePath(path_in, line_width, static_cast<LineJoinType>(linejoin_type),
+ linecap_type , miter_lim, false);
- Geom::PathVector path_out;
- for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++)
- {
- if (path_in[lmnop].size() > 1)
- {
- Geom::Path p_init;
- Geom::Path p_rev;
- Geom::PathBuilder pb = Geom::PathBuilder();
-
- if ( !path_in[lmnop].closed() )
- {
- p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt,
- miter_lim );
- p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt,
- miter_lim );
-
- pb.moveTo(p_init.initialPoint() );
- pb.append(p_init);
-
- //cap
- if (butt == butt_straight) {
- pb.lineTo(p_rev.initialPoint() );
- } else if (butt == butt_round) {
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() );
- } else if (butt == butt_square) {
- //don't know what to do
- pb.lineTo(p_rev.initialPoint() );
- } else if (butt == butt_pointy) {
- //don't know what to do
- pb.lineTo(p_rev.initialPoint() );
- }
-
- pb.append(p_rev);
-
- if (butt == butt_straight) {
- pb.lineTo(p_init.initialPoint() );
- } else if (butt == butt_round) {
- pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() );
- } else if (butt == butt_square) {
- //don't know what to do
- pb.lineTo(p_init.initialPoint() );
- } else if (butt == butt_pointy) {
- //don't know what to do
- //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0);
- //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint());
-
- pb.lineTo(p_init.initialPoint() );
- }
- }
- else
- {
- //final join
- //refer to half_outline for documentation
- Geom::Path p_almost = path_in[lmnop];
- p_almost.appendNew<Geom::LineSegment> ( path_in[lmnop].initialPoint() );
- p_init = Outline::half_outline_extrp( p_almost, -line_width, butt,
- miter_lim );
- p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt,
- miter_lim );
- p.LoadPath(path_in[lmnop], Geom::Affine(), false, false);
-
- //this is a kludge, because I can't find how to make this work properly
- bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(),
- path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) ==
- (path_in[lmnop] [path_in[lmnop].size()].length()));
-
- p_almost = p_init;
- if (lastIsLinear)
- {
- p_almost.erase_last(); p_almost.erase_last();
- }
-
- //outside test
- Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate();
- Geom::Curve* cbc2 = p_almost[0].duplicate();
-
- Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2);
-
- if (cross.empty())
- {
- //this is the outside path
-
- //reuse the old one
- p_init = p_almost;
- Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim );
- pb.moveTo(p_init.initialPoint()); pb.append(p_init);
- }
- else
- {
- //inside, carry on :-)
- pb.moveTo(p_almost.initialPoint()); pb.append(p_almost);
- }
-
- p_almost = p_rev;
- if (lastIsLinear)
- {
- p_almost.erase(p_almost.begin() );
- p_almost.erase(p_almost.begin() );
- }
-
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
-
- cbc1 = p_almost[p_almost.size() - 1].duplicate();
- cbc2 = p_almost[0].duplicate();
-
- cross = Geom::crossings(*cbc1, *cbc2);
-
- if (cross.empty())
- {
- //outside path
-
- p_init = p_almost;
- extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim );
- pb.moveTo(p_init.initialPoint()); pb.append(p_init);
- }
- else
- {
- //inside
- pb.moveTo(p_almost.initialPoint()); pb.append(p_almost);
- }
- delete cbc1; delete cbc2; cbc1 = cbc2 = NULL;
- }
- //pb.closePath();
- pb.flush();
- Geom::PathVector pv_np = pb.peek();
- //hack
- for (unsigned abcd = 0; abcd < pv_np.size(); abcd++)
- {
- path_out.push_back( pv_np[abcd] );
- }
- }
- else
- {
- p.LoadPath(path_in[lmnop], Geom::Affine(), false, false);
- p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim);
- std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
- //hack
- path_out.push_back( (*pv_p)[0].reverse() );
- delete pv_p;
- }
- }
- return path_out;
- }
-
-Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtType linecap_type,
- join_typ linejoin_type, double miter_limit)
-{
- std::vector<Geom::Path> path_out = std::vector<Geom::Path>();
- if (path_in.empty())
- {
- return path_out;
- }
- Path p = Path();
- Path outlinepath = Path();
- for (unsigned i = 0; i < path_in.size(); i++)
- {
- p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true));
- }
+ } else if (linejoin_type == 4) {
+ //extrapolated arc join
+ path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true);
- #define miter_lim fabs(line_width * miter_limit)
+ }
- //magic!
- if (linejoin_type <= 2)
- {
- p.Outline(&outlinepath, line_width / 2, linejoin_type,
- linecap_type, miter_lim);
- //fix memory leak
- std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
- path_out = *pv_p;
- delete pv_p;
-
- } else if (linejoin_type == 3) {
- //reflected arc join
- path_out = outlinePath(path_in, line_width, linejoin_type,
- linecap_type , miter_lim);
-
- } else if (linejoin_type == 4) {
- //extrapolated arc join
- path_out = outlinePath_extr(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim);
-
- }
-
- #undef miter_lim
- return path_out;
+#undef miter_lim
+ return path_out;
}
+
Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit)
{
- #define miter_lim fabs(line_width * miter_limit)
-
+#define miter_lim fabs(line_width * miter_limit)
+
Geom::Path path_out;
if (linejoin_type <= LINEJOIN_POINTY || path_in.size() <= 1) {
-
+
Geom::PathVector * pathvec;
-
+
Path path_tangent = Path();
Path path_outline = Path();
path_outline.LoadPath(path_in, Geom::Affine(), false, false);
path_outline.OutsideOutline(&path_tangent, line_width / 2, static_cast<join_typ>(linejoin_type), butt_straight, miter_lim);
-
+
pathvec = path_tangent.MakePathVector();
path_out = pathvec[0]/* deref pointer */[0]/*actual object ref*/;
delete pathvec;
return path_out;
- }
- else if (linejoin_type == LINEJOIN_REFLECTED) {
+ } else if (linejoin_type == LINEJOIN_REFLECTED) {
//reflected half outline
- Geom::PathVector pathvec; pathvec.push_back(path_in);
- path_out = half_outline(path_in, line_width, butt_straight, miter_lim);
+ Geom::PathVector pathvec;
+ pathvec.push_back(path_in);
+ path_out = doAdvHalfOutline(path_in, line_width, miter_lim, false);
return path_out;
- }
- else if (linejoin_type == LINEJOIN_EXTRAPOLATED) {
- path_out = half_outline_extrp(path_in, line_width, butt_straight, miter_lim);
+ } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) {
+ //what the hell do you think this is? :P
+ path_out = doAdvHalfOutline(path_in, line_width, miter_lim, true);
return path_out;
}
+#undef miter_lim
return path_out;
}
diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 4133f47c2..23cc7e2c4 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -16,10 +16,10 @@ namespace Outline { unsigned bezierOrder (const Geom::Curve* curve_in); std::vector<Geom::Path> PathVectorOutline(std::vector<Geom::Path> const & path_in, double line_width, ButtType linecap_type, - join_typ linejoin_type, double miter_limit); + LineJoinType linejoin_type, double miter_limit); - Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim); - Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim); + Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, + ButtType butt, double miter_lim, bool extrapolate = false); Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); } diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 82e65435d..2d4755fd2 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -53,10 +53,10 @@ /* XPM */ static char const * core_xpm[] = { "16 16 4 1", -" c None", -". c #808080", -"+ c #000000", -"@ c #FFFFFF", +" c None", +". c #808080", +"+ c #000000", +"@ c #FFFFFF", " ", " ", " ", @@ -291,9 +291,9 @@ static char const *button_on[] = { /* XPM */ static char const * axis_none_xpm[] = { "24 8 3 1", -" c None", -". c #000000", -"+ c #808080", +" c None", +". c #000000", +"+ c #808080", " ", " .++++++++++++++++++. ", " .+ . .+. ", @@ -305,10 +305,10 @@ static char const * axis_none_xpm[] = { /* XPM */ static char const * axis_off_xpm[] = { "24 8 4 1", -" c None", -". c #808080", -"+ c #000000", -"@ c #FFFFFF", +" c None", +". c #808080", +"+ c #000000", +"@ c #FFFFFF", " ", " .++++++++++++++++++. ", " .+@@@@@@@@@@@@@@@@@@+. ", @@ -320,9 +320,9 @@ static char const * axis_off_xpm[] = { /* XPM */ static char const * axis_on_xpm[] = { "24 8 3 1", -" c None", -". c #000000", -"+ c #00FF00", +" c None", +". c #000000", +"+ c #00FF00", " ", " .................... ", " ..++++++++++++++++++.. ", @@ -1707,9 +1707,9 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) axesValues[i].set_sensitive(true); if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) { // FIXME: Device axis ranges are inaccessible in GTK+ 3 and - // are deprecated in GTK+ 2. Progress-bar ranges are disabled - // until we find an alternative solution - + // are deprecated in GTK+ 2. Progress-bar ranges are disabled + // until we find an alternative solution + // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { axesValues[i].set_sensitive(true); // axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) ); @@ -1726,10 +1726,10 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) { // FIXME: Device axis ranges are inaccessible in GTK+ 3 and - // are deprecated in GTK+ 2. Progress-bar ranges are disabled - // until we find an alternative solution + // are deprecated in GTK+ 2. Progress-bar ranges are disabled + // until we find an alternative solution - // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { + // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { axesValues[i].set_sensitive(true); // axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) ); // } @@ -1860,8 +1860,8 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) GdkEventButton* btnEvt = reinterpret_cast<GdkEventButton*>(event); if ( btnEvt->device ) { key = getKeyFor(btnEvt->device); - source = gdk_device_get_source(btnEvt->device); - devName = gdk_device_get_name(btnEvt->device); + source = gdk_device_get_source(btnEvt->device); + devName = gdk_device_get_name(btnEvt->device); mapAxesValues(key, btnEvt->axes, btnEvt->device); if ( buttonMap[key].find(btnEvt->button) == buttonMap[key].end() ) { @@ -1889,8 +1889,8 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) GdkEventMotion* btnMtn = reinterpret_cast<GdkEventMotion*>(event); if ( btnMtn->device ) { key = getKeyFor(btnMtn->device); - source = gdk_device_get_source(btnMtn->device); - devName = gdk_device_get_name(btnMtn->device); + source = gdk_device_get_source(btnMtn->device); + devName = gdk_device_get_name(btnMtn->device); mapAxesValues(key, btnMtn->axes, btnMtn->device); } gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnMtn->state)); @@ -1915,19 +1915,16 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) if ( (lastSourceSeen != source) || (lastDevnameSeen != devName) ) { switch (source) { - case GDK_SOURCE_MOUSE: - { + case GDK_SOURCE_MOUSE: { testThumb.set(getPix(PIX_CORE)); + break; } - break; - case GDK_SOURCE_CURSOR: - { -// g_message("flip to cursor"); + case GDK_SOURCE_CURSOR: { +// g_message("flip to cursor"); testThumb.set(getPix(PIX_MOUSE)); + break; } - break; - case GDK_SOURCE_PEN: - { + case GDK_SOURCE_PEN: { if (devName == _("pad")) { // g_message("flip to pad"); testThumb.set(getPix(PIX_SIDEBUTTONS)); @@ -1935,17 +1932,24 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) // g_message("flip to pen"); testThumb.set(getPix(PIX_TIP)); } + break; } - break; - case GDK_SOURCE_ERASER: - { + case GDK_SOURCE_ERASER: { // g_message("flip to eraser"); testThumb.set(getPix(PIX_ERASER)); + break; } - break; -// default: -// g_message("gurgle"); +#if WITH_GTKMM_3_0 + /// \fixme GTK3 added new GDK_SOURCEs that should be handled here! + case GDK_SOURCE_KEYBOARD: + case GDK_SOURCE_TOUCHSCREEN: + case GDK_SOURCE_TOUCHPAD: { + g_warning("InputDialogImpl::eventSnoop : unhandled GDK_SOURCE type!"); + break; + } +#endif } + updateTestButtons(key, hotButton); lastSourceSeen = source; lastDevnameSeen = devName; diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index b5ee0a597..d10ed0f0d 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -194,6 +194,8 @@ void ControlPointSelection::align(Geom::Dim2 axis) bound.unionWith(Geom::OptInterval((*i)->position()[d])); } + if (!bound) { return; } + double new_coord = bound->middle(); for (iterator i = _points.begin(); i != _points.end(); ++i) { Geom::Point pos = (*i)->position(); @@ -220,6 +222,8 @@ void ControlPointSelection::distribute(Geom::Dim2 d) bound.unionWith(Geom::OptInterval(pos[d])); } + if (!bound) { return; } + // now we iterate over the multimap and set aligned positions. double step = size() == 1 ? 0 : bound->extent() / (size() - 1); double start = bound->min(); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e246bf997..fbbc4be64 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1217,6 +1217,7 @@ Handle *Node::handleToward(Node *to) return back(); } g_error("Node::handleToward(): second node is not adjacent!"); + return NULL; } Node *Node::nodeToward(Handle *dir) @@ -1228,6 +1229,7 @@ Node *Node::nodeToward(Handle *dir) return _prev(); } g_error("Node::nodeToward(): handle is not a child of this node!"); + return NULL; } Handle *Node::handleAwayFrom(Node *to) @@ -1239,6 +1241,7 @@ Handle *Node::handleAwayFrom(Node *to) return front(); } g_error("Node::handleAwayFrom(): second node is not adjacent!"); + return NULL; } Node *Node::nodeAwayFrom(Handle *h) @@ -1250,6 +1253,7 @@ Node *Node::nodeAwayFrom(Handle *h) return _next(); } g_error("Node::nodeAwayFrom(): handle is not a child of this node!"); + return NULL; } Glib::ustring Node::_getTip(unsigned state) const diff --git a/src/winmain.cpp b/src/winmain.cpp index 607660740..5120e44e0 100644 --- a/src/winmain.cpp +++ b/src/winmain.cpp @@ -11,7 +11,12 @@ #include <stdio.h> #include <io.h> #include <conio.h> -#define _WIN32_WINNT 0x0501 + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0501 +#endif + #include <windows.h> extern int main (int argc, char **argv); |
