summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJabiertxof <jtx@jtx>2017-03-16 19:08:44 +0000
committerJabiertxof <jtx@jtx>2017-03-16 19:08:44 +0000
commit8330d0ef2b97c73121ead78ea9fbcec6ee01f879 (patch)
tree1b1717d1706ee6ebfecc800f2cc80430eb0450e0 /src/display
parentupdate to trunk (diff)
parentFix rendering when canvas rotated. General code clean-up and documentation. (diff)
downloadinkscape-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.cpp1
-rw-r--r--src/display/canvas-grid.cpp4
-rw-r--r--src/display/guideline.cpp104
-rw-r--r--src/display/nr-filter-turbulence.cpp12
-rw-r--r--src/display/nr-filter-utils.h2
-rw-r--r--src/display/nr-filter.cpp5
-rw-r--r--src/display/sp-canvas.cpp44
-rw-r--r--src/display/sp-canvas.h4
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();