summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiederik van Lierop <mail@diedenrezi.nl>2019-04-30 20:40:22 +0000
committerDiederik van Lierop <mail@diedenrezi.nl>2019-04-30 20:40:22 +0000
commit2713ccbc67cb10c169fa84b3641d1747c00a5790 (patch)
treec19639f3fa62907a408841b22a01227ab3f10748
parentUpdate macOS build pipeline (diff)
downloadinkscape-2713ccbc67cb10c169fa84b3641d1747c00a5790.tar.gz
inkscape-2713ccbc67cb10c169fa84b3641d1747c00a5790.zip
Fix disappearing and antialiasing of grid lines
-rw-r--r--src/display/canvas-axonomgrid.cpp4
-rw-r--r--src/display/canvas-grid.cpp17
2 files changed, 14 insertions, 7 deletions
diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp
index 2e4a20d6a..9f423b2ab 100644
--- a/src/display/canvas-axonomgrid.cpp
+++ b/src/display/canvas-axonomgrid.cpp
@@ -529,7 +529,9 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf)
gint const ylinestart = round((ystart_x_sc - ow[Geom::X]) / spacing_ylines);
gint ylinenum = ylinestart;
for (gdouble x = ystart_x_sc; x < buf->rect.right(); x += spacing_ylines, ylinenum++) {
- gint const x0 = round(x);
+ gint const x0 = floor(x); // sp_grid_vline will add 0.5 again, so we'll pre-emptively use floor()
+ // instead of round() to avoid biasing the vertical lines to the right by half a pixel; see
+ // CanvasXYGrid::Render() for more details
if (!scaled && (ylinenum % empspacing) != 0) {
sp_grid_vline (buf, x0, buf->rect.top(), buf->rect.bottom() - 1, _color);
diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp
index f4a210fe6..60d51de2e 100644
--- a/src/display/canvas-grid.cpp
+++ b/src/display/canvas-grid.cpp
@@ -911,6 +911,10 @@ CanvasXYGrid::Render (SPCanvasBuf *buf)
cairo_set_line_width(buf->ct, 1.0);
cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE);
+ // Adding a 2 px margin to the buffer rectangle to avoid missing intersections (in case of rounding errors, and due to adding 0.5 below)
+ Geom::IntRect buf_rect_with_margin = buf->rect;
+ buf_rect_with_margin.expandBy(2);
+
for (unsigned dim = 0; dim < 2; ++dim) {
// std::cout << "\n " << (dim==0?"Horizontal":"Vertical") << " ------------" << std::endl;
@@ -932,7 +936,7 @@ CanvasXYGrid::Render (SPCanvasBuf *buf)
for (unsigned c = 0; c < 4; ++c) {
// We need signed distance... lib2geom offers only positive distance.
- double distance = signed_distance( buf->rect.corner(c), axis );
+ double distance = signed_distance( buf_rect_with_margin.corner(c), axis );
// Correct it for coordinate flips (inverts handedness).
if (Geom::cross( axis.vector(), orth.vector() ) > 0 ) {
@@ -956,7 +960,7 @@ CanvasXYGrid::Render (SPCanvasBuf *buf)
Geom::Line grid_line = Geom::make_parallel_line( ow + j * sw[(dim+1)%2], axis );
- std::vector<Geom::Point> x = intersect_line_rectangle( grid_line, buf->rect );
+ std::vector<Geom::Point> x = intersect_line_rectangle( grid_line, buf_rect_with_margin );
// If we have two intersections, grid line intersects buffer rectangle.
if (x.size() == 2 ) {
@@ -967,10 +971,11 @@ CanvasXYGrid::Render (SPCanvasBuf *buf)
std::swap(x[0], x[1]);
}
- // Set up line.
- cairo_move_to(buf->ct, x[0][Geom::X] + 0.5, x[0][Geom::Y] + 0.5);
- cairo_line_to(buf->ct, x[1][Geom::X] + 0.5, x[1][Geom::Y] + 0.5);
-
+ // Set up line. Need to use floor()+0.5 such that Cairo will draw us lines with a width of a single pixel, without any aliasing.
+ // For this we need to position the lines at exactly half pixels, see https://www.cairographics.org/FAQ/#sharp_lines
+ cairo_move_to(buf->ct, floor(x[0][Geom::X]) + 0.5, floor(x[0][Geom::Y]) + 0.5);
+ cairo_line_to(buf->ct, floor(x[1][Geom::X]) + 0.5, floor(x[1][Geom::Y]) + 0.5);
+
// Set dash pattern and color.
if (render_dotted) {
// alpha needs to be larger than in the line case to maintain a similar