From gnome-devel-list Tue Feb 24 20:42:17 2004 From: Nadav Rotem Date: Tue, 24 Feb 2004 20:42:17 +0000 To: gnome-devel-list Subject: Nautilus html thumbs Message-Id: <1077655336.2116.1.camel () gringo> X-MARC-Message: https://marc.info/?l=gnome-devel-list&m=107765566503370 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--=-NgQBqeSsrQTsbOLRLVlI" --=-NgQBqeSsrQTsbOLRLVlI Content-Type: text/plain Content-Transfer-Encoding: 7bit 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 --=-NgQBqeSsrQTsbOLRLVlI Content-Disposition: attachment; filename=new.c Content-Type: text/x-c; name=new.c; charset=UTF-8 Content-Transfer-Encoding: 7bit #include #include "gtkhtml.h" #include "stdio.h" #include #include #include #include //#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; } --=-NgQBqeSsrQTsbOLRLVlI-- _______________________________________________ gnome-devel-list mailing list gnome-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gnome-devel-list