Nautilus html thumbs
- From: Nadav Rotem <nadavrotem mail ru>
- To: gnome-devel-list gnome org
- Subject: Nautilus html thumbs
- Date: Tue, 24 Feb 2004 22:42:17 +0200
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]