Hi creak,
I'm not a fulltime programmer, so happy for you to ignore comments
if someone more intelligent has other advice...
Ian
On 25/11/13 09:28, creak ml wrote:
And
for those interested, here is the code that, apparently, is
better (I'm not sure since I found it only by
experimentation):
bool
BenchMarkArea::on_draw(Cairo::RefPtr<Cairo::Context>
const& cr)
{
I'd argue your first problem is here. Simple rule: when using a
Cairo::Context, encase everything you do in save/ restore. If you
don't, you have to manually keep track of the context state, which
is difficult/ practically impossible in many cases.
cr->set_antialias(Cairo::ANTIALIAS_NONE);
// ... [skipping boring parts, variables initializations]
...
libbench::BenchVector const& benches =
benchList.GetBenches();
for(libbench::BenchVector::const_iterator it =
benches.begin(); it != benches.end(); ++it)
{
libbench::Bench const& bench = *it;
double benchLeft = leftMargin + bench.m_startTime *
m_timeToPx;
double benchWidth = (bench.m_stopTime -
bench.m_startTime) * m_timeToPx;
// Filter unnecessary drawings; too small or outside
of the default clip area.
if(benchWidth < 1.0 || !cr->in_clip(benchLeft,
benchTop))
continue;
And again, why not save() here, so that you can return to the
Context within a loop as many times as required? You'll keep the
current clip area within that save(), and probably could set the
Pango::Layout outside this loop so you can reuse it instead of
redefining it every time you enter the loop.
// Want to start as new.
cr->begin_new_path();
// Add rectangle.
cr->rectangle(benchLeft, benchTop, benchWidth,
20.0);
// Fill in yellow-ish and preserve path (for stroke).
cr->set_line_width(1.0);
cr->set_source_rgb(1.0, 0.8, 0.5);
cr->fill_preserve();
// Stroke in black preserve path (for text clipping).
cr->set_source_rgb(0.0, 0.0, 0.0);
cr->stroke_preserve();
If you aren't going to use the path again, why are you preserving
it? That's a waste of memory because you're keeping track of
something you no longer need.
// No need to draw text if there is no space left for
it.
if(benchWidth > 2.0)
{
// http://developer.gnome.org/pangomm/unstable/classPango_1_1Layout.html
Glib::RefPtr<Pango::Layout> layout =
create_pango_layout(bench.GetName());
layout->set_font_description(m_font);
// Get the text dimensions.
int text_width;
int text_height;
layout->get_pixel_size(text_width,
text_height);
// Save because we'll need to make a clip reset
and good practice tells us to
// surround these kind of stuff with save/restore.
cr->save();
I'm not sure clipping speeds up things that much in this scenario.
You've still got to draw the entire scene; if it's a static picture,
then you may as well draw it all at once, and clipping will require
greater resources than just drawing. I can see a point in clipping
ot prevent offscreen elements from being computed, but not for
onscreen... but could easily be wrong on that.
// Clip so that text drawing will be done inside
the box.
cr->clip();
// Position the text in the middle and draw.
cr->set_source_rgb(0.0, 0.0, 0.0);
cr->move_to(benchLeft + (benchWidth -
text_width) / 2, benchTop + (20.0 - text_height) / 2);
layout->show_in_cairo_context(cr);
// Reset clip and restore.
cr->reset_clip();
cr->restore();
}
}
// Everything is under control.
return true;
}
I still have some questions though, I suppose it's not
necessary to reset the clip since we restore the context just
after...
And since I'll have to draw thousands of these kind of little
boxes, do you have some advice to have the fastest drawing
method possible?
For instance, is it better to set all the paths and then
filling and stroking them, or dealing with several small paths
are more efficient?
Thanks a lot!
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list
|