summaryrefslogtreecommitdiff
path: root/src/summary-chart.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/summary-chart.c')
-rw-r--r--src/summary-chart.c90
1 files changed, 71 insertions, 19 deletions
diff --git a/src/summary-chart.c b/src/summary-chart.c
index 53751bc..e9a5dc1 100644
--- a/src/summary-chart.c
+++ b/src/summary-chart.c
@@ -33,7 +33,8 @@
typedef struct _summary_chart {
GtkWidget widget;
- cairo_surface_t *image;
+ cairo_pattern_t *image;
+ int image_width, image_height;
AllocatorsStore *store;
struct _sum_allocator others;
@@ -140,6 +141,45 @@ summary_chart_realize (GtkWidget *widget)
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
}
+static void
+summary_chart_load_background (SummaryChart *self, cairo_surface_t *target)
+{
+ static cairo_surface_t *background;
+
+ if (background == NULL)
+ background = cairo_image_surface_create_from_png (DATADIR G_DIR_SEPARATOR_S "odin.png");
+
+ if (cairo_surface_status (background) == CAIRO_STATUS_SUCCESS) {
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ cairo_status_t status;
+
+ self->image_width = cairo_image_surface_get_width (background);
+ self->image_height = cairo_image_surface_get_height (background);
+ surface = cairo_surface_create_similar (target,
+ cairo_surface_get_content (background),
+ self->image_width, self->image_height);
+
+ cr = cairo_create (surface);
+ cairo_set_source_surface (cr, background, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status == CAIRO_STATUS_SUCCESS &&
+ cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
+ {
+ self->image = cairo_pattern_create_for_surface (surface);
+ if (cairo_pattern_status (self->image)) {
+ cairo_pattern_destroy (self->image);
+ self->image = NULL;
+ }
+ }
+ cairo_surface_destroy (surface);
+ }
+}
+
static gboolean
summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
{
@@ -148,9 +188,9 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
GPtrArray *allocators;
guint64 total;
guint min;
- guint n, ww, hh;
+ guint n;
gint r;
- gdouble theta, theta_offset;
+ gdouble theta, theta_offset, ww, hh;
AllocatorsStoreSort sort;
PangoContext *ctx;
@@ -161,7 +201,7 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
ctx = gtk_widget_create_pango_context (&self->widget);
merge = pango_context_get_font_description (ctx);
desc = pango_font_description_new ();
- pango_font_description_set_family (desc, "sans");
+ pango_font_description_set_family_static (desc, "sans");
pango_font_description_set_size (desc, PANGO_SCALE * 8);
pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
pango_font_description_merge (desc, merge, FALSE);
@@ -199,20 +239,26 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
}
theta_offset = -G_PI / 2 + (2 * G_PI - theta) / 2.;
- ww = widget->allocation.width / 2;
- hh = widget->allocation.height / 2;
+ ww = .5 * widget->allocation.width;
+ hh = .5 * widget->allocation.height;
/* background */
cairo_arc (cr, ww, hh, r, 0, 2 * G_PI);
cairo_set_source_rgb (cr, .7, .7, .7);
+ if (self->image == NULL)
+ summary_chart_load_background (self, cairo_get_target (cr));
if (self->image != NULL) {
+ cairo_matrix_t matrix;
+
cairo_fill_preserve (cr);
cairo_clip (cr);
- cairo_set_source_surface (cr, self->image,
- ww - cairo_image_surface_get_width (self->image) / 2,
- hh - cairo_image_surface_get_width (self->image) / 2);
+ cairo_matrix_init_translate (&matrix,
+ .5 * self->image_width - ww,
+ .5 * self->image_height - hh);
+ cairo_pattern_set_matrix (self->image, &matrix);
+ cairo_set_source (cr, self->image);
cairo_paint (cr);
cairo_reset_clip (cr);
} else
@@ -280,7 +326,7 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
max_r = mid_r + logical.width / 2.;
arc_height = dtheta * min_r - 4;
if (min_r < r/4 + 2 || max_r > r - 2 || logical.height > arc_height) {
- pango_layout_set_width (text, r*3./4 - 2*BORDER);
+ pango_layout_set_width (text, PANGO_SCALE * (r*3./4 - 2*BORDER));
pango_layout_set_ellipsize (text, PANGO_ELLIPSIZE_END);
pango_layout_get_pixel_extents (text, NULL, &logical);
min_r = mid_r - logical.width / 2.;
@@ -303,7 +349,6 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
}
cairo_set_source_rgb (cr, 0., 0., 0.);
pango_cairo_show_layout (cr, text);
- cairo_stroke (cr);
cairo_restore (cr);
}
g_object_unref (text);
@@ -324,6 +369,19 @@ summary_chart_expose (GtkWidget *widget, GdkEventExpose *ev)
return FALSE;
}
+static void
+summary_chart_unrealize (GtkWidget *widget)
+{
+ SummaryChart *self = (SummaryChart *) widget;
+
+ if (self->image != NULL) {
+ cairo_pattern_destroy (self->image);
+ self->image = NULL;
+ }
+
+ GTK_WIDGET_CLASS (summary_chart_parent_class)->unrealize (widget);
+}
+
static struct _sum_allocator *
_summary_chart_get_sum_for_cursor (SummaryChart *self, gint x, gint y)
{
@@ -461,7 +519,7 @@ summary_chart_query_tooltip (GtkWidget *widget,
main_fn = app_get_main_function (app_get (widget));
last = NULL;
- for (m = n; m < MIN (n + 8, A->n_frames); m++) {
+ for (m = n; m < MIN (n + NUM_CALLERS, A->n_frames); m++) {
if (A->frames[m]->function_srcloc != last) {
g_string_append_c (string, '\n');
g_string_append_c (string, '\t');
@@ -492,8 +550,6 @@ summary_chart_query_tooltip (GtkWidget *widget,
return TRUE;
}
-static cairo_surface_t *background;
-
static void
summary_chart_class_init (SummaryChartClass *klass)
{
@@ -504,6 +560,7 @@ summary_chart_class_init (SummaryChartClass *klass)
object_class->get_property = summary_chart_get_property;
widget_class->realize = summary_chart_realize;
+ widget_class->unrealize = summary_chart_unrealize;
widget_class->expose_event = summary_chart_expose;
widget_class->query_tooltip = summary_chart_query_tooltip;
@@ -518,10 +575,6 @@ summary_chart_class_init (SummaryChartClass *klass)
G_PARAM_STATIC_BLURB |
G_PARAM_STATIC_NAME |
G_PARAM_READWRITE));
-
- background = cairo_image_surface_create_from_png (DATADIR G_DIR_SEPARATOR_S "odin.png");
- if (cairo_surface_status (background))
- background = NULL;
}
@@ -529,7 +582,6 @@ static void
summary_chart_init (SummaryChart *self)
{
self->others.frame = (gchar *) "Others";
- self->image = cairo_surface_reference (background);
gtk_widget_set_has_tooltip (&self->widget, TRUE);
}