Пример #1
0
void feh_action_run(feh_file * file, char *action)
{
	if (action) {
		char *sys;
		D(("Running action %s\n", action));
		sys = feh_printf(action, file, NULL);

		if (opt.verbose && !opt.list && !opt.customlist)
			fprintf(stderr, "Running action -->%s<--\n", sys);
		system(sys);
	}
	return;
}
Пример #2
0
char *slideshow_create_name(feh_file * file, winwidget winwid)
{
	char *s = NULL;
	int len = 0;

	if (!opt.title) {
		len = strlen(PACKAGE " [slideshow mode] - ") + strlen(file->filename) + 1;
		s = emalloc(len);
		snprintf(s, len, PACKAGE " [%d of %d] - %s",
			gib_list_num(filelist, current_file) + 1, gib_list_length(filelist), file->filename);
	} else {
		s = estrdup(feh_printf(opt.title, file, winwid));
	}

	return(s);
}
Пример #3
0
/* TODO s/bit/lot */
void init_thumbnail_mode(void)
{
	/* moved to thumbnail_data:
	   Imlib_Image im_main;
	   Imlib_Image bg_im = NULL;
	   Imlib_Font fn = NULL;
	   Imlib_Font title_fn = NULL;

	   int w = 800, h = 600;
	   int bg_w = 0, bg_h = 0;

	   int text_area_w, text_area_h;
	   int max_column_w = 0;
	 */

	Imlib_Image im_temp;
	int ww = 0, hh = 0, www, hhh, xxx, yyy;
	int x = 0, y = 0;
	winwidget winwid = NULL;
	Imlib_Image im_thumb = NULL;
	unsigned char trans_bg = 0;
	int title_area_h = 0;
	int tw = 0, th = 0;
	int fw_name, fw_size, fw_dim, fh;
	int thumbnailcount = 0;
	feh_file *file = NULL;
	gib_list *l, *last = NULL;
	int lines;
	int index_image_width, index_image_height;
	int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0;
	char *s;
	unsigned int thumb_counter = 0;

	/* initialize thumbnail mode data */
	td.im_main = NULL;
	td.im_bg = NULL;
	td.font_main = NULL;
	td.font_title = NULL;

	td.w = 640;
	td.h = 480;
	td.bg_w = 0;
	td.bg_h = 0;
	td.thumb_tot_h = 0;
	td.text_area_w = 0;
	td.text_area_h = 0;

	td.vertical = 0;
	td.max_column_w = 0;

	mode = "thumbnail";

	if (opt.font)
		td.font_main = gib_imlib_load_font(opt.font);

	if (!td.font_main)
		td.font_main = gib_imlib_load_font(DEFAULT_FONT);

	if (opt.title_font) {
		int fh, fw;

		td.font_title = gib_imlib_load_font(opt.title_font);
		gib_imlib_get_text_size(td.font_title, "W", NULL, &fw, &fh,
				IMLIB_TEXT_TO_RIGHT);
		title_area_h = fh + 4;
	} else
		td.font_title = imlib_load_font(DEFAULT_FONT_TITLE);

	if ((!td.font_main) || (!td.font_title))
		eprintf("Error loading fonts");

	/* Work out how tall the font is */
	gib_imlib_get_text_size(td.font_main, "W", NULL, &tw, &th,
			IMLIB_TEXT_TO_RIGHT);
	/* For now, allow room for the right number of lines with small gaps */
	td.text_area_h = ((th + 2) * (opt.index_show_name + opt.index_show_size +
				opt.index_show_dim)) + 5;

	/* This includes the text area for index data */
	td.thumb_tot_h = opt.thumb_h + td.text_area_h;

	/* Use bg image dimensions for default size */
	if (opt.bg && opt.bg_file) {
		if (!strcmp(opt.bg_file, "trans"))
			trans_bg = 1;
		else {

			D(3, ("Time to apply a background to blend onto\n"));
			if (feh_load_image_char(&td.im_bg, opt.bg_file) != 0) {
				td.bg_w = gib_imlib_image_get_width(td.im_bg);
				td.bg_h = gib_imlib_image_get_height(td.im_bg);
			}
		}
	}

	/* figure out geometry for the main window and entries */
	feh_thumbnail_calculate_geometry();

	index_image_width = td.w;
	index_image_height = td.h + title_area_h;
	td.im_main = imlib_create_image(index_image_width, index_image_height);
	gib_imlib_image_set_has_alpha(td.im_main, 1);

	if (!td.im_main)
		eprintf("Imlib error creating index image, are you low on RAM?");

	if (td.im_bg)
		gib_imlib_blend_image_onto_image(td.im_main, td.im_bg,
						 gib_imlib_image_has_alpha
						 (td.im_bg), 0, 0, td.bg_w, td.bg_h, 0, 0,
						 td.w, td.h, 1, 0, 0);
	else if (trans_bg) {
		gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w,
				td.h + title_area_h, 0, 0, 0, 0);
		gib_imlib_image_set_has_alpha(td.im_main, 1);
	} else {
		/* Colour the background */
		gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w,
				td.h + title_area_h, 0, 0, 0, 255);
	}

	/* Create title now */

	if (!opt.title)
		s = estrdup(PACKAGE " [thumbnail mode]");
	else
		s = estrdup(feh_printf(opt.title, NULL));

	if (opt.display) {
		winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL);
		winwidget_show(winwid);
	}

	/* make sure we have an ~/.thumbnails/normal directory for storing
	   permanent thumbnails */
	td.cache_thumbnails = opt.cache_thumbnails;

	if (td.cache_thumbnails) {
		if (opt.thumb_w > opt.thumb_h)
			td.cache_dim = opt.thumb_w;
		else
			td.cache_dim = opt.thumb_h;

		if (td.cache_dim > 256) {
			/* No caching as specified by standard. Sort of. */
			td.cache_thumbnails = 0;
		} else if (td.cache_dim > 128) {
			td.cache_dim = 256;
			td.cache_dir = estrdup("large");
		} else {
			td.cache_dim = 128;
			td.cache_dir = estrdup("normal");
		}
		feh_thumbnail_setup_thumbnail_dir();
	}

	for (l = filelist; l; l = l->next) {
		file = FEH_FILE(l->data);
		if (last) {
			filelist = feh_file_remove_from_list(filelist, last);
			last = NULL;
		}
		D(4, ("About to load image %s\n", file->filename));
		/*      if (feh_load_image(&im_temp, file) != 0) */
		if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) {
			if (opt.verbose)
				feh_display_status('.');
			D(4, ("Successfully loaded %s\n", file->filename));
			www = opt.thumb_w;
			hhh = opt.thumb_h;
			ww = gib_imlib_image_get_width(im_temp);
			hh = gib_imlib_image_get_height(im_temp);
			thumbnailcount++;
			if (gib_imlib_image_has_alpha(im_temp))
				imlib_context_set_blend(1);
			else
				imlib_context_set_blend(0);

			if (opt.aspect) {
				double ratio = 0.0;

				/* Keep the aspect ratio for the thumbnail */
				ratio = ((double) ww / hh) / ((double) www / hhh);

				if (ratio > 1.0)
					hhh = opt.thumb_h / ratio;
				else if (ratio != 1.0)
					www = opt.thumb_w * ratio;
			}

			if ((!opt.stretch) && ((www > ww) || (hhh > hh))) {
				/* Don't make the image larger unless stretch is specified */
				www = ww;
				hhh = hh;
			}

			im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0,
					ww, hh, www, hhh, 1);
			gib_imlib_free_image_and_decache(im_temp);

			if (opt.alpha) {
				DATA8 atab[256];

				D(3, ("Applying alpha options\n"));
				gib_imlib_image_set_has_alpha(im_thumb, 1);
				memset(atab, opt.alpha_level, sizeof(atab));
				gib_imlib_apply_color_modifier_to_rectangle
				    (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab);
			}

			td.text_area_w = opt.thumb_w;
			/* Now draw on the info text */
			if (opt.index_show_name) {
				gib_imlib_get_text_size(td.font_main, file->name, NULL,
						&fw_name, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_name > td.text_area_w)
					td.text_area_w = fw_name;
			}
			if (opt.index_show_dim) {
				gib_imlib_get_text_size(td.font_main,
							create_index_dimension_string(ww, hh),
							NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_dim > td.text_area_w)
					td.text_area_w = fw_dim;
			}
			if (opt.index_show_size) {
				gib_imlib_get_text_size(td.font_main,
							create_index_size_string(file->filename),
							NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT);
				if (fw_size > td.text_area_w)
					td.text_area_w = fw_size;
			}
			if (td.text_area_w > opt.thumb_w)
				td.text_area_w += 5;

			/* offsets for centering text */
			x_offset_name = (td.text_area_w - fw_name) / 2;
			x_offset_dim = (td.text_area_w - fw_dim) / 2;
			x_offset_size = (td.text_area_w - fw_size) / 2;

			if (td.vertical) {
				if (td.text_area_w > td.max_column_w)
					td.max_column_w = td.text_area_w;
				if (y > td.h - td.thumb_tot_h) {
					y = 0;
					x += td.max_column_w;
					td.max_column_w = 0;
				}
				if (x > td.w - td.text_area_w)
					break;
			} else {
				if (x > td.w - td.text_area_w) {
					x = 0;
					y += td.thumb_tot_h;
				}
				if (y > td.h - td.thumb_tot_h)
					break;
			}

			/* center image relative to the text below it (if any) */
			xxx = x + ((td.text_area_w - www) / 2);
			yyy = y;

			if (opt.aspect)
				yyy += (opt.thumb_h - hhh) / 2;

			/* Draw now */
			gib_imlib_blend_image_onto_image(td.im_main,
							 im_thumb,
							 gib_imlib_image_has_alpha
							 (im_thumb), 0, 0,
							 www, hhh, xxx,
							 yyy, www, hhh, 1,
							 gib_imlib_image_has_alpha(im_thumb), 0);

			thumbnails = gib_list_add_front(thumbnails,
					feh_thumbnail_new(file, xxx, yyy, www, hhh));

			gib_imlib_free_image_and_decache(im_thumb);

			lines = 0;
			if (opt.index_show_name)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_name,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						file->name, IMLIB_TEXT_TO_RIGHT,
						255, 255, 255, 255);
			if (opt.index_show_dim)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_dim,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						create_index_dimension_string(ww, hh),
						IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
			if (opt.index_show_size)
				gib_imlib_text_draw(td.im_main,
						td.font_main, NULL,
						x + x_offset_size,
						y + opt.thumb_h + (lines++ * (th + 2)) + 2,
						create_index_size_string(file->filename),
						IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);

			if (td.vertical)
				y += td.thumb_tot_h;
			else
				x += td.text_area_w;
		} else {
			if (opt.verbose)
				feh_display_status('x');
			last = l;
		}
		if (opt.display) {
			/* thumb_counter is unsigned, so no need to catch overflows */
			if (++thumb_counter == opt.thumb_redraw) {
				winwidget_render_image(winwid, 0, 0);
				thumb_counter = 0;
			}
			if (!feh_main_iteration(0))
				exit(0);
		}
	}

	if (thumb_counter != 0)
		winwidget_render_image(winwid, 0, 0);

	if (opt.verbose)
		fprintf(stdout, "\n");

	if (opt.title_font) {
		int fw, fh, fx, fy;
		char *s;

		s = create_index_title_string(thumbnailcount, td.w, td.h);
		gib_imlib_get_text_size(td.font_title, s, NULL, &fw, &fh,
				IMLIB_TEXT_TO_RIGHT);
		fx = (index_image_width - fw) >> 1;
		fy = index_image_height - fh - 2;
		gib_imlib_text_draw(td.im_main, td.font_title, NULL, fx,
				fy, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
	}
Пример #4
0
void feh_draw_info(winwidget w)
{
	static Imlib_Font fn = NULL;
	int width = 0, height = 0, line_width = 0, line_height = 0;
	Imlib_Image im = NULL;
	int no_lines = 0, i;
	char *info_cmd;
	char info_line[256];
	char *info_buf[128];
	FILE *info_pipe;

	if ((!w->file) || (!FEH_FILE(w->file->data))
			|| (!FEH_FILE(w->file->data)->filename))
		return;

	fn = feh_load_font(w);

	info_cmd = feh_printf(opt.info_cmd, FEH_FILE(w->file->data), w);

	info_pipe = popen(info_cmd, "r");

	if (!info_pipe) {
		info_buf[0] = estrdup("Failed to run info command");
		gib_imlib_get_text_size(fn, info_buf[0], NULL, &width, &height, IMLIB_TEXT_TO_RIGHT);
		no_lines = 1;
	}
	else {
		while ((no_lines < 128) && fgets(info_line, 256, info_pipe)) {
			if (info_line[strlen(info_line)-1] == '\n')
				info_line[strlen(info_line)-1] = '\0';

			gib_imlib_get_text_size(fn, info_line, NULL, &line_width,
					&line_height, IMLIB_TEXT_TO_RIGHT);

			if (line_height > height)
				height = line_height;
			if (line_width > width)
				width = line_width;

			info_buf[no_lines] = estrdup(info_line);

			no_lines++;
		}
		pclose(info_pipe);
	}

	if (no_lines == 0)
		return;

	height *= no_lines;
	width += 4;

	im = imlib_create_image(width, height);
	if (!im)
		eprintf("Couldn't create image. Out of memory?");

	feh_imlib_image_fill_text_bg(im, width, height);

	for (i = 0; i < no_lines; i++) {
		gib_imlib_text_draw(im, fn, NULL, 2, (i * line_height) + 2,
				info_buf[i], IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
		gib_imlib_text_draw(im, fn, NULL, 1, (i * line_height) + 1,
				info_buf[i], IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);

		free(info_buf[i]);
	}

	gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0,
			w->h - height, 1, 1, 0);

	gib_imlib_free_image_and_decache(im);
	return;
}
Пример #5
0
void init_collage_mode(void)
{
	Imlib_Image im_main;
	Imlib_Image im_temp;
	int ww, hh, www, hhh, xxx, yyy;
	int w = 800, h = 600;
	int bg_w = 0, bg_h = 0;
	winwidget winwid = NULL;
	Imlib_Image bg_im = NULL, im_thumb = NULL;
	feh_file *file = NULL;
	unsigned char trans_bg = 0;
	gib_list *l, *last = NULL;
	char *s;

	D_ENTER(4);

	mode = "collage";

	/* Use bg image dimensions for default size */
	if (opt.bg && opt.bg_file) {
		if (!strcmp(opt.bg_file, "trans"))
			trans_bg = 1;
		else {

			D(4, ("Time to apply a background to blend onto\n"));
			if (feh_load_image_char(&bg_im, opt.bg_file) != 0) {
				bg_w = gib_imlib_image_get_width(bg_im);
				bg_h = gib_imlib_image_get_height(bg_im);
			}
		}
	}

	if (!opt.limit_w || !opt.limit_h) {
		if (bg_im) {
			if (opt.verbose)
				fprintf(stdout,
					PACKAGE
					" - No size restriction specified for collage.\n"
					" You did specify a background however, so the\n"
					" collage size has defaulted to the size of the image\n");
			opt.limit_w = bg_w;
			opt.limit_h = bg_h;
		} else {
			if (opt.verbose)
				fprintf(stdout,
					PACKAGE
					" - No size restriction specified for collage.\n"
					" - For collage mode, you need to specify width and height.\n"
					" Using defaults (width 800, height 600)\n");
			opt.limit_w = 800;
			opt.limit_h = 600;
		}
	}

	w = opt.limit_w;
	h = opt.limit_h;
	D(4, ("Limiting width to %d and height to %d\n", w, h));

	im_main = imlib_create_image(w, h);

	if (!im_main)
		eprintf("Imlib error creating image");

	if (bg_im)
		gib_imlib_blend_image_onto_image(im_main, bg_im,
				gib_imlib_image_has_alpha(bg_im), 0, 0,
				bg_w, bg_h, 0, 0, w, h, 1, 0, 0);
	else if (trans_bg) {
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 0);
		gib_imlib_image_set_has_alpha(im_main, 1);
	} else {
		/* Colour the background */
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255);
	}

	/* Create the title string */

	if (!opt.title)
		s = estrdup(PACKAGE " [collage mode]");
	else
		s = estrdup(feh_printf(opt.title, NULL));

	if (opt.display) {
		winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE);
		winwidget_show(winwid);
	}

	for (l = filelist; l; l = l->next) {
		file = FEH_FILE(l->data);
		if (last) {
			filelist = feh_file_remove_from_list(filelist, last);
			filelist_len--;
			last = NULL;
		}
		D(3, ("About to load image %s\n", file->filename));
		if (feh_load_image(&im_temp, file) != 0) {
			D(3, ("Successfully loaded %s\n", file->filename));
			if (opt.verbose)
				feh_display_status('.');
			www = opt.thumb_w;
			hhh = opt.thumb_h;
			ww = gib_imlib_image_get_width(im_temp);
			hh = gib_imlib_image_get_height(im_temp);

			if (opt.aspect) {
				double ratio = 0.0;

				/* Keep the aspect ratio for the thumbnail */
				ratio = ((double) ww / hh) / ((double) www / hhh);

				if (ratio > 1.0)
					hhh = opt.thumb_h / ratio;
				else if (ratio != 1.0)
					www = opt.thumb_w * ratio;
			}

			if ((!opt.stretch) && ((www > ww) || (hhh > hh))) {
				/* Don't make the image larger unless stretch is specified */
				www = ww;
				hhh = hh;
			}

			/* pick random coords for thumbnail */
			xxx = ((w - www) * ((double) rand() / RAND_MAX));
			yyy = ((h - hhh) * ((double) rand() / RAND_MAX));
			D(5, ("image going on at x=%d, y=%d\n", xxx, yyy));

			im_thumb = gib_imlib_create_cropped_scaled_image(im_temp,
					0, 0, ww, hh, www, hhh, 1);
			gib_imlib_free_image_and_decache(im_temp);

			if (opt.alpha) {
				DATA8 atab[256];

				D(4, ("Applying alpha options\n"));
				gib_imlib_image_set_has_alpha(im_thumb, 1);
				memset(atab, opt.alpha_level, sizeof(atab));
				gib_imlib_apply_color_modifier_to_rectangle(im_thumb,
						0, 0, www, hhh, NULL, NULL, NULL, atab);
			}
			gib_imlib_blend_image_onto_image(im_main, im_thumb,
					gib_imlib_image_has_alpha(im_thumb), 0, 0, www, hhh, xxx,
					yyy,www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0);
			gib_imlib_free_image_and_decache(im_thumb);
		} else {
			last = l;
			if (opt.verbose)
				feh_display_status('x');
		}
		if (opt.display) {
			winwidget_render_image(winwid, 0, 0);
			if (!feh_main_iteration(0))
				exit(0);
		}
	}
	if (opt.verbose)
		fprintf(stdout, "\n");

	if (opt.output && opt.output_file) {
		char output_buf[1024];
		if (opt.output_dir)
			snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file);
		else
			strncpy(output_buf, opt.output_file, 1024);
		gib_imlib_save_image(im_main, output_buf);
		if (opt.verbose) {
			int tw, th;

			tw = gib_imlib_image_get_width(im_main);
			th = gib_imlib_image_get_height(im_main);
			fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf);
			fprintf(stdout,
				"    - Image is %dx%d pixels and contains %d thumbnails\n",
				tw, th, (tw / opt.thumb_w) * (th / opt.thumb_h));
		}
	}

	if (!opt.display)
		gib_imlib_free_image_and_decache(im_main);
	free(s);
	D_RETURN_(4);
}
Пример #6
0
/* TODO s/bit/lot */
void init_index_mode(void)
{
	Imlib_Image im_main;
	Imlib_Image im_temp;
	int w = 800, h = 600, ww = 0, hh = 0, www, hhh, xxx, yyy;
	int x = 0, y = 0;
	int bg_w = 0, bg_h = 0;
	winwidget winwid = NULL;
	Imlib_Image bg_im = NULL, im_thumb = NULL;
	int tot_thumb_h;
	int text_area_h = 50;
	int title_area_h = 0;
	Imlib_Font fn = NULL;
	Imlib_Font title_fn = NULL;
	int text_area_w = 0;
	int tw = 0, th = 0;
	int fw, fh;
	int vertical = 0;
	int max_column_w = 0;
	int thumbnailcount = 0;
	gib_list *l = NULL, *last = NULL;
	feh_file *file = NULL;
	int lineno;
	unsigned char trans_bg = 0;
	int index_image_width, index_image_height;
	char *s;
	gib_list *line, *lines;

	if (opt.montage) {
		mode = "montage";
	} else {
		mode = "index";
	}

	if (opt.font)
		fn = gib_imlib_load_font(opt.font);

	if (!fn)
		fn = gib_imlib_load_font(DEFAULT_FONT);

	if (opt.title_font) {

		title_fn = gib_imlib_load_font(opt.title_font);
		if (!title_fn)
			title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE);

		gib_imlib_get_text_size(title_fn, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT);
		title_area_h = fh + 4;
	} else
		title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE);

	if ((!fn) || (!title_fn))
		eprintf("Error loading fonts");

	/* Work out how tall the font is */
	gib_imlib_get_text_size(fn, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
	get_index_string_dim(NULL, fn, &fw, &fh);
	/* For now, allow room for the right number of lines with small gaps */
	text_area_h = fh + 5;

	/* This includes the text area for index data */
	tot_thumb_h = opt.thumb_h + text_area_h;

	/* Use bg image dimensions for default size */
	if (opt.bg && opt.bg_file) {
		if (!strcmp(opt.bg_file, "trans"))
			trans_bg = 1;
		else {
			D(("Time to apply a background to blend onto\n"));
			if (feh_load_image_char(&bg_im, opt.bg_file) != 0) {
				bg_w = gib_imlib_image_get_width(bg_im);
				bg_h = gib_imlib_image_get_height(bg_im);
			}
		}
	}

	if (!opt.limit_w && !opt.limit_h) {
		if (bg_im) {
			opt.limit_w = bg_w;
			opt.limit_h = bg_h;
		} else
			opt.limit_w = 800;
	}

	/* Here we need to whiz through the files, and look at the filenames and
	   info in the selected font, work out how much space we need, and
	   calculate the size of the image we will require */

	if (opt.limit_w) {
		w = opt.limit_w;

		index_calculate_height(fn, w, &h, &tot_thumb_h);

		if (opt.limit_h) {
			if (h > opt.limit_h)
				weprintf(
					"The image size you specified (%dx%d) is not large\n"
					"enough to hold all %d thumbnails. To fit all the thumbnails,\n"
					"either decrease their size, choos e asmaller font,\n"
					"or use a larger image (like %dx%d)",
					opt.limit_w, opt.limit_h, filelist_len, w, h);
			h = opt.limit_h;
		}
	} else if (opt.limit_h) {
		vertical = 1;
		h = opt.limit_h;

		index_calculate_width(fn, &w, h, &tot_thumb_h);
	}

	index_image_width = w;
	index_image_height = h + title_area_h;
	im_main = imlib_create_image(index_image_width, index_image_height);

	if (!im_main)
		eprintf("Imlib error creating index image, are you low on RAM?");

	if (bg_im)
		gib_imlib_blend_image_onto_image(im_main, bg_im,
						 gib_imlib_image_has_alpha
						 (bg_im), 0, 0, bg_w, bg_h, 0, 0, w, h, 1, 0, 0);
	else if (trans_bg) {
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, 0, 0);
		gib_imlib_image_set_has_alpha(im_main, 1);
	} else {
		/* Colour the background */
		gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, 0, 255);
	}

	/* Create the window title at this point */

	if (!opt.title)
		s = estrdup(PACKAGE " [index mode]");
	else
		s = estrdup(feh_printf(opt.title, NULL));

	if (opt.display) {
		winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE);
		winwidget_show(winwid);
	}

	for (l = filelist; l; l = l->next) {
		file = FEH_FILE(l->data);
		if (last) {
			filelist = feh_file_remove_from_list(filelist, last);
			last = NULL;
		}
		D(("About to load image %s\n", file->filename));
		if (feh_load_image(&im_temp, file) != 0) {
			if (opt.verbose)
				feh_display_status('.');
			D(("Successfully loaded %s\n", file->filename));
			www = opt.thumb_w;
			hhh = opt.thumb_h;
			ww = gib_imlib_image_get_width(im_temp);
			hh = gib_imlib_image_get_height(im_temp);
			thumbnailcount++;

			if (opt.aspect) {
				double ratio = 0.0;

				/* Keep the aspect ratio for the thumbnail */
				ratio = ((double) ww / hh) / ((double) www / hhh);

				if (ratio > 1.0)
					hhh = opt.thumb_h / ratio;
				else if (ratio != 1.0)
					www = opt.thumb_w * ratio;
			}

			if ((!opt.stretch) && ((www > ww) || (hhh > hh))) {
				/* Don't make the image larger unless stretch is specified */
				www = ww;
				hhh = hh;
			}

			im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, hhh, 1);
			gib_imlib_free_image_and_decache(im_temp);

			if (opt.alpha) {
				DATA8 atab[256];

				D(("Applying alpha options\n"));
				gib_imlib_image_set_has_alpha(im_thumb, 1);
				memset(atab, opt.alpha_level, sizeof(atab));
				gib_imlib_apply_color_modifier_to_rectangle
				    (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab);
			}

			text_area_w = opt.thumb_w;
			/* Now draw on the info text */
			if (opt.index_info) {
				get_index_string_dim(file, fn, &fw, &fh);
				if (fw > text_area_w)
					text_area_w = fw;
			}
			if (text_area_w > opt.thumb_w)
				text_area_w += 5;

			if (vertical) {
				if (text_area_w > max_column_w)
					max_column_w = text_area_w;
				if (y > h - tot_thumb_h) {
					y = 0;
					x += max_column_w;
					max_column_w = 0;
				}
				if (x > w - text_area_w)
					break;
			} else {
				if (x > w - text_area_w) {
					x = 0;
					y += tot_thumb_h;
				}
				if (y > h - tot_thumb_h)
					break;
			}

			/* center image relative to the text below it (if any) */
			xxx = x + ((text_area_w - www) / 2);
			yyy = y;

			if (opt.aspect)
				yyy += (opt.thumb_h - hhh) / 2;

			/* Draw now */
			gib_imlib_blend_image_onto_image(im_main, im_thumb,
							 gib_imlib_image_has_alpha
							 (im_thumb), 0, 0,
							 www, hhh, xxx,
							 yyy, www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0);

			gib_imlib_free_image_and_decache(im_thumb);

			lineno = 0;
			if (opt.index_info) {
				line = lines = feh_wrap_string(create_index_string(file),
						opt.thumb_w * 3, fn, NULL);

				while (line) {
					gib_imlib_get_text_size(fn, (char *) line->data,
							NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT);
					gib_imlib_text_draw(im_main, fn, NULL,
							x + ((text_area_w - fw) >> 1),
							y + opt.thumb_h + (lineno++ * (th + 2)) + 2,
							(char *) line->data,
							IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
					line = line->next;
				}
				gib_list_free_and_data(lines);
			}

			if (vertical)
				y += tot_thumb_h;
			else
				x += text_area_w;

		} else {
			if (opt.verbose)