static void gwy_app_file_chooser_describe_channel(GwyContainer *container, gint id, GString *str) { GwyDataField *dfield; GwySIUnit *siunit; GwySIValueFormat *vf; GQuark quark; gint xres, yres; gdouble xreal, yreal; gchar *s; g_string_truncate(str, 0); quark = gwy_app_get_data_key_for_id(id); dfield = GWY_DATA_FIELD(gwy_container_get_object(container, quark)); g_return_if_fail(GWY_IS_DATA_FIELD(dfield)); s = gwy_app_get_data_field_title(container, id); g_string_append(str, s); g_free(s); siunit = gwy_data_field_get_si_unit_z(dfield); s = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP); g_string_append_printf(str, " [%s]\n", s); g_free(s); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); g_string_append_printf(str, "%d×%d px\n", xres, yres); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); siunit = gwy_data_field_get_si_unit_xy(dfield); vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, sqrt(xreal*yreal), NULL); g_string_append_printf(str, "%.*f×%.*f%s%s", vf->precision, xreal/vf->magnitude, vf->precision, yreal/vf->magnitude, (vf->units && *vf->units) ? " " : "", vf->units); gwy_si_unit_value_format_free(vf); }
static gboolean height_dist(GwyContainer *data, GwyRunType run) { GString *lab; GtkWidget *graph; GwyDataWindow *data_window; GwyGraphAutoProperties prop; GwyDataLine *dataline; GwyDataField *dfield; GwyDataField *mfield; GwySIValueFormat *units; g_return_val_if_fail(run & DIST_RUN_MODES, FALSE); g_return_val_if_fail(gwy_container_contains_by_name(data, "/0/mask"), FALSE); graph = gwy_graph_new(); gwy_graph_get_autoproperties(GWY_GRAPH(graph), &prop); prop.is_point = 0; prop.is_line = 1; gwy_graph_set_autoproperties(GWY_GRAPH(graph), &prop); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data")); mfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/mask")); dataline = (GwyDataLine*)gwy_data_line_new(10, 10, TRUE); gwy_data_field_grains_get_height_distribution(dfield, mfield, dataline); lab = g_string_new(_("Grain height histogram")); units = gwy_si_unit_get_format(dfield->si_unit_xy, dataline->real, NULL); gwy_graph_add_dataline_with_units(GWY_GRAPH(graph), dataline, 0, lab, NULL, units->magnitude, 1, units->units, " "); data_window = gwy_app_data_window_get_for_data(data); gwy_app_graph_window_create_for_window(GWY_GRAPH(graph), data_window, _("Grain height distribution")); g_string_free(lab, TRUE); g_object_unref(dataline); g_free(units); return FALSE; }
static void gwy_recent_file_update_thumbnail(GwyRecentFile *rf, GwyContainer *data, gint hint, GdkPixbuf *use_this_pixbuf) { GwyDataField *dfield; GdkPixbuf *pixbuf; GStatBuf st; gchar *fnm; GwySIUnit *siunit; GwySIValueFormat *vf; gdouble xreal, yreal; gchar str_mtime[22]; gchar str_size[22]; gchar str_width[22]; gchar str_height[22]; GError *err = NULL; GQuark quark; gint id; g_return_if_fail(GWY_CONTAINER(data)); if (use_this_pixbuf) { /* If we are given a pixbuf, hint must be the ultimate channel id. * We also ignore the thnumbnail state then. */ g_return_if_fail(GDK_IS_PIXBUF(use_this_pixbuf)); id = hint; pixbuf = g_object_ref(use_this_pixbuf); } else { pixbuf = NULL; id = gwy_recent_file_find_some_channel(data, hint); if (rf->file_state == FILE_STATE_UNKNOWN) gwy_app_recent_file_try_load_thumbnail(rf); } /* Find channel with the lowest id not smaller than hint */ if (id == G_MAXINT) { gwy_debug("There is no channel in the file, cannot make thumbnail."); return; } if (g_stat(rf->file_sys, &st) != 0) { g_warning("File <%s> was just loaded or saved, but it doesn't seem to " "exist any more: %s", rf->file_utf8, g_strerror(errno)); return; } if ((gulong)rf->file_mtime == (gulong)st.st_mtime) return; quark = gwy_app_get_data_key_for_id(id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); g_return_if_fail(GWY_IS_DATA_FIELD(dfield)); rf->file_mtime = st.st_mtime; rf->file_size = st.st_size; rf->image_width = gwy_data_field_get_xres(dfield); rf->image_height = gwy_data_field_get_yres(dfield); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); siunit = gwy_data_field_get_si_unit_xy(dfield); vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, sqrt(xreal*yreal), NULL); g_free(rf->image_real_size); rf->image_real_size = g_strdup_printf("%.*f×%.*f%s%s", vf->precision, xreal/vf->magnitude, vf->precision, yreal/vf->magnitude, (vf->units && *vf->units) ? " " : "", vf->units); rf->file_state = FILE_STATE_OK; gwy_si_unit_value_format_free(vf); if (g_str_has_prefix(rf->file_sys, gwy_recent_file_thumbnail_dir())) { gchar c; c = rf->file_sys[strlen(gwy_recent_file_thumbnail_dir())]; if (!c || G_IS_DIR_SEPARATOR(c)) return; } if (!pixbuf) pixbuf = gwy_app_get_channel_thumbnail(data, id, TMS_NORMAL_THUMB_SIZE, TMS_NORMAL_THUMB_SIZE); g_snprintf(str_mtime, sizeof(str_mtime), "%lu", rf->file_mtime); g_snprintf(str_size, sizeof(str_size), "%lu", rf->file_size); g_snprintf(str_width, sizeof(str_width), "%d", rf->image_width); g_snprintf(str_height, sizeof(str_height), "%d", rf->image_height); /* invent an unique temporary name for atomic save * FIXME: rough, but works on Win32 */ fnm = g_strdup_printf("%s.%u", rf->thumb_sys, getpid()); if (!gdk_pixbuf_save(pixbuf, fnm, "png", &err, KEY_SOFTWARE, PACKAGE_NAME, KEY_THUMB_URI, rf->file_uri, KEY_THUMB_MTIME, str_mtime, KEY_THUMB_FILESIZE, str_size, KEY_THUMB_IMAGE_WIDTH, str_width, KEY_THUMB_IMAGE_HEIGHT, str_height, KEY_THUMB_GWY_REAL_SIZE, rf->image_real_size, NULL)) { g_clear_error(&err); rf->thumb_state = FILE_STATE_FAILED; } #ifndef G_OS_WIN32 chmod(fnm, 0600); #endif g_unlink(rf->thumb_sys); if (g_rename(fnm, rf->thumb_sys) != 0) { g_unlink(fnm); rf->thumb_state = FILE_STATE_FAILED; rf->thumb_mtime = 0; } else { rf->thumb_state = FILE_STATE_UNKNOWN; /* force reload */ rf->thumb_mtime = rf->file_mtime; } g_free(fnm); gwy_object_unref(rf->pixbuf); g_object_unref(pixbuf); }
static void grain_stat(GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table, *hbox, *button; GwyDataField *dfield, *mfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf, *vf2; gint xres, yres, ngrains; gdouble total_area, area, size, vol_0, vol_min, vol_laplace, bound_len, v; gdouble *values = NULL; gint *grains; GString *str, *str2; GPtrArray *report; const guchar *title; gchar *key, *value; gint row, id; guint i, maxlen; g_return_if_fail(run & STAT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield); g_return_if_fail(mfield); report = g_ptr_array_sized_new(20); if (gwy_container_gis_string_by_name(data, "/filename", &title)) { g_ptr_array_add(report, _("File:")); g_ptr_array_add(report, g_strdup(title)); } key = g_strdup_printf("/%d/data/title", id); if (gwy_container_gis_string_by_name(data, key, &title)) { g_ptr_array_add(report, _("Data channel:")); g_ptr_array_add(report, g_strdup(title)); } g_free(key); /* Make empty line in the report */ g_ptr_array_add(report, NULL); g_ptr_array_add(report, NULL); xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); total_area = gwy_data_field_get_xreal(dfield) *gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); area = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_PROJECTED_AREA); size = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_EQUIV_SQUARE_SIDE); vol_0 = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_0); vol_min = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_MIN); vol_laplace = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_LAPLACE); bound_len = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_FLAT_BOUNDARY_LENGTH); g_free(values); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); table = gtk_table_new(10, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(NULL); str2 = g_string_new(NULL); g_string_printf(str, "%d", ngrains); add_report_row(GTK_TABLE(table), &row, _("Number of grains:"), str->str, str->str, report); siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = gwy_si_unit_power(siunit, 2, NULL); v = area; vf = gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, NULL); vf2 = gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected area (abs.):"), str->str, str2->str, report); g_string_printf(str, "%.2f %%", 100.0*area/total_area); add_report_row(GTK_TABLE(table), &row, _("Total projected area (rel.):"), str->str, str->str, report); v = area/ngrains; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain area:"), str->str, str2->str, report); v = size/ngrains; gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain size:"), str->str, str2->str, report); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_multiply(siunit2, siunit, siunit2); v = vol_0; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (zero):"), str->str, str2->str, report); v = vol_min; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (minimum):"), str->str, str2->str, report); v = vol_laplace; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (laplacian):"), str->str, str2->str, report); v = bound_len; gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected boundary length:"), str->str, str2->str, report); gwy_si_unit_value_format_free(vf2); gwy_si_unit_value_format_free(vf); g_object_unref(siunit2); maxlen = 0; for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) maxlen = MAX(strlen(key), maxlen); } g_string_truncate(str, 0); g_string_append(str, _("Grain Statistics")); g_string_append(str, "\n\n"); for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) { value = (gchar*)g_ptr_array_index(report, 2*i + 1); g_string_append_printf(str, "%-*s %s\n", maxlen+1, key, value); g_free(value); } else g_string_append_c(str, '\n'); } g_ptr_array_free(report, TRUE); g_object_set_data(G_OBJECT(dialog), "report", str->str); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); button = grain_stats_add_aux_button(hbox, GTK_STOCK_SAVE, _("Save table to a file")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_save), dialog); button = grain_stats_add_aux_button(hbox, GTK_STOCK_COPY, _("Copy table to clipboard")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_copy), dialog); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); g_string_free(str2, TRUE); g_string_free(str, TRUE); }
static void gwy_color_axis_draw_label(GtkWidget *widget) { GwyColorAxis *axis; PangoLayout *layout; GwySIValueFormat *format = NULL; GString *strmin, *strmax; GdkGC *mygc; PangoRectangle rect; gwy_debug(""); mygc = gdk_gc_new(widget->window); axis = GWY_COLOR_AXIS(widget); /*compute minimum and maximum numbers*/ strmax = g_string_new(" "); if (axis->max == 0) { if (axis->min == 0) g_string_printf(strmax, "0.0"); else { format = gwy_si_unit_get_format(axis->siunit, axis->max, NULL); g_string_printf(strmax, "0.0 "); g_string_append(strmax, format->units); } } else { format = gwy_si_unit_get_format(axis->siunit, axis->max, NULL); g_string_printf(strmax, "%3.1f ", axis->max/format->magnitude); g_string_append(strmax, format->units); } strmin = g_string_new(" "); if (axis->min == 0) { if (axis->max == 0) g_string_printf(strmin, "0.0"); else { format = gwy_si_unit_get_format(axis->siunit, axis->max, format); g_string_printf(strmin, "0.0 "); g_string_append(strmin, format->units); } } else { /*yes, realy axis->max*/ format = gwy_si_unit_get_format(axis->siunit, axis->max, format); g_string_printf(strmin, "%3.1f ", axis->min/format->magnitude); g_string_append(strmin, format->units); } if (axis->orientation == GTK_ORIENTATION_VERTICAL) { /*draw frame around axis*/ gdk_draw_rectangle(widget->window, mygc, 0, 0, 0, widget->allocation.width - axis->par.textarea, widget->allocation.height - 1); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, 0, widget->allocation.width - axis->par.textarea + axis->par.tick_length, 0); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, widget->allocation.height/2, widget->allocation.width - axis->par.textarea + axis->par.tick_length, widget->allocation.height/2); gdk_draw_line(widget->window, mygc, widget->allocation.width - axis->par.textarea, widget->allocation.height - 1, widget->allocation.width - axis->par.textarea + axis->par.tick_length, widget->allocation.height - 1); /*draw text*/ layout = gtk_widget_create_pango_layout(widget, ""); pango_layout_set_font_description(layout, axis->par.font); pango_layout_set_markup(layout, strmax->str, strmax->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - axis->par.textarea + 2, 2, layout); pango_layout_set_markup(layout, strmin->str, strmin->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - axis->par.textarea + 2, widget->allocation.height - rect.height - 2, layout); } else { /*draw frame around axis*/ gdk_draw_rectangle(widget->window, mygc, FALSE, 0, axis->par.textarea, widget->allocation.width - 1, widget->allocation.height - 1); gdk_draw_line(widget->window, mygc, 0, axis->par.textarea - axis->par.tick_length, 0, axis->par.textarea); gdk_draw_line(widget->window, mygc, widget->allocation.width/2, axis->par.textarea - axis->par.tick_length, widget->allocation.width/2, axis->par.textarea); gdk_draw_line(widget->window, mygc, widget->allocation.width - 1, axis->par.textarea - axis->par.tick_length, widget->allocation.width - 1, axis->par.textarea); /*draw text*/ layout = gtk_widget_create_pango_layout(widget, ""); pango_layout_set_font_description(layout, axis->par.font); pango_layout_set_markup(layout, strmin->str, strmin->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, 2, axis->par.textarea - rect.height - 2, layout); pango_layout_set_markup(layout, strmax->str, strmax->len); pango_layout_get_pixel_extents(layout, NULL, &rect); gdk_draw_layout(widget->window, mygc, widget->allocation.width - rect.width - 2, axis->par.textarea - rect.height - 2, layout); } g_object_unref(mygc); g_object_unref(layout); if (format) gwy_si_unit_value_format_free(format); g_string_free(strmin, TRUE); g_string_free(strmax, TRUE); }
static gboolean stats(GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table, *label; GwyDataField *dfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf; gint i, xres, yres, ngrains, npix; gdouble area, v; GString *str; gint *grains; gint row; g_return_val_if_fail(run & DIST_RUN_MODES, FALSE); g_return_val_if_fail(gwy_container_contains_by_name(data, "/0/mask"), FALSE); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/mask")); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); area = gwy_data_field_get_xreal(dfield)*gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(dfield, grains); npix = 0; for (i = 0; i < xres*yres; i++) npix += (grains[i] != 0); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); table = gtk_table_new(4, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(""); label = gtk_label_new(_("Number of grains:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); g_string_printf(str, "%d", ngrains); label = gtk_label_new(str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; /* FIXME: simplify with 2.x unit methods */ siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = GWY_SI_UNIT(gwy_si_unit_new("")); gwy_si_unit_multiply(siunit, siunit, siunit2); label = gtk_label_new(_("Total projected area (abs.):")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = npix*area/(xres*yres); vf = gwy_si_unit_get_format(siunit2, v, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Total projected area (rel.):")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); g_string_printf(str, "%.2f %%", 100.0*npix/(xres*yres)); label = gtk_label_new(str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Mean grain area:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = npix*area/(ngrains*xres*yres); gwy_si_unit_get_format(siunit2, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Mean grain size:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = sqrt(npix*area/(ngrains*xres*yres)); gwy_si_unit_get_format(siunit, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; gwy_si_unit_value_format_free(vf); g_string_free(str, TRUE); g_object_unref(siunit2); gtk_widget_show_all(dialog); return FALSE; }
static void grain_stat(G_GNUC_UNUSED GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table; GwyDataField *dfield, *mfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf; gint xres, yres, ngrains; gdouble total_area, area, size, vol_0, vol_min, vol_laplace, v; gdouble *values = NULL; gint *grains; GString *str; gint row; g_return_if_fail(run & STAT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield); g_return_if_fail(mfield); xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); total_area = gwy_data_field_get_xreal(dfield) *gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); area = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_PROJECTED_AREA); size = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_EQUIV_SQUARE_SIDE); vol_0 = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_0); vol_min = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_MIN); vol_laplace = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_LAPLACE); g_free(values); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); table = gtk_table_new(7, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(NULL); g_string_printf(str, "%d", ngrains); add_report_row(GTK_TABLE(table), &row, _("Number of grains:"), str->str); siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = gwy_si_unit_power(siunit, 2, NULL); v = area; vf = gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total projected area (abs.):"), str->str); g_string_printf(str, "%.2f %%", 100.0*area/total_area); add_report_row(GTK_TABLE(table), &row, _("Total projected area (rel.):"), str->str); v = area/ngrains; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain area:"), str->str); v = size/ngrains; gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain size:"), str->str); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_multiply(siunit2, siunit, siunit2); v = vol_0; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (zero):"), str->str); v = vol_min; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (minimum):"), str->str); v = vol_laplace; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (laplacian):"), str->str); gwy_si_unit_value_format_free(vf); g_string_free(str, TRUE); g_object_unref(siunit2); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); }