diff options
Diffstat (limited to 'src/summary-chart.c')
-rw-r--r-- | src/summary-chart.c | 90 |
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); } |