Nautilus html thumbs



Hi,

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 
control-center-2.5.3/capplets/common/theme-thumbnail.c
and also from
/epiphany-1.1.9/lib/egg/egg-editable-toolbar.c

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;
}

                                                                                                                             
FILE *
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;
                                                                                                                           
int
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);  
   gtk_widget_realize(app);
   gtk_widget_realize(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);

  //gtk_widget_show_all(app);
	
  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,
                                             320,
                                             200,
                                             GDK_INTERP_BILINEAR);
pixbuf_scaled = new_pixbuf_from_widget (html_widget);

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


gtk_main_quit();
}



/*******************************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 (), 
					  GTK_ICON_SIZE_LARGE_TOOLBAR,
					  NULL, 
					  &icon_height))
    {
      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]