mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-11 00:56:33 +01:00
simplify cairo pixel alignment in Canvas::LineSet
1. do the math when we add a new coord, not at every render call 2. correctly decide whether to force an odd-width line on an integer coordinate to a half pixel, or an even-width line on a non-integer coordinate to a whole pixel.
This commit is contained in:
parent
705fe2b52d
commit
ae913acacf
1 changed files with 31 additions and 20 deletions
|
|
@ -101,21 +101,18 @@ LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||||
for (auto const & l : _lines) {
|
for (auto const & l : _lines) {
|
||||||
|
|
||||||
Rect self;
|
Rect self;
|
||||||
const double shift = 0.5;
|
|
||||||
|
|
||||||
if (_orientation == Horizontal) {
|
if (_orientation == Horizontal) {
|
||||||
self = Rect (0, l.pos - (l.width/2.0), _extent, l.pos + (l.width/2.0));
|
self = Rect (0, l.pos - (l.width/2.0), _extent, l.pos + (l.width/2.0));
|
||||||
if (fmod (l.width, 2.)) {
|
|
||||||
self.y0 += shift;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self = Rect (l.pos - (l.width/2.0), 0, l.pos + (l.width/2.0), _extent);
|
self = Rect (l.pos - (l.width/2.0), 0, l.pos + (l.width/2.0), _extent);
|
||||||
if (fmod (l.width, 2.)) {
|
|
||||||
self.x0 += shift;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self = item_to_window (self);
|
/* Note the 2nd argument, to avoid rounding after we may have
|
||||||
|
* just shifted to a half-pixel grid (see
|
||||||
|
* doc/cairo-single-pixel-lines)
|
||||||
|
*/
|
||||||
|
self = item_to_window (self, false);
|
||||||
Rect intersection = self.intersection (area);
|
Rect intersection = self.intersection (area);
|
||||||
|
|
||||||
if (!intersection) {
|
if (!intersection) {
|
||||||
|
|
@ -125,20 +122,12 @@ LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||||
Gtkmm2ext::set_source_rgba (context, l.color);
|
Gtkmm2ext::set_source_rgba (context, l.color);
|
||||||
context->set_line_width (l.width);
|
context->set_line_width (l.width);
|
||||||
|
|
||||||
/* Not 100% sure that the computation of the invariant
|
|
||||||
* positions (y and x) below work correctly if the line width
|
|
||||||
* is not 1.0, but visual inspection suggests it is OK.
|
|
||||||
* See doc/cairo-single-pixel-lines lines to understand why we add 0.5
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_orientation == Horizontal) {
|
if (_orientation == Horizontal) {
|
||||||
const double y = item_to_window (Duple (0, l.pos)).y;
|
context->move_to (intersection.x0, self.y0);
|
||||||
context->move_to (intersection.x0, y + shift);
|
context->line_to (intersection.x1, self.y0);
|
||||||
context->line_to (intersection.x1, y + shift);
|
|
||||||
} else {
|
} else {
|
||||||
const double x = item_to_window (Duple (l.pos, 0)).x;
|
context->move_to (self.x0, intersection.y0);
|
||||||
context->move_to (x + shift, intersection.y0);
|
context->line_to (self.x0, intersection.y1);
|
||||||
context->line_to (x + shift, intersection.y1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context->stroke ();
|
context->stroke ();
|
||||||
|
|
@ -149,6 +138,28 @@ void
|
||||||
LineSet::add_coord (Coord pos, Distance width, Gtkmm2ext::Color color)
|
LineSet::add_coord (Coord pos, Distance width, Gtkmm2ext::Color color)
|
||||||
{
|
{
|
||||||
_lines.push_back (Line (pos, width, color));
|
_lines.push_back (Line (pos, width, color));
|
||||||
|
Line& l (_lines.back());
|
||||||
|
|
||||||
|
if (_orientation == Horizontal) {
|
||||||
|
/* If width is odd (width % 2 != 0) and position is on
|
||||||
|
a whole pixel, shift it to a half-pixel position. Otherwise
|
||||||
|
force it back to an integer position. See
|
||||||
|
doc/cairo-single-pixel-lines for more details.
|
||||||
|
*/
|
||||||
|
if (fmod (l.width, 2.) && fmod (l.pos, 1.0)) {
|
||||||
|
l.pos += 0.5;
|
||||||
|
} else {
|
||||||
|
l.pos = floor (l.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (fmod (l.width, 2.) && fmod (l.pos, 1.0)) {
|
||||||
|
l.pos += 0.5;
|
||||||
|
} else {
|
||||||
|
l.pos = floor (l.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue