Exemple #1
0
void expedia_snip ( const gchar *file )
{
  /* Load the pixbuf */
  GError *gx = NULL;
  GdkPixbuf *old, *cropped;
  gint width, height;

  old = gdk_pixbuf_new_from_file ( file, &gx );
  if (gx)
  {
    g_warning ( _("Couldn't open EXPEDIA image file (right after successful download! Please report and delete image file!): %s"), gx->message );
    g_error_free ( gx );
    return;
  }

  width = gdk_pixbuf_get_width ( old );
  height = gdk_pixbuf_get_height ( old );

  cropped = gdk_pixbuf_new_subpixbuf ( old, WIDTH_BUFFER, HEIGHT_BUFFER,
                              width - 2*WIDTH_BUFFER, height - 2*HEIGHT_BUFFER );

  gdk_pixbuf_save ( cropped, file, "png", &gx, NULL );
  if ( gx ) {
    g_warning ( _("Couldn't save EXPEDIA image file (right after successful download! Please report and delete image file!): %s"), gx->message );
    g_error_free ( gx );
  }

  g_object_unref ( cropped );
  g_object_unref ( old );
}
static void
load_sliced_image (GSimpleAsyncResult *result,
                   GObject *object,
                   GCancellable *cancellable)
{
  AsyncImageData *data;
  GList *res = NULL;
  GdkPixbuf *pix;
  gint width, height, y, x;

  g_assert (!cancellable);

  data = g_object_get_data (G_OBJECT (result), "load_sliced_image");
  g_assert (data);

  if (!(pix = gdk_pixbuf_new_from_file (data->path, NULL)))
    return;

  width = gdk_pixbuf_get_width (pix);
  height = gdk_pixbuf_get_height (pix);
  for (y = 0; y < height; y += data->grid_height)
    {
      for (x = 0; x < width; x += data->grid_width)
        {
          GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y, data->grid_width, data->grid_height);
          g_assert (pixbuf != NULL);
          res = g_list_append (res, pixbuf);
        }
    }
  /* We don't need the original pixbuf anymore, though the subpixbufs
     will hold a reference. */
  g_object_unref (pix);
  g_simple_async_result_set_op_res_gpointer (result, res, free_glist_unref_gobjects);
}
static void
load_sliced_image (GSimpleAsyncResult *result,
                   GObject *object,
                   GCancellable *cancellable)
{
  AsyncImageData *data;
  GList *res = NULL;
  GdkPixbuf *pix;
  gint width, height, y, x;
  GdkPixbufLoader *loader;
  gchar *buffer = NULL;
  gsize length;

  g_assert (!cancellable);

  data = g_object_get_data (G_OBJECT (result), "load_sliced_image");
  g_assert (data);

  loader = gdk_pixbuf_loader_new ();
  g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data);

  if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, NULL))
    goto out;

  if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, NULL))
    goto out;

  if (!gdk_pixbuf_loader_close (loader, NULL))
    goto out;

  pix = gdk_pixbuf_loader_get_pixbuf (loader);
  width = gdk_pixbuf_get_width (pix);
  height = gdk_pixbuf_get_height (pix);
  for (y = 0; y < height; y += data->grid_height * data->scale_factor)
    {
      for (x = 0; x < width; x += data->grid_width * data->scale_factor)
        {
          GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y,
                                                        data->grid_width * data->scale_factor,
                                                        data->grid_height * data->scale_factor);
          g_assert (pixbuf != NULL);
          res = g_list_append (res, pixbuf);
        }
    }

 out:
  /* We don't need the original pixbuf anymore, which is owned by the loader,
   * though the subpixbufs will hold a reference. */
  g_object_unref (loader);
  g_free (buffer);
  g_simple_async_result_set_op_res_gpointer (result, res, free_glist_unref_gobjects);
}
GdkPixbuf *
um_crop_area_get_picture (UmCropArea *area)
{
        gint width, height;

        width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
        height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
        width = MIN (area->priv->crop.width, width - area->priv->crop.x);
        height = MIN (area->priv->crop.height, height - area->priv->crop.y);

        return gdk_pixbuf_new_subpixbuf (area->priv->browse_pixbuf,
                                         area->priv->crop.x,
                                         area->priv->crop.y,
                                         width, height);
}
static GdkPixbuf *
ar_card_theme_sliced_get_card_pixbuf (ArCardTheme *card_theme,
                                         int card_id)
{
  ArCardThemePreimage *preimage_card_theme = (ArCardThemePreimage *) card_theme;
  ArCardThemeSliced *theme = (ArCardThemeSliced *) card_theme;
  GdkPixbuf *subpixbuf, *card_pixbuf;
  int suit, rank;

  if (G_UNLIKELY (card_id == AR_CARD_SLOT)) {
    subpixbuf = games_preimage_render (preimage_card_theme->slot_preimage,
                                       preimage_card_theme->card_size.width,
                                       preimage_card_theme->card_size.height);

    return subpixbuf;
  }

  suit = card_id / 13;
  rank = card_id % 13;

  if (!theme->source &&
      (!theme->scalable ||
       !ar_card_theme_sliced_prerender_scalable (theme)))
    return NULL;

  subpixbuf = gdk_pixbuf_new_subpixbuf (theme->source,
                                        rank *
                                        theme->subsize.width,
                                        suit *
                                        theme->subsize.height,
                                        theme->subsize.width,
                                        theme->subsize.height);
  if (theme->scalable) {
    card_pixbuf = subpixbuf;
  } else {
    card_pixbuf = gdk_pixbuf_scale_simple (subpixbuf,
                                           preimage_card_theme->card_size.width,
                                           preimage_card_theme->card_size.height,
                                           GDK_INTERP_BILINEAR);
    g_object_unref (subpixbuf);
  }

  return card_pixbuf;
}
/*
 * um_crop_area_get_picture:
 * @area: a #UmCropArea
 *
 * Returns the cropped image, or the whole image if no crop region has been
 * set, as a #GdkPixbuf.
 *
 * Returns: a #GdkPixbuf
 */
