Пример #1
0
static gboolean gegl_can_process(GeglNode *render_node)
{
	GeglRectangle  roi;
	roi      = gegl_node_get_bounding_box (geglGraph->node_pixbuf);
	g_print("GeglRectangle: height:%i, width:%i\n",roi.height,roi.width);
	return TRUE;
}
Пример #2
0
static GeglNode *
photos_base_item_load (PhotosBaseItem *self, GCancellable *cancellable, GError **error)
{
  PhotosBaseItemPrivate *priv = self->priv;
  GeglNode *ret_val = NULL;
  gchar *path = NULL;

  if (priv->graph == NULL)
    {
      path = photos_base_item_download (self, cancellable, error);
      if (path == NULL)
        goto out;

      priv->graph = gegl_node_new ();
      priv->node = gegl_node_new_child (priv->graph,
                                        "operation", "gegl:load",
                                        "path", path,
                                        NULL);
    }

  gegl_node_process (priv->node);
  priv->bbox = gegl_node_get_bounding_box (priv->node);
  ret_val = g_object_ref (priv->node);

 out:
  g_free (path);
  return ret_val;
}
Пример #3
0
Файл: gegl.c Проект: jonnor/gegl
static void
prepare (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglNode *gegl, *input, *output;
  GError *error = NULL;

  gegl = operation->node;

  if (!o->user_data || !g_str_equal (o->user_data, o->string))
  {
    g_free (o->user_data);
    o->user_data = g_strdup (o->string);

  input  = gegl_node_get_input_proxy (gegl,  "input");
  output = gegl_node_get_output_proxy (gegl, "output");

  gegl_node_link_many (input, output, NULL);
  {
     gchar cwd[81920]; // XXX: should do better
     getcwd (cwd, sizeof(cwd));
  gegl_create_chain (o->string, input, output, 0.0,
                     gegl_node_get_bounding_box (input).height, cwd,
                     &error);
  }

  if (error)
  {
    gegl_node_set (gegl, "error", error->message, NULL);
    g_clear_error (&error);
  }
  else
    g_object_set (operation, "error", "", NULL);
  }
}
Пример #4
0
static gdouble
photos_print_setup_get_max_percentage (PhotosPrintSetup *self)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble height;
    gdouble page_height;
    gdouble page_width;
    gdouble width;
    gdouble perc;

    page_width = gtk_page_setup_get_page_width (priv->page_setup, GTK_UNIT_INCH);
    page_height = gtk_page_setup_get_page_height (priv->page_setup, GTK_UNIT_INCH);
    bbox = gegl_node_get_bounding_box (priv->node);

    width  = (gdouble) bbox.width / FACTOR_INCH_TO_PIXEL;
    height = (gdouble) bbox.height / FACTOR_INCH_TO_PIXEL;

    if (page_width > width && page_height > height)
        perc = 1.0;
    else
        perc = MIN (page_width / width, page_height / height);

    return perc;
}
Пример #5
0
static void
update_autoscale(ViewHelper *self)
{
    GdkRectangle viewport = self->widget_allocation;
    GeglRectangle bbox = gegl_node_get_bounding_box(self->node);
    model_rect_to_view_rect(self, &bbox);

    if (!self->node || viewport.width < 0 || viewport.height < 0
            || bbox.width < 0 || bbox.height < 0)
        return;

    if (self->autoscale_policy == GEGL_GTK_VIEW_AUTOSCALE_WIDGET) {
        /* Request widget size change */
        /* XXX: Should we reset scale/x/y here? */
        g_signal_emit(self, view_helper_signals[SIGNAL_SIZE_CHANGED],
                      0, &bbox, NULL);

    } else if (self->autoscale_policy == GEGL_GTK_VIEW_AUTOSCALE_CONTENT) {
        /* Calculate and set scaling factor to make the content fit inside */
        float width_ratio = bbox.width / (float)viewport.width;
        float height_ratio = bbox.height / (float)viewport.height;
        float max_ratio = width_ratio >= height_ratio ? width_ratio : height_ratio;

        float current_scale = view_helper_get_scale(self);
        view_helper_set_scale(self, current_scale * (1.0 / max_ratio));
    }

}
Пример #6
0
void
view_helper_set_node(ViewHelper *self, GeglNode *node)
{
    if (self->node == node)
        return;

    if (self->node)
        g_object_unref(self->node);

    if (node) {
        g_object_ref(node);
        self->node = node;

        g_signal_connect_object(self->node, "computed",
                                G_CALLBACK(computed_event),
                                self, 0);
        g_signal_connect_object(self->node, "invalidated",
                                G_CALLBACK(invalidated_event),
                                self, 0);

        if (self->processor)
            g_object_unref(self->processor);

        GeglRectangle bbox = gegl_node_get_bounding_box(self->node);
        self->processor = gegl_node_new_processor(self->node, &bbox);

        update_autoscale(self);
        trigger_processing(self, bbox);

    } else
        self->node = NULL;
}
GeglRectangle *
gegl_node_introspectable_get_bounding_box (GeglNode *node)
{
  GeglRectangle  bbox   = gegl_node_get_bounding_box (node);
  GeglRectangle *result = g_new (GeglRectangle, 1);

  *result = bbox;

  return result;
}
static GeglNode *
photos_operation_insta_hefe_detect (GeglOperation *operation, gint x, gint y)
{
  PhotosOperationInstaHefe *self = PHOTOS_OPERATION_INSTA_HEFE (operation);
  GeglRectangle bounds;

  bounds = gegl_node_get_bounding_box (self->output);
  if (x >= bounds.x && y >= bounds.y && x < bounds.x + bounds.width && y < bounds.y + bounds.height)
    return operation->node;

  return NULL;
}
static void
photos_operation_insta_hefe_prepare (GeglOperation *operation)
{
  PhotosOperationInstaHefe *self = PHOTOS_OPERATION_INSTA_HEFE (operation);
  GeglRectangle bbox;

  bbox = gegl_node_get_bounding_box (self->input);
  if (!gegl_rectangle_equal (&self->bbox, &bbox))
    {
      self->bbox = bbox;
      photos_operation_insta_hefe_setup (self);
    }
}
Пример #10
0
static void
photos_image_view_update (PhotosImageView *self)
{
  GdkRectangle viewport;
  GeglRectangle bbox;
  float zoom_scaled = 1.0;
  gint scale_factor;
  gint viewport_height_real;
  gint viewport_width_real;

  if (self->node == NULL)
    return;

  gtk_widget_get_allocation (GTK_WIDGET (self), &viewport);

  if (viewport.width < 0 || viewport.height < 0)
    return;

  bbox = gegl_node_get_bounding_box (self->node);
  if (bbox.width < 0 || bbox.height < 0)
    return;

  scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
  viewport_height_real = viewport.height * scale_factor;
  viewport_width_real = viewport.width * scale_factor;

  if (bbox.height > viewport_height_real || bbox.width > viewport_width_real)
    {
      gfloat height_ratio = bbox.height / (gfloat) viewport_height_real;
      gfloat width_ratio = bbox.width / (gfloat) viewport_width_real;
      gfloat max_ratio =  MAX (height_ratio, width_ratio);

      zoom_scaled = 1.0 / max_ratio;

      bbox.width = (gint) (zoom_scaled * bbox.width + 0.5);
      bbox.height = (gint) (zoom_scaled * bbox.height + 0.5);
      bbox.x = (gint) (zoom_scaled * bbox.x + 0.5);
      bbox.y = (gint) (zoom_scaled * bbox.y + 0.5);
    }

  self->zoom_scaled = zoom_scaled;
  self->zoom = self->zoom_scaled / (gfloat) scale_factor;

  /* At this point, viewport is definitely bigger than bbox. */
  self->x_scaled = (bbox.width - viewport_width_real) / 2.0 + bbox.x;
  self->y_scaled = (bbox.height - viewport_height_real) / 2.0 + bbox.y;

  self->x = self->x_scaled / (gfloat) scale_factor;
  self->y = self->y_scaled / (gfloat) scale_factor;
}
Пример #11
0
static void
photos_print_setup_set_initial_values (PhotosPrintSetup *self)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble page_height;
    gdouble page_width;
    gdouble factor;
    gdouble height;
    gdouble max_perc;
    gdouble width;

    factor = get_scale_to_px_factor (self);

    bbox = gegl_node_get_bounding_box (priv->node);
    width = (gdouble) bbox.width/factor;
    height = (gdouble) bbox.height/factor;

    max_perc = photos_print_setup_get_max_percentage (self);

    width *= max_perc;
    height *= max_perc;

    gtk_range_set_range (GTK_RANGE (priv->scaling), 1, 100 * max_perc);
    gtk_range_set_increments (GTK_RANGE (priv->scaling), max_perc, 10 * max_perc);
    gtk_range_set_value (GTK_RANGE (priv->scaling), 100 * max_perc);

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), max_perc);
    gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->width), 0, width);
    gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->height), 0, height);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_BOTH);

    photos_print_setup_center (gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit),
                               gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->width)),
                               GTK_SPIN_BUTTON (priv->left), GTK_SPIN_BUTTON (priv->right));
    photos_print_setup_center (gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit),
                               gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->height)),
                               GTK_SPIN_BUTTON (priv->top), GTK_SPIN_BUTTON (priv->bottom));

    page_width = gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit);
    page_height = gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit);

    update_image_pos_ranges (self, page_width, page_height, width, height);
}
Пример #12
0
static void
on_scale_changed (GtkRange *range, gpointer user_data)
{
    PhotosPrintSetup *self = PHOTOS_PRINT_SETUP (user_data);
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble height;
    gdouble scale;
    gdouble width;
    gdouble left, right, top, bottom;
    gdouble page_width, page_height;
    gdouble factor;

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);

    bbox = gegl_node_get_bounding_box (priv->node);
    factor = get_scale_to_px_factor (self);

    width = (gdouble) bbox.width / factor;
    height = (gdouble) bbox.height / factor;

    left = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->left));
    top = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->top));

    scale = CLAMP (0.01 * gtk_range_get_value (range), 0, photos_print_setup_get_max_percentage (self));

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), scale);

    width  *= scale;
    height *= scale;

    page_width = gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit);
    page_height = gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit);

    update_image_pos_ranges (self, page_width, page_height, width, height);

    right = page_width - left - width;
    bottom = page_height - top - height;

    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->right), right);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->bottom), bottom);
}
static void
photos_print_operation_constructed (GObject *object)
{
  PhotosPrintOperation *self = PHOTOS_PRINT_OPERATION (object);
  GeglRectangle bbox;
  GtkPageSetup *page_setup;
  gchar *name;

  G_OBJECT_CLASS (photos_print_operation_parent_class)->constructed (object);

  page_setup = gtk_page_setup_new ();
  gtk_print_operation_set_default_page_setup (GTK_PRINT_OPERATION (self), page_setup);

  bbox = gegl_node_get_bounding_box (self->node);
  if (bbox.height >= bbox.width)
    gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_PORTRAIT);
  else
    gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_LANDSCAPE);

  g_object_unref (page_setup);

  name = g_strdup (photos_base_item_get_name (self->item));
  if (name == NULL || name[0] == '\0')
    {
      GFile *file;
      const gchar *uri;
      gchar *basename;

      uri = photos_base_item_get_uri (self->item);
      file = g_file_new_for_uri (uri);
      basename = g_file_get_basename (file);

      if (g_utf8_validate (basename, -1, NULL))
        name = g_strdup (basename);
      else
        name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);

      g_free (basename);
      g_object_unref (file);
    }

  gtk_print_operation_set_job_name (GTK_PRINT_OPERATION (self), name);
  g_free (name);
}
Пример #14
0
void refresh_images(GeglEditorLayer* self)
{
  return;
  GSList*	pair = self->pairs;
  for(;pair != NULL; pair = pair->next)
    {
      node_id_pair	*data = pair->data;

      /*      if(node->image != NULL)
	      cairo_surface_destroy(node->image);	//TODO: only destory if it has changed*/

      const Babl	*cairo_argb32 = babl_format("cairo-ARGB32");

      const GeglRectangle	roi = gegl_node_get_bounding_box(GEGL_NODE(data->node));
      g_print("Rect: %dx%d\n", roi.x, roi.y);

      if(roi.width == 0 || roi.height == 0)
	{
	  g_print("Empty rectangle: %s\n", gegl_node_get_operation(GEGL_NODE(data->node)));
	  continue;		//skip
	}

      gegl_editor_show_node_image(self->editor, data->id);

      gint	stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, roi.width);
      guchar*	buf    = malloc(stride*roi.height);

      //make buffer in memory
      gegl_node_blit(GEGL_NODE(data->node),
		     1.0,
		     &roi,
		     cairo_argb32,
		     buf,
		     GEGL_AUTO_ROWSTRIDE,
		     GEGL_BLIT_CACHE);

      cairo_surface_t*	image =
	cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
				      roi.width, roi.height,
				      stride);
      //            free(buf);
      gegl_editor_set_node_image(self->editor, data->id, image);
    }
}
Пример #15
0
static void
photos_print_setup_size_changed (PhotosPrintSetup *self,
                                 GtkWidget *w_size_x,
                                 GtkWidget *w_size_y,
                                 GtkWidget *w_margin_x_1,
                                 GtkWidget *w_margin_x_2,
                                 GtkWidget *w_margin_y_1,
                                 GtkWidget *w_margin_y_2,
                                 gdouble page_size_x,
                                 gdouble page_size_y,
                                 gint change)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble margin_x_1, margin_x_2;
    gdouble margin_y_1, margin_y_2;
    gdouble orig_size_x = -1, orig_size_y = -1, scale;
    gdouble size_x, size_y;
    gdouble factor;

    size_x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_size_x));
    margin_x_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_x_1));
    margin_y_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_y_1));

    bbox = gegl_node_get_bounding_box (priv->node);
    factor = get_scale_to_px_factor (self);

    switch (change)
    {
    case CHANGE_HORIZ:
        orig_size_x = (gdouble) bbox.width / factor;
        orig_size_y = (gdouble) bbox.height / factor;
        break;
    case CHANGE_VERT:
        orig_size_y = (gdouble) bbox.width / factor;
        orig_size_x = (gdouble) bbox.height / factor;
        break;
    default:
        g_assert_not_reached ();
        break;
    }

    scale = CLAMP (size_x / orig_size_x, 0, 1);

    size_y = scale * orig_size_y;

    margin_x_2 = page_size_x - margin_x_1 - size_x;
    margin_y_2 = page_size_y - margin_y_1 - size_y;

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), scale);

    switch (change)
    {
    case CHANGE_HORIZ:
        update_image_pos_ranges (self, page_size_x, page_size_y, size_x, size_y);
        break;
    case CHANGE_VERT:
        update_image_pos_ranges (self, page_size_y, page_size_x, size_y, size_x);
        break;
    default:
        g_assert_not_reached ();
        break;
    }

    gtk_range_set_value (GTK_RANGE (priv->scaling), 100*scale);

    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_x_2), margin_x_2);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_size_y), size_y);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_y_2), margin_y_2);

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);
}
Пример #16
0
static gboolean
test_operation (const gchar *op_name,
                const gchar *image,
                gchar       *output_path)
{
  gchar         *ref_path;
  GeglNode      *img, *ref_img, *gegl;
  GeglRectangle  ref_bounds, comp_bounds;
  gint           ref_pixels;
  gboolean       result = TRUE;

  gegl = gegl_node_new ();

  ref_path = g_build_path (G_DIR_SEPARATOR_S, reference_dir, image, NULL);
  ref_img = gegl_node_new_child (gegl,
                                 "operation", "gegl:load",
                                 "path", ref_path,
                                 NULL);
  g_free (ref_path);

  img = gegl_node_new_child (gegl,
                             "operation", "gegl:load",
                             "path", output_path,
                             NULL);

  ref_bounds  = gegl_node_get_bounding_box (ref_img);
  comp_bounds = gegl_node_get_bounding_box (img);
  ref_pixels  = ref_bounds.width * ref_bounds.height;

  if (ref_bounds.width != comp_bounds.width ||
      ref_bounds.height != comp_bounds.height)
    {
      g_printf ("FAIL\n  Reference and composition differ in size\n");
      result = FALSE;
    }
  else
    {
      GeglNode *comparison;
      gdouble   max_diff;

      comparison = gegl_node_create_child (gegl, "gegl:image-compare");
      gegl_node_link (img, comparison);
      gegl_node_connect_to (ref_img, "output", comparison, "aux");
      gegl_node_process (comparison);
      gegl_node_get (comparison, "max diff", &max_diff, NULL);

      if (max_diff < 1.0)
        {
          g_printf ("PASS\n");
          result = TRUE;
        }
      else
        {
          GeglNode *output;
          gchar    *diff_path;
          gdouble   avg_diff_wrong, avg_diff_total;
          gint      wrong_pixels;

          gegl_node_get (comparison, "avg_diff_wrong", &avg_diff_wrong,
                         "avg_diff_total", &avg_diff_total, "wrong_pixels",
                         &wrong_pixels, NULL);

          g_printf ("FAIL\n  Reference image and composition differ\n"
                    "    wrong pixels : %i/%i (%2.2f%%)\n"
                    "    max Δe       : %2.3f\n"
                    "    avg Δe       : %2.3f (wrong) %2.3f (total)\n",
                    wrong_pixels, ref_pixels,
                    (wrong_pixels * 100.0 / ref_pixels),
                    max_diff, avg_diff_wrong, avg_diff_total);

          diff_path = operation_to_path (op_name, TRUE);
          output = gegl_node_new_child (gegl,
                                        "operation", "gegl:png-save",
                                        "path", diff_path,
                                        NULL);
          gegl_node_link (comparison, output);
          gegl_node_process (output);

          g_free (diff_path);

          result = FALSE;
        }
    }

  g_object_unref (gegl);
  return result;
}
Пример #17
0
gint
main (gint    argc,
      gchar **argv)
{
    GeglNode      *gegl, *imgA, *imgB, *comparison;
    GeglRectangle  boundsA, boundsB;
    gdouble        max_diff, avg_diff_wrong, avg_diff_total;
    gint           wrong_pixels, total_pixels;

    gegl_init (&argc, &argv);

    if (argc != 3)
    {
        g_print ("This is simple image difference detection tool for use in regression testing.\n"
                 "Exit code is non zero if images are different, if they are equal"
                 "the output will contain the string identical.\n");
        g_print ("Usage: %s <imageA> <imageB>\n", argv[0]);
        return ERROR_WRONG_ARGUMENTS;
    }

    gegl = gegl_node_new ();
    imgA = gegl_node_new_child (gegl,
                                "operation", "gegl:load",
                                "path", argv[1],
                                NULL);
    imgB = gegl_node_new_child (gegl,
                                "operation", "gegl:load",
                                "path", argv[2],
                                NULL);

    boundsA = gegl_node_get_bounding_box (imgA);
    boundsB = gegl_node_get_bounding_box (imgB);
    total_pixels = boundsA.width * boundsA.height;

    if (boundsA.width != boundsB.width || boundsA.height != boundsB.height)
    {
        g_printerr ("%s and %s differ in size\n", argv[1], argv[2]);
        g_printerr ("  %ix%i vs %ix%i\n",
                    boundsA.width, boundsA.height, boundsB.width, boundsB.height);
        return ERROR_WRONG_SIZE;
    }

    comparison = gegl_node_create_child (gegl, "gegl:image-compare");
    gegl_node_link (imgA, comparison);
    gegl_node_connect_to (imgB, "output", comparison, "aux");
    gegl_node_process (comparison);
    gegl_node_get (comparison,
                   "max diff", &max_diff,
                   "avg-diff-wrong", &avg_diff_wrong,
                   "avg-diff-total", &avg_diff_total,
                   "wrong-pixels", &wrong_pixels,
                   NULL);

    if (max_diff >= 0.1)
    {
        g_printerr ("%s and %s differ\n"
                    "  wrong pixels   : %i/%i (%2.2f%%)\n"
                    "  max Δe         : %2.3f\n"
                    "  avg Δe (wrong) : %2.3f(wrong) %2.3f(total)\n",
                    argv[1], argv[2],
                    wrong_pixels, total_pixels,
                    (wrong_pixels*100.0/total_pixels), max_diff,
                    avg_diff_wrong, avg_diff_total);

        if (!strstr (argv[2], "broken"))
        {
            GeglNode *save;
            gchar *debug_path = g_malloc (strlen (argv[2])+16);

            memcpy (debug_path, argv[2], strlen (argv[2])+1);
            memcpy (debug_path + strlen(argv[2])-4, "-diff.png", 11);

            save = gegl_node_new_child (gegl,
                                        "operation", "gegl:png-save",
                                        "path", debug_path,
                                        NULL);
            gegl_node_link (comparison, save);
            gegl_node_process (save);


            /*gegl_graph (sink=gegl_node ("gegl:png-save",
                                        "path", debug_path, NULL,
                                        gegl_node ("gegl:buffer-source", "buffer", debug_buf, NULL)));*/
            if (max_diff > 1.5)
                return ERROR_PIXELS_DIFFERENT;
        }
        if (strstr (argv[2], "broken"))
            g_print ("because the test is expected to fail ");
        else
            g_print ("because the error is small ");
        g_print ("we'll say ");
    }

    g_print ("%s and %s are identical\n", argv[1], argv[2]);

    g_object_unref (gegl);

    gegl_exit ();
    return SUCCESS;
}
static void
photos_print_operation_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr)
{
  PhotosPrintOperation *self = PHOTOS_PRINT_OPERATION (operation);
  GeglRectangle bbox;
  GdkPixbuf *pixbuf = NULL;
  GtkPageSetup *page_setup;
  cairo_t *cr;
  gdouble dpi_x;
  gdouble dpi_y;
  gdouble page_height;
  gdouble page_width;
  gdouble scale_factor_n;
  gdouble x0;
  gdouble y0;

  scale_factor_n = self->scale_factor / 100.0;
  bbox = gegl_node_get_bounding_box (self->node);

  dpi_x = gtk_print_context_get_dpi_x (context);
  dpi_y = gtk_print_context_get_dpi_x (context);

  switch (self->unit)
    {
    case GTK_UNIT_INCH:
      x0 = self->left_margin * dpi_x;
      y0 = self->top_margin  * dpi_y;
      break;
    case GTK_UNIT_MM:
      x0 = self->left_margin * dpi_x / 25.4;
      y0 = self->top_margin  * dpi_y / 25.4;
      break;
    case GTK_UNIT_NONE:
    case GTK_UNIT_POINTS:
    default:
      g_assert_not_reached ();
    }

  cr = gtk_print_context_get_cairo_context (context);
  cairo_translate (cr, x0, y0);

  page_setup = gtk_print_context_get_page_setup (context);
  page_width =  gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS);
  page_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS);

  /* This is both a workaround for a bug in cairo's PDF backend, and
   * a way to ensure we are not printing outside the page margins.
   */
  cairo_rectangle (cr,
                   0,
                   0,
                   MIN (bbox.width * scale_factor_n, page_width),
                   MIN (bbox.height * scale_factor_n, page_height));
  cairo_clip (cr);
  cairo_scale (cr, scale_factor_n, scale_factor_n);

  pixbuf = photos_utils_create_pixbuf_from_node (self->node);
  if (pixbuf == NULL)
    goto out;

  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, 0.0);
  cairo_paint (cr);

 out:
  g_clear_object (&pixbuf);
}
Пример #19
0
gint layer_node_selected (gpointer host, GeglEditor* editor, gint node_id)
{
  GeglEditorLayer*	self = (GeglEditorLayer*)host;
  GeglNode*		node = NULL;
  GSList*		pair = self->pairs;
  for(;pair != NULL; pair = pair->next)
    {
      node_id_pair*	data = pair->data;
      if(data->id == node_id)
	{
	  node = data->node;
	  break;
	}
    }

  g_assert(node != NULL);

  GeglNode** nodes;
  const gchar** pads;
  gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);

  int i;
  g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);
  for(i = 0; i < num; i++)
    {
      g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
    }
  g_print("Input from: %s\n", gegl_node_get_operation(gegl_node_get_producer(node, "input", NULL)));

  //  g_print("selected: %s\n", gegl_node_get_operation(node));

  guint		n_props;
  GParamSpec**	properties = gegl_operation_list_properties(gegl_node_get_operation(node), &n_props);

  //TODO: only create enough columns for the properties which will actually be included (i.e. ignoring GeglBuffer props)
  GtkTable	*prop_table = GTK_TABLE(gtk_table_new(2, n_props, FALSE));

  int d;
  for(d = 0, i = 0; i < n_props; i++, d++)
    {
      GParamSpec*	prop = properties[i];
      GType		type = prop->value_type;
      const gchar*		name = prop->name;

      GtkWidget*	name_label = gtk_label_new(name);
      gtk_misc_set_alignment(GTK_MISC(name_label), 0, 0.5);


      GtkWidget*	value_entry = gtk_entry_new();

      gchar buf[256] = "*";	//can probably be smaller; In fact, can probably do this without sprintf and a buffer. TODO: look at g_string

      gint	i_value;
      gdouble	d_value;
      gchar*	str_value;
      gboolean skip = FALSE;

      switch(type)
	{
	case G_TYPE_INT:
	  gegl_node_get(node, name, &i_value, NULL);
	  sprintf(buf, "%d", i_value);
	  break;
	case G_TYPE_DOUBLE:
	  gegl_node_get(node, name, &d_value, NULL);
	  sprintf(buf, "%.3f", d_value);
	  break;
	case G_TYPE_STRING:
	  gegl_node_get(node, name, &str_value, NULL);
	  sprintf(buf, "%s", str_value);
	  break;
	}

      if(type == GEGL_TYPE_BUFFER) {
	skip = TRUE;
	d--;
      } else if( type == GEGL_TYPE_COLOR) {
	skip = TRUE;
	GtkWidget *color_button = gtk_button_new_with_label("Select");

	select_color_info* info = malloc(sizeof(select_color_info));
	info->node = node;
	info->property = name;
	info->layer = self;

	g_signal_connect(color_button, "clicked", (GCallback)select_color, info);

	gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
	gtk_table_attach(prop_table, color_button, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
      }

      if(!skip)
	{
	  gtk_entry_set_text(GTK_ENTRY(value_entry), buf);

	  gtk_entry_set_width_chars(GTK_ENTRY(value_entry), 2);
	  struct text_prop_data	*data = malloc(sizeof(struct text_prop_data));	//TODO store this in a list and free it when the node is deselected
	  data->node		      = node;
	  data->property		      = name;
	  data->prop_type		      = type;
	  data->layer		      = self;
	  g_signal_connect(value_entry, "activate", G_CALLBACK(text_property_changed), data);

	  gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
	  gtk_table_attach(prop_table, value_entry, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
	}
    }

  //  gegl_node_process(node);
  GeglGtkView *gtk_view = gegl_gtk_view_new_for_node(node);

  GeglRectangle rect = gegl_node_get_bounding_box(node);

  if(gegl_rectangle_is_infinite_plane(&rect))
    {
      gegl_gtk_view_set_autoscale_policy(gtk_view, GEGL_GTK_VIEW_AUTOSCALE_DISABLED);
      gegl_gtk_view_set_scale(gtk_view, 1.0);
      g_print("Disable autoscale: scale=%f, x=%f, y=%f\n", gegl_gtk_view_get_scale(gtk_view),
      gegl_gtk_view_get_x(gtk_view), gegl_gtk_view_get_y(gtk_view));
    }

  gtk_widget_show(GTK_WIDGET(gtk_view));

  //TODO: draw checkerboard under preview to indicate transparency

  gtk_box_pack_start(GTK_BOX(self->prop_box), GTK_WIDGET(prop_table), FALSE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(self->prop_box), GTK_WIDGET(gtk_view), TRUE, TRUE, 10);

  GtkWidget* label = gtk_label_new("Click the image\nto open in a\nnew window");
  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
  gtk_box_pack_start(GTK_BOX(self->prop_box), label, FALSE, TRUE, 10);

  gtk_widget_show_all(self->prop_box);
}