Nautilus html thumbs


I am trying to implement Nautilus html thumbs using gtkhtml. I decided
to render the html file to a widget and than save it to a file. I have a
few problems with that. I need to be able to render the widget off the
screen and still be able to save it. 

I looked into fake_expose_widget()  from 
and also from

I am able to render simple widgets such as lables, and buttons. More
complex widgets such as containers need special handling, that I can do.
I need to loop
through each component and render it. In the case of gtkhtml, I do not
know the structure of the widget and it does not get rendered when I
call fake_expose_widget() on it. 

Is there a known fix? Is there any other way to save the canvas? (gnome
print maybe?)

-Nadav Rotem
Attached: the code
#include <gtk/gtk.h>
#include "gtkhtml.h"
#include "stdio.h"

#include <metacity-private/util.h>
#include <metacity-private/theme.h>
#include <metacity-private/theme-parser.h>
#include <metacity-private/preview-widget.h>

//#include "gtkhtml.h"
//#include "htmlurl.h"
//#include "htmlengine.h"
//#include "gtkhtml-embedded.h"
//#include "gtkhtml-properties.h"
//#include "gtkhtmldebug.h"

#define BUFF_SIZE 1024*8
void call_snap(void);

#define ICON_SIZE_WIDTH 800
#define ICON_SIZE_HEIGHT 600

typedef struct {
  FILE *fil;
  GtkHTMLStream *handle;
} FileInProgress;

static GdkPixbuf *
new_pixbuf_from_widget (GtkWidget *widget);
static void
hbox_foreach (GtkWidget *widget,
	      gpointer   data);

static GtkHTML *html;
static GtkHTMLStream *handle = NULL;
  GdkVisual *visual;

static void
fake_expose_widget (GtkWidget *widget,
		    GdkPixmap *pixmap)
  GdkWindow *tmp_window;
  GdkEventExpose event;

  event.type = GDK_EXPOSE;
  event.window = pixmap;
  event.send_event = FALSE;
  event.area = widget->allocation;
  event.region = NULL;
  event.count = 0;

  tmp_window = widget->window;
  widget->window = pixmap;
  gtk_widget_send_expose (widget, (GdkEvent *) &event);
  widget->window = tmp_window;

stream_from_file (char *filename)
  if (filename)
      FILE *input_stream = fopen (filename, "r");
      if (!input_stream)
          perror ("Couldn't load input file");
          return NULL;
      return input_stream;
  return NULL;
char *
buffer_from_file (FILE * stream)
  unsigned char fread_buffer[BUFF_SIZE];
  unsigned char *buffer;
  size_t nread, total_read, avail_size;
  if (stream == NULL)
    return NULL;
  buffer = g_new0 (unsigned char, BUFF_SIZE);
  avail_size = BUFF_SIZE;
  total_read = nread = 0;
  while ((nread =
          fread (fread_buffer, sizeof (unsigned char), sizeof (fread_buffer),
                 stream)) > 0)
      if (nread + total_read > avail_size)
          avail_size *= 2;
          buffer = g_renew (unsigned char, buffer, avail_size);
      strncpy (buffer + total_read, fread_buffer, nread);
      total_read += nread;
  fclose (stream);
  return buffer;

  GtkWidget *app;
  GtkWidget *canvas;
  GtkWidget *html_widget;
  GtkWidget *snap_now;
  GtkRequisition requisition;
  GtkAllocation allocation;
  GdkPixbuf *pixbuf;
  GdkPixbuf *pixbuf_scaled;
	GtkWidget *hbox;
  GtkWidget *control_label;
main (int argc, char *argv[])

  gtk_init (&argc, &argv);
  app = gtk_window_new (GTK_WINDOW_TOPLEVEL);

   hbox =  gtk_hbox_new (FALSE, 6); //meta_preview_new (); 
   gtk_container_add (GTK_CONTAINER (app), hbox);  

   html_widget = gtk_html_new ();
	html = GTK_HTML (html_widget);
	gtk_html_set_allow_frameset (html, TRUE);
	gtk_html_load_empty (html);                                  

//html_widget = gtk_button_new_with_label ("Yomama");		

   gtk_container_add (GTK_CONTAINER (hbox), html_widget);
   gtk_widget_show_all (hbox);
   gtk_widget_realize (html_widget);
   gtk_widget_map (html_widget); //??

  gtk_window_set_default_size (GTK_WINDOW (app), ICON_SIZE_WIDTH, ICON_SIZE_HEIGHT);
   char *file_data =  buffer_from_file (stream_from_file ("test10.html"));
	handle = gtk_html_begin_content (html, "text/html; charset=utf-8");	
	gtk_html_write (html, handle, file_data, strlen(file_data));
	gtk_html_end (html, handle, GTK_HTML_STREAM_OK);

  gtk_widget_size_request (app, &requisition);
  allocation.x = 0;
  allocation.y = 0;
  allocation.width = 800;
  allocation.height = 600;
  gtk_widget_size_allocate (app, &allocation);
  gtk_widget_size_request (app, &requisition);
  g_print ("requisition: %d %d\n", requisition.width, requisition.height);

  g_idle_add(G_CALLBACK (call_snap),NULL); 

     gtk_main ();
  return 0;

void call_snap(void)
visual = gtk_widget_get_visual (app);
GdkPixmap *pixmap = gdk_pixmap_new (NULL, ICON_SIZE_WIDTH, ICON_SIZE_HEIGHT, gdk_visual_get_best_depth());
gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), gtk_widget_get_colormap (app));
gtk_widget_ensure_style (app);

fake_expose_widget (app,pixmap);
fake_expose_widget (hbox,pixmap);
fake_expose_widget (html_widget,pixmap);
fake_expose_widget (html->engine,pixmap);

pixbuf= gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, ICON_SIZE_WIDTH, ICON_SIZE_HEIGHT);

pixbuf_scaled =  gdk_pixbuf_scale_simple     (pixbuf,
pixbuf_scaled = new_pixbuf_from_widget (html_widget);

gdk_pixbuf_save (pixbuf_scaled,"yomama.jpg", "jpeg", NULL,
                 "quality", "100", NULL);


/*******************************Epiphany code *******/

/* We should probably experiment some more with this.
 * Right now the rendered icon is pretty good for most
 * themes. However, the icon is slightly large for themes
 * with large toolbar icons.
static GdkPixbuf *
new_pixbuf_from_widget (GtkWidget *widget)
  GtkWidget *window;
  GdkPixbuf *pixbuf;
  GtkRequisition requisition;
  GtkAllocation allocation;
  GdkPixmap *pixmap;
  GdkVisual *visual;
  gint icon_width;
  gint icon_height;

  icon_width = 32;

  if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_default (), 
      icon_height = 32;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_add (GTK_CONTAINER (window), widget);
  gtk_widget_realize (window);
  gtk_widget_show (widget);
  gtk_widget_realize (widget);
  gtk_widget_map (widget);

  /* Gtk will never set the width or height of a window to 0. So setting the width to
   * 0 and than getting it will provide us with the minimum width needed to render
   * the icon correctly, without any additional window background noise.
   * This is needed mostly for pixmap based themes.
  gtk_window_set_default_size (GTK_WINDOW (window), icon_width, icon_height);
  gtk_window_get_size (GTK_WINDOW (window),&icon_width, &icon_height);

  gtk_widget_size_request (window, &requisition);
  allocation.x = 0;
  allocation.y = 0;
  allocation.width = icon_width;
  allocation.height = icon_height;
  gtk_widget_size_allocate (window, &allocation);
  gtk_widget_size_request (window, &requisition);
  /* Create a pixmap */
  visual = gtk_widget_get_visual (window);
  pixmap = gdk_pixmap_new (NULL, icon_width, icon_height, gdk_visual_get_best_depth());
  gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), gtk_widget_get_colormap (window));

  /* Draw the window */
  gtk_widget_ensure_style (window);
  g_assert (window->style);
  g_assert (window->style->font_desc);
  fake_expose_widget (window, pixmap);
  fake_expose_widget (widget, pixmap);
  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, icon_width, icon_height);
  gdk_pixbuf_get_from_drawable (pixbuf, pixmap, NULL, 0, 0, 0, 0, icon_width, icon_height);

  return pixbuf;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]