GdkPixbuf *
um_crop_area_get_picture (UmCropArea *area)
{
        UmCropAreaPrivate *priv = um_crop_area_get_instance_private (area);
        gint width, height;

        if (priv->browse_pixbuf == NULL)
                return NULL;

        width = gdk_pixbuf_get_width (priv->browse_pixbuf);
        height = gdk_pixbuf_get_height (priv->browse_pixbuf);
        width = MIN (priv->crop.width, width - priv->crop.x);
        height = MIN (priv->crop.height, height - priv->crop.y);

        return gdk_pixbuf_new_subpixbuf (priv->browse_pixbuf,
                                         priv->crop.x,
                                         priv->crop.y,
                                         width, height);
}
static GdkPixbuf *
soi_get_cropped_pixbuf (SheetObjectImage *soi, GdkPixbuf *pixbuf)
{
	int width  = gdk_pixbuf_get_width (pixbuf);
	int height = gdk_pixbuf_get_height (pixbuf);
	int sub_x = rint (soi->crop_left * width);
	int sub_y = rint (soi->crop_top * height);
	int sub_width  = rint (width *
			       (1. - soi->crop_left - soi->crop_right));
	int sub_height = rint (height *
			       (1. - soi->crop_top - soi->crop_bottom));
	GdkPixbuf *sub = gdk_pixbuf_new_subpixbuf (pixbuf, sub_x, sub_y,
						   sub_width, sub_height);
	if (sub) {
		g_object_unref (G_OBJECT (pixbuf));
		pixbuf = sub;
	}
	return pixbuf;
}
Exemple #8
0
static GdkPixbuf *
extract_frame (GdkPixbuf *grid_pixbuf,
	       int x,
	       int y,
	       int size)
{
	GdkPixbuf *pixbuf;

	if (x + size > gdk_pixbuf_get_width (grid_pixbuf) ||
	    y + size > gdk_pixbuf_get_height (grid_pixbuf))
	{
		return NULL;
	}

	pixbuf = gdk_pixbuf_new_subpixbuf (grid_pixbuf,
					   x, y,
					   size, size);
	g_return_val_if_fail (pixbuf != NULL, NULL);

	return pixbuf;
}
Exemple #9
0
GR_UnixImage *GR_UnixImage::makeSubimage(const std::string & name,
                           UT_sint32 x, UT_sint32 y,
                           UT_sint32 width, UT_sint32 height) const
{
    if(m_image == NULL)
	    return NULL;
	GR_UnixImage * pImage = new GR_UnixImage(name.c_str());

    pImage->m_image = gdk_pixbuf_new_subpixbuf(m_image,x,y,width,height);
//
//  gdk_pixbuf_new_subpixbuf shares pixels with the original pixbuf and
//  so puts a reference on m_image.

	g_object_unref(G_OBJECT(m_image));
	UT_ASSERT(G_OBJECT(m_image)->ref_count == 1);
//
// Make a copy so we don't have to worry about ref counting the orginal.
//
	pImage->m_image = gdk_pixbuf_copy(pImage->m_image);
    return pImage;
}
Exemple #10
0
void
xmr_button_set_image_from_pixbuf(XmrButton *button, GdkPixbuf *pixbuf)
{
	XmrButtonPrivate *priv;
	gint width, height;
	gint i;

	g_return_if_fail( button != NULL && pixbuf != NULL);

	priv = button->priv;

	width = gdk_pixbuf_get_width(pixbuf)/LAST_STATE;
	height = gdk_pixbuf_get_height(pixbuf);
	
	xmr_button_unref_images(button);

	for(i=0; i<LAST_STATE; i++)
		priv->images[i] = gdk_pixbuf_new_subpixbuf(pixbuf, width*i, 0, width, height);

	gtk_widget_set_size_request(GTK_WIDGET(button), width, height);
	gtk_widget_queue_draw(GTK_WIDGET(button));
}
Exemple #11
0
int update_icon(struct named_element *e, const char *value)
{
        GdkPixbuf *icon;
        int index = value[1] - '!';
        int x = (20 + 1) * APRS_IMG_MULT * (index % 16);
        int y = (20 + 1) * APRS_IMG_MULT * (index / 16);
        GdkPixbuf *source = value[0] == '\\' ? aprs_sec_img : aprs_pri_img;

        if (value[0]) {
                icon = gdk_pixbuf_new_subpixbuf(source,
                                                x + APRS_IMG_MULT,
                                                y + APRS_IMG_MULT,
                                                20 * APRS_IMG_MULT,
                                                20 * APRS_IMG_MULT);
        } else {
                icon = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 0, 8, 20, 20);
                gdk_pixbuf_fill(icon, FILL_BLACK);
        }
        gtk_image_set_from_pixbuf(GTK_IMAGE(e->widget), icon);
        g_object_unref(icon);

        return 0;
}
Exemple #12
0
static void
load_sliced_image (GTask        *result,
                   gpointer      object,
                   gpointer      task_data,
                   GCancellable *cancellable)
{
  AsyncImageData *data;
  GList *res = NULL;
  GdkPixbuf *pix;
  gint width, height, y, x;

  g_assert (!cancellable);

  data = task_data;
  g_assert (data);

  if (!(pix = gdk_pixbuf_new_from_file (data->path, NULL)))
    return;

  width = gdk_pixbuf_get_width (pix);
  height = gdk_pixbuf_get_height (pix);
  for (y = 0; y < height; y += data->grid_height)
    {
      for (x = 0; x < width; x += data->grid_width)
        {
          GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y, data->grid_width, data->grid_height);
          g_assert (pixbuf != NULL);
          res = g_list_prepend (res, pixbuf);
        }
    }
  res = g_list_reverse (res);
  /* We don't need the original pixbuf anymore, though the subpixbufs
     will hold a reference. */
  g_object_unref (pix);
  g_task_return_pointer (result, res, free_glist_unref_gobjects);
}
Exemple #13
0
// Copy LCD pixuf into B&W pixbuf
GdkPixbuf* hid_copy_lcd(void)
{
	int i, j, k;
	uint8_t *lcd_bitmap = &tihw.ram[tihw.lcd_adr];	
	uint8_t *lcd_buf = (uint8_t *)lcd_bytmap;
	guchar *p;

	tihw.lcd_ptr = (char *) &tihw.ram[tihw.lcd_adr];	

	// convert the bitmap screen to a bytemap screen and grayscalize
	memset(lcd_bytmap, 0, LCDMEM_H*LCDMEM_W);	
	for(j = 0, k = 0; k < LCDMEM_H; k++)
	{
		for(i = 0; i < LCDMEM_W/8; i++, lcd_bitmap++) 
		{
			lcd_bytmap[j++] = convtab[(*lcd_bitmap << 1)  ];
			lcd_bytmap[j++] = convtab[(*lcd_bitmap << 1)+1];
		}
	}

	// and copy
	for(j = 0; j < LCDMEM_H; j++)
	{
		for (i = 0; i < LCDMEM_W; i++) 
		{
			p = li.pixels + j * li.rowstride + i * li.n_channels;
			
			p[0] = *lcd_buf ? 0x00: 0xff;
			p[1] = *lcd_buf ? 0x00: 0xff;
			p[2] = *lcd_buf ? 0x00: 0xff;
			lcd_buf++;
		}
	}

	return gdk_pixbuf_new_subpixbuf(lcd_mem, 0, 0, tihw.lcd_w, tihw.lcd_h);
}
int main(int argc, char** argv) {
    //start gnome_init
    initGUI(argc, argv);
    cellsWide = DEFAULT_WIDTH / PIX_PER_CELL;

    //GUI components
    GtkWidget *window;
    GtkWidget *imageEventBox, *mainHBox, *sideBox, *quitButton,
              *settingFrame, *resetButton, *sideVBox, *widthFrame,
              *saveButton, *hSep, *label, *lowerSideVBox, *checkButton,
              *rulesFrame, *rulesClearButton, *rulesSetButton,
              *rulesHBox, *rulesVBox;
    GdkPixbuf *icon_buf_16, *icon_buf_32, *icon_buf_48,
              *icon_buf_64, *icon_buf_128, *bg;

    GList *icons = NULL;

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    //load icons from files	
    icon_buf_16 = gdk_pixbuf_new_from_file(ICON_16, NULL);
    icon_buf_32 = gdk_pixbuf_new_from_file(ICON_32, NULL);
    icon_buf_48 = gdk_pixbuf_new_from_file(ICON_48, NULL);
    icon_buf_64 = gdk_pixbuf_new_from_file(ICON_64, NULL);
    icon_buf_128 = gdk_pixbuf_new_from_file(ICON_128, NULL);

    //tell gnome to use these icons
    icons = g_list_append(icons, icon_buf_16);
    icons = g_list_append(icons, icon_buf_32);
    icons = g_list_append(icons, icon_buf_48);
    icons = g_list_append(icons, icon_buf_64);
    icons = g_list_append(icons, icon_buf_128);
    gtk_window_set_icon_list(GTK_WINDOW(window), icons);

    //connect the delete_event signal to the delete_event function
    g_signal_connect (G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);

    //here follows formatting, packing, etc of gtk widgets
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    gtk_window_set_title(GTK_WINDOW(window), "Cellular Automata");

    widthAdjust = gtk_spin_button_new_with_range(WIDTH_LOWER, WIDTH_UPPER, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widthAdjust), DEFAULT_WIDTH);
    widthFrame = gtk_frame_new("Set Width");
    gtk_container_add(GTK_CONTAINER(widthFrame), widthAdjust);
    gtk_container_set_border_width(GTK_CONTAINER(widthFrame), 10);

    ruleAdjust = gtk_spin_button_new_with_range(0, 255, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(ruleAdjust), 30);
    settingFrame = gtk_frame_new("Set Rule #");
    gtk_container_add(GTK_CONTAINER(settingFrame), ruleAdjust);
    gtk_container_set_border_width (GTK_CONTAINER(settingFrame), 10);
    bg = gdk_pixbuf_new_from_file("./data/cellular_automata.png", NULL);
    imagebuf = gdk_pixbuf_scale_simple(bg, WIDTH, HEIGHT, GDK_INTERP_BILINEAR);
    mainImage = gtk_image_new_from_pixbuf(imagebuf);

    imageEventBox = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(imageEventBox), mainImage);
    mainHBox = gtk_hbox_new(FALSE, 0);
    sideVBox = gtk_vbox_new(FALSE, 0);
    lowerSideVBox = gtk_vbox_new(TRUE, 0);
    sideBox = gtk_vbox_new(TRUE, 0);
    checkButton = gtk_check_button_new_with_mnemonic("_Autosave Images");
    quitButton = gtk_button_new_from_stock (GTK_STOCK_QUIT);
    startButton = gtk_button_new_with_mnemonic("_Start");
    stopButton = gtk_button_new_with_mnemonic ("_Stop");
    saveButton = gtk_button_new_from_stock(GTK_STOCK_SAVE);
    gtk_widget_set_sensitive(GTK_WIDGET(stopButton), FALSE);
    resetButton = gtk_button_new_with_mnemonic("_Reset");

    //connect the proper callback functions to the proper signals
    g_signal_connect_swapped (G_OBJECT(quitButton), "clicked", G_CALLBACK(gtk_main_quit), G_OBJECT (window));
    g_signal_connect_swapped (G_OBJECT(startButton),"clicked", G_CALLBACK(getLoopy), G_OBJECT(ruleAdjust));
    g_signal_connect_swapped (G_OBJECT(stopButton),"clicked", G_CALLBACK(stopLoopy), G_OBJECT(ruleAdjust));
    g_signal_connect_swapped (G_OBJECT(resetButton),"clicked", G_CALLBACK(resetImage), G_OBJECT(resetButton));
    g_signal_connect_swapped(G_OBJECT(ruleAdjust),"value-changed", G_CALLBACK(updateRule), GTK_WIDGET(ruleAdjust));
    g_signal_connect_swapped(G_OBJECT(widthAdjust),"value-changed", G_CALLBACK(initCA), GTK_WIDGET(widthAdjust));

    g_signal_connect_swapped(G_OBJECT(saveButton),"clicked", G_CALLBACK(getPic), GTK_WIDGET(saveButton));
    g_signal_connect_swapped(G_OBJECT(checkButton),"toggled", G_CALLBACK(toggleSave), GTK_WIDGET(checkButton));

    hSep = gtk_hseparator_new();
    label = gtk_label_new("Save Image");

    //load the meta-rule file names
    std::vector<std::string> rulesList;
    std::string rulesDir("./"), suff(".rules");
    getRulesList(rulesDir, rulesList, suff);

    rulesComboBox = gtk_combo_box_new_text();

    gtk_combo_box_append_text(GTK_COMBO_BOX(rulesComboBox), "Rule Set");

    for (uint i = 0; i < rulesList.size(); i++) {
        gtk_combo_box_append_text(GTK_COMBO_BOX(rulesComboBox), rulesList[i].c_str());
    }
    if (rulesList.size()) {
        gtk_combo_box_set_active(GTK_COMBO_BOX(rulesComboBox), 0);
    }

    rulesFrame = gtk_frame_new("Rule Change Controls");
    rulesHBox = gtk_hbox_new(FALSE, 0);
    rulesVBox = gtk_vbox_new(TRUE, 0);	
    rulesClearButton = gtk_button_new_with_mnemonic("_Clear Rules Rule");
    rulesSetButton = gtk_button_new_with_mnemonic("Set _Rules Rule");

    g_signal_connect(G_OBJECT(rulesComboBox), "changed", G_CALLBACK(combo_selected), rulesFrame);
    g_signal_connect_swapped(G_OBJECT(rulesClearButton), "clicked", G_CALLBACK(clearRules), G_OBJECT(rulesClearButton));

    autoResetButton = gtk_check_button_new_with_mnemonic("_Auto Reset on Dead Lines");
    randomizeLengthButton = gtk_check_button_new_with_mnemonic("Randomize _Time Between Rule Changes");

    g_signal_connect_swapped(G_OBJECT(autoResetButton), "toggled", G_CALLBACK(autoResetFunction), G_OBJECT(autoResetButton));
    g_signal_connect_swapped(G_OBJECT(randomizeLengthButton), "toggled", G_CALLBACK(randomizeLengthFunction), G_OBJECT(randomizeLengthButton));

    //pack the widgets into their proper containers
    gtk_box_pack_start(GTK_BOX(rulesHBox), rulesClearButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(rulesVBox), rulesComboBox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(rulesVBox), rulesHBox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(rulesVBox), autoResetButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(rulesVBox), randomizeLengthButton, FALSE, FALSE, 0);
    gtk_container_add(GTK_CONTAINER(rulesFrame), rulesVBox);
    gtk_box_pack_start(GTK_BOX(sideVBox), settingFrame, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(sideVBox), stopButton, FALSE, FALSE,0);
    gtk_box_pack_start(GTK_BOX(sideVBox), startButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(sideVBox), resetButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(sideBox), sideVBox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(sideVBox), rulesFrame, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(lowerSideVBox), label, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(lowerSideVBox), saveButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(lowerSideVBox), checkButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(lowerSideVBox), hSep, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(lowerSideVBox), quitButton, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(sideBox), lowerSideVBox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(mainHBox), sideBox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(mainHBox), imageEventBox, FALSE, FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), mainHBox);

    gtk_widget_show_all(window);

    //load black and white pixels into buffers
    blackb = gdk_pixbuf_new_subpixbuf(imagebuf, 0, 0, PIX_PER_CELL, PIX_PER_CELL);
    black = gdk_pixbuf_copy(blackb);
    gdk_pixbuf_fill(black, 0x000000ff);
    whiteb = gdk_pixbuf_new_subpixbuf(imagebuf, 0, 0, PIX_PER_CELL, PIX_PER_CELL);
    white = gdk_pixbuf_copy(whiteb);
    gdk_pixbuf_fill(white, 0xffffffff);

    //setup the cellular automaton=========================================
    initCA();

    //run the main loop of the program
    gtk_main();
    exit(0);
}
Exemple #15
0
void
create_object_pixmap(SheetObject *so, GtkWidget *parent,
                     GdkPixmap **pixmap, GdkBitmap **mask)
{
  GtkStyle *style;

  g_assert(so);
  g_assert(pixmap);
  g_assert(mask);
  
  style = gtk_widget_get_style(parent);
  
  if (so->pixmap != NULL)
  {
    *pixmap =
      gdk_pixmap_colormap_create_from_xpm_d(NULL,
                                            gtk_widget_get_colormap(parent),
                                            mask, 
                                            &style->bg[GTK_STATE_NORMAL],
                                            (gchar **)so->pixmap);
  }
  else
  {
    if (so->pixmap_file != NULL)
    {
      GdkPixbuf *pixbuf;
      GError *error = NULL;

      pixbuf = gdk_pixbuf_new_from_file(so->pixmap_file, &error);
      if (pixbuf != NULL)
      {
        int width = gdk_pixbuf_get_width (pixbuf);
        int height = gdk_pixbuf_get_height (pixbuf);
        if (width > 22 && prefs.fixed_icon_size) 
	{
	  GdkPixbuf *cropped;
	  g_warning ("Shape icon '%s' size wrong, cropped.", so->pixmap_file);
	  cropped = gdk_pixbuf_new_subpixbuf (pixbuf, 
	                                      (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0, 
					      22, height > 22 ? 22 : height);
	  g_object_unref (pixbuf);
	  pixbuf = cropped;
	}
        gdk_pixbuf_render_pixmap_and_mask(pixbuf, pixmap, mask, 1.0);
        g_object_unref(pixbuf);
      } else {
        message_warning ("%s", error->message);
        g_error_free (error);
	*pixmap = gdk_pixmap_colormap_create_from_xpm_d
	  (NULL,
	   gtk_widget_get_colormap(parent),
	   mask, 
	   &style->bg[GTK_STATE_NORMAL],
	   (gchar **)missing);
      }
    }
    else
    {
      *pixmap = NULL;
      *mask = NULL;
    }
  }
}
void
gkrellm_panel_create(GtkWidget *vbox, GkrellmMonitor *mon, GkrellmPanel *p)
	{
	GtkWidget		*hbox;
	GkrellmPiximage	piximage;
	GtkWidget   	*top_win = gkrellm_get_top_window();

	if (!vbox || !mon || !p)
		return;
	p->monitor = (gpointer) mon;
	if (!p->style)	/* gkrellm_panel_configure() may not have been called. */
		setup_panel_style(p, mon->privat->panel_style);

	if (!p->bg_piximage_override)
		{
		if (mon->privat->style_type == CHART_PANEL_TYPE)
			p->bg_piximage = gkrellm_bg_panel_piximage(mon->privat->style_id);
		else
			p->bg_piximage = gkrellm_bg_meter_piximage(mon->privat->style_id);
		}
	p->bg_piximage_override = FALSE;

	/* If not being called from rebuild or after a panel destroy, then panel
	|  still has a height that must be accounted for.
	*/
	if (p->h && p->shown)
		gkrellm_monitor_height_adjust(- p->h);
	p->h = p->h_configure;
	p->w = _GK.chart_width;

	if (p->hbox == NULL)
		{
		hbox = gtk_hbox_new(FALSE, 0);
		gtk_container_add (GTK_CONTAINER(vbox), hbox);
		p->hbox = hbox;
		p->drawing_area = gtk_drawing_area_new();
		p->layout = gtk_widget_create_pango_layout(top_win, NULL);
		gtk_widget_set_events (p->drawing_area, GDK_EXPOSURE_MASK
				| GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
				| GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK
				| GDK_POINTER_MOTION_MASK);
		gtk_box_pack_start(GTK_BOX(p->hbox), p->drawing_area,
				FALSE, FALSE, 0);
		gtk_widget_show(p->drawing_area);
		gtk_widget_show(hbox);
		p->shown = TRUE;
		gtk_widget_realize(hbox);
		gtk_widget_realize(p->drawing_area);
		panel_list = g_list_append(panel_list, p);
		p->y_mapped = -1;
		g_signal_connect(G_OBJECT (p->drawing_area), "size_allocate",
					G_CALLBACK(cb_panel_size_allocate), p);
		}
	gtk_widget_set_size_request(p->drawing_area, p->w, p->h);

	if (_GK.frame_left_panel_overlap > 0 || _GK.frame_right_panel_overlap > 0)
		{
		piximage.pixbuf = gdk_pixbuf_new_subpixbuf(p->bg_piximage->pixbuf,
				_GK.frame_left_panel_overlap, 0,
				gdk_pixbuf_get_width(p->bg_piximage->pixbuf)
							- _GK.frame_left_panel_overlap
							- _GK.frame_right_panel_overlap,
				gdk_pixbuf_get_height(p->bg_piximage->pixbuf));
		piximage.border = p->bg_piximage->border;
		gkrellm_border_adjust(&piximage.border,
				-_GK.frame_left_panel_overlap, -_GK.frame_right_panel_overlap,
				0, 0);
//		gkrellm_scale_piximage_to_pixmap(&piximage, &p->bg_clean_pixmap,
//				&p->bg_mask, p->w, p->h);
		gkrellm_scale_theme_background(&piximage, &p->bg_clean_pixmap,
				&p->bg_mask, p->w, p->h);
		g_object_unref(G_OBJECT(piximage.pixbuf));
		}
	else
		gkrellm_scale_theme_background(p->bg_piximage, &p->bg_clean_pixmap,
			&p->bg_mask, p->w, p->h);
//		gkrellm_scale_piximage_to_pixmap(p->bg_piximage, &p->bg_clean_pixmap,
//			&p->bg_mask, p->w, p->h);

	if (p->bg_text_layer_pixmap)
		g_object_unref(G_OBJECT(p->bg_text_layer_pixmap));
	p->bg_text_layer_pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1);
	if (p->bg_pixmap)
		g_object_unref(G_OBJECT(p->bg_pixmap));
	p->bg_pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1);
	if (p->pixmap)
		g_object_unref(G_OBJECT(p->pixmap));
	p->pixmap = gdk_pixmap_new(top_win->window, p->w, p->h, -1);

	if (p->shown)
		{
		gkrellm_monitor_height_adjust(p->h);
		gkrellm_pack_side_frames();
		}
	p->need_decal_overlap_check = TRUE;
	draw_panel(p, FALSE);
	gkrellm_panel_button_signals_connect(p);
	}
