fix rect redraw problems caused by intersection requiring the usual 0.5 expansion (though consider a more general fix for this at teh group level)
This commit is contained in:
parent
77f5f4c4bf
commit
691be68ac2
@ -227,7 +227,7 @@ void
|
||||
Canvas::queue_draw_item_area (Item* item, Rect area)
|
||||
{
|
||||
ArdourCanvas::Rect canvas_area = item->item_to_canvas (area);
|
||||
// cerr << "CANVAS Invalidate " << area << " TRANSLATE AS " << canvas_area << endl;
|
||||
// cerr << "CANVAS " << this << " for " << item->whatami() << ' ' << item->name << " invalidate " << area << " TRANSLATE AS " << canvas_area << endl;
|
||||
request_redraw (canvas_area);
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ void
|
||||
GtkCanvas::request_redraw (Rect const & request)
|
||||
{
|
||||
Rect area = canvas_to_window (request);
|
||||
// cerr << "Invalidate " << request << " TRANSLATE AS " << area << endl;
|
||||
// cerr << this << " Invalidate " << request << " TRANSLATE AS " << area << endl;
|
||||
queue_draw_area (floor (area.x0), floor (area.y0), ceil (area.x1) - floor (area.x0), ceil (area.y1) - floor (area.y0));
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,10 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||
(*i)->name);
|
||||
}
|
||||
#endif
|
||||
(*i)->render (draw.get(), context);
|
||||
|
||||
(*i)->render (area, context);
|
||||
++render_count;
|
||||
|
||||
} else {
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
|
||||
|
@ -52,19 +52,26 @@ Rectangle::Rectangle (Group* parent, Rect const & rect)
|
||||
void
|
||||
Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||
{
|
||||
/* Cairo goes a little (!) wrong when asked to fill/stroke rectangles that
|
||||
* extend way beyond the surface boundaries. To avoid this issue,
|
||||
* clamp what we are drawing using the absolute end of the visible
|
||||
* canvas, converting to item-space coordinates, of course.
|
||||
*/
|
||||
|
||||
Rect self = item_to_window (_rect);
|
||||
boost::optional<Rect> draw = self.intersection (area);
|
||||
boost::optional<Rect> d = self.intersection (area);
|
||||
|
||||
if (_fill && draw) {
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rect draw = d.get();
|
||||
static const double boundary = 0.5;
|
||||
|
||||
draw.x0 = max (self.x0, max (0.0, draw.x0 - boundary));
|
||||
draw.x1 = min (self.x1, min (2000.0, draw.x1 + boundary));
|
||||
|
||||
draw.y0 = max (self.y0, max (0.0, draw.y0 - boundary));
|
||||
draw.y1 = min (self.y1, min (2000.0, draw.y1 + boundary));
|
||||
|
||||
if (_fill) {
|
||||
setup_fill_context (context);
|
||||
|
||||
context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
|
||||
context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
|
||||
|
||||
if (!_outline) {
|
||||
context->fill ();
|
||||
@ -96,30 +103,30 @@ Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) con
|
||||
*/
|
||||
|
||||
if (!_fill) {
|
||||
context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
|
||||
context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
|
||||
context->stroke ();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (_outline_what & LEFT) {
|
||||
context->move_to (draw->x0, draw->y0);
|
||||
context->line_to (draw->x0, draw->y1);
|
||||
context->move_to (draw.x0, draw.y0);
|
||||
context->line_to (draw.x0, draw.y1);
|
||||
}
|
||||
|
||||
if (_outline_what & BOTTOM) {
|
||||
context->move_to (draw->x0, draw->y1);
|
||||
context->line_to (draw->x1, draw->y1);
|
||||
context->move_to (draw.x0, draw.y1);
|
||||
context->line_to (draw.x1, draw.y1);
|
||||
}
|
||||
|
||||
if (_outline_what & RIGHT) {
|
||||
context->move_to (draw->x1, draw->y0);
|
||||
context->line_to (draw->x1, draw->y1);
|
||||
context->move_to (draw.x1, draw.y0);
|
||||
context->line_to (draw.x1, draw.y1);
|
||||
}
|
||||
|
||||
if (_outline_what & TOP) {
|
||||
context->move_to (draw->x0, draw->y0);
|
||||
context->line_to (draw->x1, draw->y0);
|
||||
context->move_to (draw.x0, draw.y0);
|
||||
context->line_to (draw.x1, draw.y0);
|
||||
}
|
||||
|
||||
context->stroke ();
|
||||
|
@ -96,11 +96,26 @@ Text::redraw (Cairo::RefPtr<Cairo::Context> context) const
|
||||
* ::render
|
||||
*/
|
||||
|
||||
cerr << "rendered \"" << layout->get_text() << "\" into image\n";
|
||||
|
||||
_need_redraw = false;
|
||||
}
|
||||
|
||||
void
|
||||
Text::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
|
||||
{
|
||||
if (_text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_need_redraw) {
|
||||
redraw (context);
|
||||
}
|
||||
|
||||
Rect self = item_to_window (Rect (0, 0, min (_clamped_width, _width), _height));
|
||||
context->rectangle (self.x0, self.y0, self.width(), self.height());
|
||||
context->set_source (_image, self.x0, self.y0);
|
||||
context->fill ();
|
||||
}
|
||||
|
||||
void
|
||||
Text::clamp_width (double w)
|
||||
{
|
||||
@ -137,26 +152,6 @@ Text::compute_bounding_box () const
|
||||
_bounding_box_dirty = false;
|
||||
}
|
||||
|
||||
void
|
||||
Text::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||
{
|
||||
if (_text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_need_redraw) {
|
||||
redraw (context);
|
||||
}
|
||||
|
||||
|
||||
Rect self = item_to_window (Rect (0, 0, min (_clamped_width, _width), _height));
|
||||
cerr << "Draw \"" << _text << "\" @ " << self.x0 << ", " << self.y0 << ' ' << self.width() << " x " << self.height() << endl;
|
||||
context->rectangle (self.x0, self.y0, self.width(), self.height());
|
||||
context->set_source (_image, 0, 0);
|
||||
//context->set_source_rgb (0.3, 0.4, 0.02);
|
||||
context->fill ();
|
||||
}
|
||||
|
||||
void
|
||||
Text::set_alignment (Pango::Alignment alignment)
|
||||
{
|
||||
|
@ -154,10 +154,6 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
Rect self = item_to_window (Rect (0.0, 0.0, _region->length() / _samples_per_pixel, _height));
|
||||
boost::optional<Rect> draw = self.intersection (area);
|
||||
|
||||
context->rectangle (self.x0, self.y0, self.width(), self.height());
|
||||
context->set_source_rgb (1.0, 0.0, 0.0);
|
||||
context->stroke ();
|
||||
|
||||
if (!draw) {
|
||||
return;
|
||||
}
|
||||
@ -169,8 +165,8 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
|
||||
list<CacheEntry*>::iterator cache = _cache.begin ();
|
||||
|
||||
cerr << name << " draw " << area << "self = " << self << "\n\twill use " << draw.get() << endl;
|
||||
#if 1
|
||||
// cerr << name << " draw " << area << "self = " << self << "\n\twill use " << draw.get() << endl;
|
||||
#if 0
|
||||
cerr << " Cache contains " << _cache.size() << endl;
|
||||
while (cache != _cache.end()) {
|
||||
cerr << "\tsample span " << (*cache)->start() << " .. " << (*cache)->end()
|
||||
@ -186,7 +182,7 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
|
||||
while ((end - start) > 1.0) {
|
||||
|
||||
cerr << "***** RANGE = " << start << " .. " << end << " = " << end - start << endl;
|
||||
// cerr << "***** RANGE = " << start << " .. " << end << " = " << end - start << endl;
|
||||
|
||||
frameoffset_t start_sample_offset = to_src_sample_offset (_region_start, start, _samples_per_pixel);
|
||||
|
||||
@ -208,8 +204,6 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
|
||||
if (cache == _cache.end ()) {
|
||||
|
||||
cerr << "Nothing in cache spans\n";
|
||||
|
||||
/* Case 1: we have run out of cache entries, so make a new one for
|
||||
the whole required area and put it in the list.
|
||||
|
||||
@ -225,9 +219,6 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
double const rend = _region->length() / _samples_per_pixel;
|
||||
double const endpoint = min (rend, max (end, start + _canvas->visible_area().width()));
|
||||
|
||||
cerr << "New cache entry for " << start_sample_offset << " .. " << to_src_sample_offset (_region_start, endpoint, _samples_per_pixel)
|
||||
<< endl;
|
||||
|
||||
CacheEntry* c = new CacheEntry (this,
|
||||
start_sample_offset,
|
||||
to_src_sample_offset (_region_start, endpoint, _samples_per_pixel),
|
||||
@ -261,9 +252,7 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
|
||||
npeaks = end_pixel - start;
|
||||
assert (npeaks > 0);
|
||||
|
||||
cerr << "New fill-in cache entry for " << start_sample_offset << " .. " << end_sample_offset << endl;
|
||||
|
||||
|
||||
CacheEntry* c = new CacheEntry (this,
|
||||
start_sample_offset,
|
||||
end_sample_offset,
|
||||
@ -279,8 +268,6 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
we have left, so render it.
|
||||
*/
|
||||
|
||||
cerr << "found suitable cache entry\n";
|
||||
|
||||
image = *cache;
|
||||
++cache;
|
||||
|
||||
@ -290,7 +277,7 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
|
||||
double this_end = min (end, to_pixel_offset (_region_start, image->end (), _samples_per_pixel));
|
||||
double const image_origin = to_pixel_offset (_region_start, image->start(), _samples_per_pixel);
|
||||
#if 1
|
||||
#if 0
|
||||
cerr << "\t\tDraw image between "
|
||||
<< start
|
||||
<< " .. "
|
||||
@ -306,11 +293,10 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
||||
<< endl;
|
||||
#endif
|
||||
|
||||
cerr << "Fill rect " << draw->x0 << ", " << self.y0 << ' ' << draw->width() << " x " << draw->height() << endl;
|
||||
// cerr << "Fill rect " << draw->x0 << ", " << self.y0 << ' ' << draw->width() << " x " << draw->height() << endl;
|
||||
|
||||
context->rectangle (start, draw->y0, this_end - start, _height);
|
||||
// context->set_source (image->image(), image_origin, self.y0 - draw->y0);
|
||||
context->set_source_rgb (0.0, 0.0, 1.0);
|
||||
context->set_source (image->image(), self.x0 - image_origin, self.y0);
|
||||
context->fill ();
|
||||
|
||||
start = this_end;
|
||||
|
Loading…
Reference in New Issue
Block a user