diff options
| author | Jabiertxof <jtx@jtx> | 2017-03-16 19:08:44 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx> | 2017-03-16 19:08:44 +0000 |
| commit | 8330d0ef2b97c73121ead78ea9fbcec6ee01f879 (patch) | |
| tree | 1b1717d1706ee6ebfecc800f2cc80430eb0450e0 /src/display | |
| parent | update to trunk (diff) | |
| parent | Fix rendering when canvas rotated. General code clean-up and documentation. (diff) | |
| download | inkscape-8330d0ef2b97c73121ead78ea9fbcec6ee01f879.tar.gz inkscape-8330d0ef2b97c73121ead78ea9fbcec6ee01f879.zip | |
Update to trunk
(bzr r13645.1.170)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/canvas-axonomgrid.cpp | 1 | ||||
| -rw-r--r-- | src/display/canvas-grid.cpp | 4 | ||||
| -rw-r--r-- | src/display/guideline.cpp | 104 | ||||
| -rw-r--r-- | src/display/nr-filter-turbulence.cpp | 12 | ||||
| -rw-r--r-- | src/display/nr-filter-utils.h | 2 | ||||
| -rw-r--r-- | src/display/nr-filter.cpp | 5 | ||||
| -rw-r--r-- | src/display/sp-canvas.cpp | 44 | ||||
| -rw-r--r-- | src/display/sp-canvas.h | 4 |
8 files changed, 89 insertions, 87 deletions
diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 94ee4ccfd..589cc849d 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -42,7 +42,6 @@ #include "2geom/line.h" #include "2geom/angle.h" #include "helper/mathfns.h" -#include "round.h" #include "util/units.h" using Inkscape::Util::unit_table; diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index cf7d04555..2dadde336 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -841,7 +841,9 @@ void CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/) { ow = origin * affine; - sw = spacing * affine; + // Temp hack to insure grid doesn't collapse with rotation. + sw[0] = spacing[0] * sqrt(affine[0]*affine[0] + affine[1]*affine[1]); + sw[1] = spacing[1] * sqrt(affine[2]*affine[2] + affine[3]*affine[3]); sw -= Geom::Point(affine[4], affine[5]); for(int dim = 0; dim < 2; dim++) { diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index f66b65e1a..cde10f6c2 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -10,12 +10,15 @@ * Copyright (C) 2000-2002 Lauris Kaplinski * Copyright (C) 2007 Johan Engelen * Copyright (C) 2009 Maximilian Albert + * Copyright (C) 2017 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ #include <2geom/coord.h> #include <2geom/transforms.h> +#include <2geom/line.h> + #include "sp-canvas-util.h" #include "guideline.h" #include "display/cairo-utils.h" @@ -29,8 +32,6 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf); static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); - G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); static void sp_guideline_class_init(SPGuideLineClass *c) @@ -76,10 +77,6 @@ static void sp_guideline_destroy(SPCanvasItem *object) static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) { - //TODO: the routine that renders the label of a specific guideline sometimes - // ends up erasing the labels of the other guidelines. - // Maybe we should render all labels everytime. - SPGuideLine const *gl = SP_GUIDELINE (item); cairo_save(buf->ct); @@ -89,8 +86,9 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE); cairo_set_font_size(buf->ct, 10); - Geom::Point normal_dt = /*unit_vector*/(gl->normal_to_line * gl->affine.withoutTranslation()); // note that normal_dt does not have unit length - Geom::Point point_on_line_dt = gl->point_on_line * gl->affine; + // normal_dt does not have unit length + Geom::Point normal_dt = gl->normal_to_line * gl->affine.withoutTranslation(); + Geom::Point point_on_line_dt = gl->point_on_line * gl->affine; if (gl->label) { int px = round(point_on_line_dt[Geom::X]); @@ -104,55 +102,54 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) cairo_restore(buf->ct); } - if ( Geom::are_near(normal_dt[Geom::Y], 0.) ) { // is vertical? + // Draw guide. + // Special case horizontal and vertical lines so they snap to pixels. + // Don't use isHorizontal()/isVertical() as they test only exact matches. + if ( Geom::are_near(normal_dt[Geom::Y], 0.0) ) { // Vertical? + int position = round(point_on_line_dt[Geom::X]); cairo_move_to(buf->ct, position + 0.5, buf->rect.top() + 0.5); cairo_line_to(buf->ct, position + 0.5, buf->rect.bottom() - 0.5); cairo_stroke(buf->ct); - } else if ( Geom::are_near(normal_dt[Geom::X], 0.) ) { // is horizontal? + + } else if ( Geom::are_near(normal_dt[Geom::X], 0.0) ) { // Horizontal? + int position = round(point_on_line_dt[Geom::Y]); cairo_move_to(buf->ct, buf->rect.left() + 0.5, position + 0.5); cairo_line_to(buf->ct, buf->rect.right() - 0.5, position + 0.5); cairo_stroke(buf->ct); - } else { - // render angled line. Once intersection has been detected, draw from there. - Geom::Point parallel_to_line( normal_dt.ccw() ); - - //try to intersect with left vertical of rect - double y_intersect_left = (buf->rect.left() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - if ( (y_intersect_left >= buf->rect.top()) && (y_intersect_left <= buf->rect.bottom()) ) { - // intersects with left vertical! - double y_intersect_right = (buf->rect.right() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - sp_guideline_drawline (buf, buf->rect.left(), static_cast<gint>(round(y_intersect_left)), buf->rect.right(), static_cast<gint>(round(y_intersect_right)), gl->rgba); - goto end; - } - //try to intersect with right vertical of rect - double y_intersect_right = (buf->rect.right() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - if ( (y_intersect_right >= buf->rect.top()) && (y_intersect_right <= buf->rect.bottom()) ) { - // intersects with right vertical! - sp_guideline_drawline (buf, buf->rect.right(), static_cast<gint>(round(y_intersect_right)), buf->rect.left(), static_cast<gint>(round(y_intersect_left)), gl->rgba); - goto end; - } + } else { - //try to intersect with top horizontal of rect - double x_intersect_top = (buf->rect.top() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - if ( (x_intersect_top >= buf->rect.left()) && (x_intersect_top <= buf->rect.right()) ) { - // intersects with top horizontal! - double x_intersect_bottom = (buf->rect.bottom() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_top)), buf->rect.top(), static_cast<gint>(round(x_intersect_bottom)), buf->rect.bottom(), gl->rgba); - goto end; + Geom::Line guide = + Geom::Line::from_origin_and_vector( point_on_line_dt, Geom::rot90(normal_dt) ); + + // Find intersections of guide with buf rectangle. There should be zero or two. + std::vector<Geom::Point> intersections; + for (unsigned i = 0; i < 4; ++i) { + Geom::LineSegment side( buf->rect.corner(i), buf->rect.corner((i+1)%4) ); + try { + Geom::OptCrossing oc = Geom::intersection(guide, side); + if (oc) { + intersections.push_back( guide.pointAt((*oc).ta)); + } + } catch (Geom::InfiniteSolutions) { + // Shouldn't happen as we have already taken care of horizontal/vertical guides. + std::cerr << "sp_guideline_render: Error: Infinite intersections." << std::endl; + } } - //try to intersect with bottom horizontal of rect - double x_intersect_bottom = (buf->rect.bottom() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - if ( (x_intersect_top >= buf->rect.left()) && (x_intersect_top <= buf->rect.right()) ) { - // intersects with bottom horizontal! - sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_bottom)), buf->rect.bottom(), static_cast<gint>(round(x_intersect_top)), buf->rect.top(), gl->rgba); - goto end; + if (intersections.size() == 2) { + double x0 = intersections[0][Geom::X]; + double x1 = intersections[1][Geom::X]; + double y0 = intersections[0][Geom::Y]; + double y1 = intersections[1][Geom::Y]; + cairo_move_to(buf->ct, x0, y0); + cairo_line_to(buf->ct, x1, y1); + cairo_stroke(buf->ct); } } - end: + cairo_restore(buf->ct); } @@ -179,15 +176,10 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, } gl->affine = affine; - Geom::Point pol_transformed = gl->point_on_line * affine; - if (gl->is_horizontal()) { - sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1)); - } else if (gl->is_vertical()) { - sp_canvas_update_bbox (item, round(pol_transformed[Geom::X]), -1000000, round(pol_transformed[Geom::X] + 16), 1000000); - } else { - //TODO: labels in angled guidelines are not showing up for some reason. - sp_canvas_update_bbox (item, -1000000, -1000000, 1000000, 1000000); - } + + // Rotated canvas requires large bbox for all guides. + sp_canvas_update_bbox (item, -1000000, -1000000, 1000000, 1000000); + } // Returns 0.0 if point is on the guideline @@ -276,14 +268,6 @@ void sp_guideline_delete(SPGuideLine *gl) sp_canvas_item_destroy(SP_CANVAS_ITEM(gl)); } -static void -sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 /*rgba*/) -{ - cairo_move_to(buf->ct, x0 + 0.5, y0 + 0.5); - cairo_line_to(buf->ct, x1 + 0.5, y1 + 0.5); - cairo_stroke(buf->ct); -} - /* Local Variables: mode:c++ diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index 19dedb67c..1397c0f34 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -286,15 +286,7 @@ private: static int const BSize = 0x100; static int const BMask = 0xff; -#ifdef CPP11 // GCC 4.6.1 (currently used on Windows) does not correctly set __cplusplus in C++11 mode, so configure with -DCPP11 to make this work in C++11 mode static double constexpr PerlinOffset = 4096.0; -#else -#if (__cplusplus < 201103L) - static double const PerlinOffset; -#else - static double constexpr PerlinOffset = 4096.0; -#endif -#endif Geom::Rect _tile; Geom::Point _baseFreq; @@ -311,10 +303,6 @@ private: bool _fractalnoise; }; -#if !defined(CPP11) && __cplusplus < 201103L - double const TurbulenceGenerator::PerlinOffset = 4096.0; -#endif - FilterTurbulence::FilterTurbulence() : gen(new TurbulenceGenerator()) , XbaseFrequency(0) diff --git a/src/display/nr-filter-utils.h b/src/display/nr-filter-utils.h index 35a74d7c1..52b6bd11a 100644 --- a/src/display/nr-filter-utils.h +++ b/src/display/nr-filter-utils.h @@ -14,8 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "round.h" - namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 789758d9c..d430553d4 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -48,11 +48,6 @@ #include "sp-filter-units.h" #include "preferences.h" -#if defined (SOLARIS) && (SOLARIS == 8) -#include "round.h" -using Inkscape::round; -#endif - namespace Inkscape { namespace Filters { diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 68eae0a65..61602e880 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -48,6 +48,10 @@ #include <iomanip> #include <glibmm/i18n.h> +#if GTK_CHECK_VERSION(3,20,0) +# include <gdkmm/seat.h> +#endif + using Inkscape::Debug::GdkEventLatencyTracker; // gtk_check_version returns non-NULL on failure @@ -72,9 +76,15 @@ struct SPCanvasGroupClass { static void ungrab_default_client_pointer(guint32 const time = GDK_CURRENT_TIME) { auto const display = Gdk::Display::get_default(); + +#if GTK_CHECK_VERSION(3,20,0) + auto const seat = display->get_default_seat(); + seat->ungrab(); +#else auto const dm = display->get_device_manager(); auto const device = dm->get_client_pointer(); device->ungrab(time); +#endif } /** @@ -625,9 +635,22 @@ int sp_canvas_item_grab(SPCanvasItem *item, guint event_mask, GdkCursor *cursor, // fixme: Top hack (Lauris) // fixme: If we add key masks to event mask, Gdk will abort (Lauris) - // fixme: But Canvas actualle does get key events, so all we need is routing these here - auto dm = gdk_display_get_device_manager(gdk_display_get_default()); + // fixme: But Canvas actually does get key events, so all we need is routing these here + auto display = gdk_display_get_default(); +#if GTK_CHECK_VERSION(3,20,0) + auto seat = gdk_display_get_default_seat(display); + gdk_seat_grab(seat, + getWindow(item->canvas), + GDK_SEAT_CAPABILITY_ALL_POINTING, + FALSE, + cursor, + NULL, + NULL, + NULL); +#else + auto dm = gdk_display_get_device_manager(display); auto device = gdk_device_manager_get_client_pointer(dm); + gdk_device_grab(device, getWindow(item->canvas), GDK_OWNERSHIP_NONE, @@ -635,6 +658,7 @@ int sp_canvas_item_grab(SPCanvasItem *item, guint event_mask, GdkCursor *cursor, (GdkEventMask)(event_mask & (~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))), cursor, etime); +#endif item->canvas->_grabbed_item = item; item->canvas->_grabbed_event_mask = event_mask; @@ -1034,7 +1058,7 @@ void SPCanvas::handle_realize(GtkWidget *widget) attributes.width = allocation.width; attributes.height = allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gdk_visual_get_system(); + attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default()); attributes.event_mask = (gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | @@ -1694,8 +1718,14 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1) gint x, y; auto const display = Gdk::Display::get_default(); + +#if GTK_CHECK_VERSION(3,20,0) + auto const seat = display->get_default_seat(); + auto const device = seat->get_pointer(); +#else auto const dm = display->get_device_manager(); auto const device = dm->get_client_pointer(); +#endif gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(this)), device->gobj(), @@ -1907,10 +1937,16 @@ double start_angle = 0; bool started = false; bool rotated = false; -void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling) +/** + * Scroll screen to point 'c'. 'c' is measured in screen pixels. + */ +void SPCanvas::scrollTo( Geom::Point const &c, unsigned int clear, bool is_scrolling) { GtkAllocation allocation; + double cx = c[Geom::X]; + double cy = c[Geom::Y]; + int ix = (int) round(cx); // ix and iy are the new canvas coordinates (integer screen pixels) int iy = (int) round(cy); // cx might be negative, so (int)(cx + 0.5) will not do! int dx = ix - _x0; // dx and dy specify the displacement (scroll) of the diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 21b6760f2..708653bdf 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -70,8 +70,8 @@ GType sp_canvas_get_type() G_GNUC_CONST; * Port of GnomeCanvas for inkscape needs. */ struct SPCanvas { - /// Scrolls canvas to specific position (cx and cy are measured in screen pixels). - void scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling = false); + /// Scrolls canvas to specific position (c is measured in screen pixels). + void scrollTo(Geom::Point const &c, unsigned int clear, bool is_scrolling = false); void startRotateTo(double angle); void rotateTo(double angle); bool endRotateTo(); |