static void
load_sliced_image (GTask        *result,
                   gpointer      object,
                   gpointer      task_data,
                   GCancellable *cancellable)
{
  AsyncImageData *data;
  GList *res = NULL;
  GdkPixbuf *pix;
  gint width, height, y, x;
  GdkPixbufLoader *loader;
  GError *error = NULL;
  gchar *buffer = NULL;
  gsize length;

  g_assert (!cancellable);

  data = task_data;
  g_assert (data);

  loader = gdk_pixbuf_loader_new ();
  g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data);

  if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, &error))
    {
      g_warning ("Failed to open sliced image: %s", error->message);
      goto out;
    }

  if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, &error))
    {
      g_warning ("Failed to load image: %s", error->message);
      goto out;
    }

  if (!gdk_pixbuf_loader_close (loader, NULL))
    goto out;

  pix = gdk_pixbuf_loader_get_pixbuf (loader);
  width = gdk_pixbuf_get_width (pix);
  height = gdk_pixbuf_get_height (pix);
  for (y = 0; y < height; y += data->grid_height * data->scale_factor)
    {
      for (x = 0; x < width; x += data->grid_width * data->scale_factor)
        {
          GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y,
                                                        data->grid_width * data->scale_factor,
                                                        data->grid_height * data->scale_factor);
          g_assert (pixbuf != NULL);
          res = g_list_append (res, pixbuf);
        }
    }

 out:
  /* We don't need the original pixbuf anymore, which is owned by the loader,
   * though the subpixbufs will hold a reference. */
  g_object_unref (loader);
  g_free (buffer);
  g_clear_pointer (&error, g_error_free);
  g_task_return_pointer (result, res, free_glist_unref_gobjects);
}
/**
 * gpk_animated_icon_set_filename_tile:
 **/
gboolean
gpk_animated_icon_set_filename_tile (GpkAnimatedIcon *icon, GtkIconSize size, const gchar *name)
{
	gboolean ret;
	gint w, h;
	gint rows, cols;
	gint r, c, i;
	GdkPixbuf *pixbuf;

	g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
	g_return_val_if_fail (name != NULL, FALSE);

	/* have we already set the same icon */
	if (g_strcmp0 (icon->filename, name) == 0) {
		g_debug ("already set the same icon name %s, ignoring", name);
		return FALSE;
	}

	/* stop existing animation */
	gpk_animated_icon_enable_animation (icon, FALSE);

	/* save new value */
	g_free (icon->filename);
	icon->filename = g_strdup (name);

	/* do we need to unload */
	if (icon->frames != NULL) {
		gpk_animated_icon_free_pixbufs (icon);
	}

	g_debug ("loading from %s", name);
	ret = gtk_icon_size_lookup (size, &w, &h);
	if (!ret) {
		g_warning ("Can't get icon size info");
		return FALSE;
	}

	pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), name, w, 0, NULL);
	/* can't load from gnome-icon-theme */
	if (pixbuf == NULL) {
		g_debug ("can't load animation %s", name);
		return FALSE;
	}

	/* silly hack until we get some metadata */
	if (g_strcmp0 (name, "process-working") == 0) {
		w = gdk_pixbuf_get_width (pixbuf) / 8;
		h = gdk_pixbuf_get_height (pixbuf) / 4;
	}

	/* we failed to get a valid pixbuf */
	if (w == 0 || h == 0) {
		g_object_unref (pixbuf);
		return FALSE;
	}

	cols = gdk_pixbuf_get_width (pixbuf) / w;
	rows = gdk_pixbuf_get_height (pixbuf) / h;

	icon->frame_counter = 0;
	icon->number_frames = rows * cols;
	icon->frames = g_new (GdkPixbuf*, icon->number_frames);

	for (i = 0, r = 0; r < rows; r++)
		for (c = 0; c < cols; c++, i++) {
		icon->frames[i] = gdk_pixbuf_new_subpixbuf (pixbuf, c * w, r * h, w, h);
	}

	g_object_unref (pixbuf);

	/* enable new animation */
	gpk_animated_icon_enable_animation (icon, TRUE);

	return TRUE;
}
Exemple #19
0
GtkWidget *spinner_new(const gchar *path, gint interval)
{
	SpinnerData *sp;

	sp = g_new0(SpinnerData, 1);

	if (path)
		{
		gchar *pathl;
		GdkPixbuf *pb;
		gint n;
		gchar *buf;

		pathl = path_from_utf8(path);

		n = 0;
		buf = g_strdup_printf("%s%02d.png", pathl, n);
		while ((pb = gdk_pixbuf_new_from_file(buf, NULL)))
			{
			sp->list = g_list_append(sp->list, pb);

			n++;
			g_free(buf);
			buf = g_strdup_printf("%s%02d.png", pathl, n);
			}
		g_free(buf);

		g_free(pathl);
		}

	if (!sp->list)
		{
		GdkPixbuf *pb;
		gint n;
		gint w, h;

		pb = gdk_pixbuf_new_from_inline(-1, icon_spinner, FALSE, NULL);
		w = gdk_pixbuf_get_width(pb);
		h = gdk_pixbuf_get_height(pb) / SPINNER_FRAMES;
		for (n = 0; n < SPINNER_FRAMES; n++)
			{
			sp->list = g_list_append(sp->list,
						 gdk_pixbuf_new_subpixbuf(pb, 0, n * h, w, h));
			}
		/* pb pixels is inline static, so the subpixbufs in sp->list will be ok */
		g_object_unref(pb);
		}

	if (sp->list)
		{
		GdkPixbuf *pb;

		pb = sp->list->data;
		sp->image = gtk_image_new_from_pixbuf(pb);
		}
	else
		{
		sp->image = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DIALOG);
		}

	g_object_set_data(G_OBJECT(sp->image), "spinner", sp);

	g_signal_connect(G_OBJECT(sp->image), "destroy",
			 G_CALLBACK(spinner_destroy_cb), sp);

	spinner_set_timeout(sp, interval);

	return sp->image;
}
Exemple #20
0
/****************************************************************************
  Create a new sprite by cropping and taking only the given portion of
  the image.

  source gives the sprite that is to be cropped.

  x,y, width, height gives the rectangle to be cropped.  The pixel at
  position of the source sprite will be at (0,0) in the new sprite, and
  the new sprite will have dimensions (width, height).

  mask gives an additional mask to be used for clipping the new sprite.

  mask_offset_x, mask_offset_y is the offset of the mask relative to the
  origin of the source image.  The pixel at (mask_offset_x,mask_offset_y)
  in the mask image will be used to clip pixel (0,0) in the source image
  which is pixel (-x,-y) in the new image.
****************************************************************************/
struct sprite *crop_sprite(struct sprite *source,
			   int x, int y,
			   int width, int height,
			   struct sprite *mask,
			   int mask_offset_x, int mask_offset_y)
{
  GdkPixbuf *mypixbuf, *sub, *mask_pixbuf;

  /* First just crop the image. */
  if (x < 0) {
    width += x;
    x = 0;
  }
  if (y < 0) {
    height += y;
    y = 0;
  }
  width = CLIP(0, width, source->width - x);
  height = CLIP(0, height, source->height - y);
  sub = gdk_pixbuf_new_subpixbuf(sprite_get_pixbuf(source), x, y,
				 width, height);
  mypixbuf = gdk_pixbuf_copy(sub);
  g_object_unref(sub);

  /* Now mask.  This reduces the alpha of the final image proportional to the
   * alpha of the mask.  Thus if the mask has 50% alpha the final image will
   * be reduced by 50% alpha.  Note that the mask offset is in coordinates
   * relative to the clipped image not the final image. */
  if (mask
      && (mask_pixbuf = sprite_get_pixbuf(mask))
      && gdk_pixbuf_get_has_alpha(mask_pixbuf)) {
    int x1, y1;

    /* The mask offset is the offset of the mask relative to the origin
     * of the original source image.  For instance when cropping with
     * blending sprites the offset is always 0.  Here we convert the
     * coordinates so that they are relative to the origin of the new
     * (cropped) image. */
    mask_offset_x -= x;
    mask_offset_y -= y;

    width = CLIP(0, width, mask->width + mask_offset_x);
    height = CLIP(0, height, mask->height + mask_offset_y);

    if (!gdk_pixbuf_get_has_alpha(mypixbuf)) {
      GdkPixbuf *p2 = mypixbuf;

      mypixbuf = gdk_pixbuf_add_alpha(mypixbuf, FALSE, 0, 0, 0);
      g_object_unref(p2);
    }

    for (x1 = 0; x1 < width; x1++) {
      for (y1 = 0; y1 < height; y1++) {
	int mask_x = x1 - mask_offset_x, mask_y = y1 - mask_offset_y;
	guchar *alpha = gdk_pixbuf_get_pixels(mypixbuf)
	  + y1 * gdk_pixbuf_get_rowstride(mypixbuf)
	  + x1 * gdk_pixbuf_get_n_channels(mypixbuf)
	  + 3;
	guchar *mask_alpha = gdk_pixbuf_get_pixels(mask_pixbuf)
	  + mask_y * gdk_pixbuf_get_rowstride(mask_pixbuf)
	  + mask_x * gdk_pixbuf_get_n_channels(mask_pixbuf)
	  + 3;

	*alpha = (*alpha) * (*mask_alpha) / 255;
      }
    }
  }

  return ctor_sprite(mypixbuf);
}
Exemple #21
0
int  hid_init(void)
{
    // Found a PC keyboard keymap
    match_keymap(tihw.calc_type);

    // Load kbd keymap
    if(keymap_load(options.keys_file) == -1)
    {
	    gchar *s = g_strdup_printf("unable to load this keymap: <%s>\n", options.keys_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

    // Found a skin
	match_skin(tihw.calc_type);

    // Load skin (2 parts)
    if(skin_load(&skin_infos, options.skin_file) == -1) 
    {
	    gchar *s = g_strdup_printf("unable to load this skin: <%s>\n", options.skin_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Allocate the skn pixbuf (if needed)
	skn = skin_infos.image;
  
	// Set skin keymap depending on calculator type
    switch(tihw.calc_type)
    {
    case TI92:
    case TI92p:
    case V200:
        skn_keymap = sknKey92;
        break;
    case TI89:
    case TI89t:
      	skn_keymap = sknKey89;
        break;
    default:
        {
	  	gchar *s = g_strdup_printf("no skin found for this calc\n");
	  	tiemu_error(0, s);
	  	g_free(s);
	  	return -1;
        }
	}

	// Set window/LCD sizes
	set_scale(options.view);
	set_infos();

    // Allocate the TI screen buffer
	lcd_bytmap = (uint32_t *)malloc(LCDMEM_W * LCDMEM_H);

    // Allocate the lcd pixbuf
    lcd = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, si.t * LCDMEM_W, si.t * LCDMEM_H);
    if(lcd == NULL)
    {
        gchar *s = g_strdup_printf("unable to create LCD pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Used by TI89 (the LCD view is clipped from memory view)
	si.l = gdk_pixbuf_new_subpixbuf(lcd, 0, 0, tihw.lcd_w, tihw.lcd_h);
    
	// Constants for LCD update (speed-up)
    li.n_channels = gdk_pixbuf_get_n_channels (lcd);
	li.width = gdk_pixbuf_get_width (lcd);
	li.height = gdk_pixbuf_get_height (lcd);
	li.rowstride = gdk_pixbuf_get_rowstride (lcd);
	li.pixels = gdk_pixbuf_get_pixels (lcd);

	// Create main window
	display_main_wnd();

    // Allocate the backing pixmap (used for drawing and refresh)
    pixmap = gdk_pixmap_new(main_wnd->window, wr.w, wr.h, -1);
    if(pixmap == NULL)
    {
        gchar *s = g_strdup_printf("unable to create backing pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }
    
    // Draw the skin and compute grayscale palette
	redraw_skin();
  	compute_grayscale();

    // Init the planar/chunky conversion table for LCD
  	compute_convtable();

    // Install LCD refresh: 100 FPS (10 ms)
    tid = g_timeout_add((params.lcd_rate == -1) ? 50 : params.lcd_rate, 
		(GtkFunction)hid_refresh, NULL);

	gtk_widget_show(main_wnd);	// show wnd here

	if(options.view == VIEW_FULL)
		gdk_window_fullscreen(main_wnd->window);
	
    return 0;
}
gpointer itdb_thumb_ipod_item_to_pixbuf (Itdb_Device *device,
                                         Itdb_Thumb_Ipod_Item *item)
{
	/* pixbuf is already on the iPod -> read from there */
	GdkPixbuf *pixbuf_full;
	GdkPixbuf *pixbuf_sub;
        GdkPixbuf *pixbuf;
	gint pad_x = item->horizontal_padding;
	gint pad_y = item->vertical_padding;
	gint width = item->width;
	gint height = item->height;
	guint rowstride;
        const Itdb_ArtworkFormat *img_info = item->format;
        guchar *pixels;

/*	printf ("hp%d vp%d w%d h%d\n",
	       pad_x, pad_y, width, height);*/
        if (item->format == NULL) {
	    g_warning (_("Unable to retrieve thumbnail (appears to be on iPod, but no image info available): filename: '%s'\n"),
		       item->filename);
            return NULL;
        }
	pixels = itdb_thumb_get_rgb_data (device, item);
	if (pixels == NULL)
	{
	    return NULL;
	}

	/* FIXME: this is broken for non-16bpp image formats :-/ */
	rowstride = get_aligned_width (img_info, sizeof(guint16))*3;
	pixbuf_full =
	    gdk_pixbuf_new_from_data (pixels,
				      GDK_COLORSPACE_RGB,
				      FALSE, 8,
				      img_info->width, img_info->height,
				      rowstride,
				      (GdkPixbufDestroyNotify)g_free,
				      NULL);

	/* !! do not g_free(pixels) here: it will be freed when doing a
	 * gdk_pixbuf_unref() on the GdkPixbuf !! */

	/* Remove padding from the pixmap and/or cut the pixmap to the
	   right size. */

	/* Negative offsets indicate that part of the image was cut
	   off at the left/top. thumb->width/height include that part
	   of the image. Positive offsets indicate that part of the
	   thumbnail are padded in black. thumb->width/height also
	   include that part of the image -> reduce width and height
	   by the absolute value of the padding */
	width = width - abs (pad_x);
	height = height - abs (pad_y);
	/* And throw out "negative" padding */
	if (pad_x < 0)		pad_x = 0;
	if (pad_y < 0)		pad_y = 0;
	/* Width/height might still be larger than
	   img_info->width/height, indicating that part of the image
	   was cut off at the right/bottom (similar to negative
	   padding above). Adjust width/height accordingly. */
	if (pad_x + width > img_info->width)
	    width = img_info->width - pad_x;
	if (pad_y + height > img_info->height)
	    height = img_info->height - pad_y;

#if DEBUG_ARTWORK
 	printf ("px=%2d py=%2d x=%3d y=%3d\n", pad_x, pad_y, width, height);
#endif

	pixbuf_sub = gdk_pixbuf_new_subpixbuf (pixbuf_full,
					       pad_x, pad_y,
					       width, height);
	pixbuf = gdk_pixbuf_copy (pixbuf_sub);
	g_object_unref (pixbuf_full);
	g_object_unref (pixbuf_sub);

        return pixbuf;
}
/* This function courtesy of James Henstridge and fontilus */
static void
save_pixbuf(GdkPixbuf *pixbuf, gchar *filename)
{
    guchar *buffer;
    gint p_width, p_height, p_rowstride;
    gint i, j;
    gint trim_left, trim_right, trim_top, trim_bottom;
    GdkPixbuf *subpixbuf;

    buffer      = gdk_pixbuf_get_pixels(pixbuf);
    p_width     = gdk_pixbuf_get_width(pixbuf);
    p_height    = gdk_pixbuf_get_height(pixbuf);
    p_rowstride = gdk_pixbuf_get_rowstride(pixbuf);

    for (i = 0; i < p_width; i++) {
	gboolean seen_pixel = FALSE;

	for (j = 0; j < p_height; j++) {
	    gint offset = j * p_rowstride + 3*i;

	    seen_pixel = (buffer[offset]   != 0xff ||
			  buffer[offset+1] != 0xff ||
			  buffer[offset+2] != 0xff);
	    if (seen_pixel)
		break;
	}
	if (seen_pixel)
	    break;
    }
    trim_left = MIN(p_width, i);
    trim_left = MAX(trim_left - PAD_PIXELS, 0);

    for (i = p_width-1; i >= trim_left; i--) {
	gboolean seen_pixel = FALSE;

	for (j = 0; j < p_height; j++) {
	    gint offset = j * p_rowstride + 3*i;

	    seen_pixel = (buffer[offset]   != 0xff ||
			  buffer[offset+1] != 0xff ||
			  buffer[offset+2] != 0xff);
	    if (seen_pixel)
		break;
	}
	if (seen_pixel)
	    break;
    }
    trim_right = MAX(trim_left, i);
    trim_right = MIN(trim_right + PAD_PIXELS, p_width-1);

    for (j = 0; j < p_height; j++) {
	gboolean seen_pixel = FALSE;

	for (i = 0; i < p_width; i++) {
	    gint offset = j * p_rowstride + 3*i;

	    seen_pixel = (buffer[offset]   != 0xff ||
			  buffer[offset+1] != 0xff ||
			  buffer[offset+2] != 0xff);
	    if (seen_pixel)
		break;
	}
	if (seen_pixel)
	    break;
    }
    trim_top = MIN(p_height, j);
    trim_top = MAX(trim_top - PAD_PIXELS, 0);

    for (j = p_height-1; j >= trim_top; j--) {
	gboolean seen_pixel = FALSE;

	for (i = 0; i < p_width; i++) {
	    gint offset = j * p_rowstride + 3*i;

	    seen_pixel = (buffer[offset]   != 0xff ||
			  buffer[offset+1] != 0xff ||
			  buffer[offset+2] != 0xff);
	    if (seen_pixel)
		break;
	}
	if (seen_pixel)
	    break;
    }
    trim_bottom = MAX(trim_top, j);
    trim_bottom = MIN(trim_bottom + PAD_PIXELS, p_height-1);

    subpixbuf = gdk_pixbuf_new_subpixbuf(pixbuf, trim_left, trim_top,
					 trim_right - trim_left,
					 trim_bottom - trim_top);
    gdk_pixbuf_save(subpixbuf, filename, "png", NULL, NULL);
    gdk_pixbuf_unref(subpixbuf);
}