⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pixbuf-renderer.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
			g_value_set_boolean(value, pr->loading);			break;		case PROP_COMPLETE:			g_value_set_boolean(value, pr->complete);			break;		case PROP_CACHE_SIZE_DISPLAY:			g_value_set_uint(value, pr->tile_cache_max);			break;		case PROP_CACHE_SIZE_TILES:			g_value_set_uint(value, pr->source_tiles_cache_size);			break;		case PROP_WINDOW_FIT:			g_value_set_boolean(value, pr->window_fit);			break;		case PROP_WINDOW_LIMIT:			g_value_set_boolean(value, pr->window_limit);			break;		case PROP_WINDOW_LIMIT_VALUE:			g_value_set_uint(value, pr->window_limit_size);			break;		default:			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);			break;		}}static gint pixbuf_renderer_expose(GtkWidget *widget, GdkEventExpose *event){	if (GTK_WIDGET_DRAWABLE(widget))		{		if (!GTK_WIDGET_NO_WINDOW(widget))			{			pixbuf_renderer_paint(PIXBUF_RENDERER(widget), &event->area);			}		}	return FALSE;}/* *------------------------------------------------------------------- * misc utilities *------------------------------------------------------------------- */static void widget_set_cursor(GtkWidget *widget, gint icon){	GdkCursor *cursor;	if (!widget->window) return;	if (icon == -1)		{		cursor = NULL;		}	else		{		cursor = gdk_cursor_new (icon);		}	gdk_window_set_cursor(widget->window, cursor);	if (cursor) gdk_cursor_unref(cursor);}static gint pixmap_calc_size(GdkPixmap *pixmap){	gint w, h, d;	d = gdk_drawable_get_depth(pixmap);	gdk_drawable_get_size(pixmap, &w, &h);	return w * h * (d / 8);}static gint pr_clip_region(gint x, gint y, gint w, gint h,			   gint clip_x, gint clip_y, gint clip_w, gint clip_h,			   gint *rx, gint *ry, gint *rw, gint *rh){	if (clip_x + clip_w <= x ||	    clip_x >= x + w ||	    clip_y + clip_h <= y ||	    clip_y >= y + h)		{		return FALSE;		}	*rx = MAX(x, clip_x);	*rw = MIN((x + w), (clip_x + clip_w)) - *rx;	*ry = MAX(y, clip_y);	*rh = MIN((y + h), (clip_y + clip_h)) - *ry;	return TRUE;}static gint pr_parent_window_sizable(PixbufRenderer *pr){	GdkWindowState state;	if (!pr->parent_window) return FALSE;	if (!pr->window_fit) return FALSE;	if (!GTK_WIDGET(pr)->window) return FALSE;	if (!pr->parent_window->window) return FALSE;	state = gdk_window_get_state(pr->parent_window->window);	if (state & GDK_WINDOW_STATE_MAXIMIZED) return FALSE;	return TRUE;}static gint pr_parent_window_resize(PixbufRenderer *pr, gint w, gint h){	GtkWidget *widget;	GtkWidget *parent;	gint ww, wh;	if (!pr_parent_window_sizable(pr)) return FALSE;	if (pr->window_limit)		{		gint sw = gdk_screen_width() * pr->window_limit_size / 100;		gint sh = gdk_screen_height() * pr->window_limit_size / 100;		if (w > sw) w = sw;		if (h > sh) h = sh;		}	widget = GTK_WIDGET(pr);	parent = GTK_WIDGET(pr->parent_window);	w += (parent->allocation.width - widget->allocation.width);	h += (parent->allocation.height - widget->allocation.height);	gdk_drawable_get_size(parent->window, &ww, &wh);	if (w == ww && h == wh) return FALSE;	gdk_window_resize(parent->window, w, h);	return TRUE;}void pixbuf_renderer_set_parent(PixbufRenderer *pr, GtkWindow *window){	g_return_if_fail(IS_PIXBUF_RENDERER(pr));	g_return_if_fail(window == NULL || GTK_IS_WINDOW(window));	pr->parent_window = GTK_WIDGET(window);}GtkWindow *pixbuf_renderer_get_parent(PixbufRenderer *pr){	g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), NULL);	return GTK_WINDOW(pr->parent_window);}/* *------------------------------------------------------------------- * overlays *------------------------------------------------------------------- */static void pr_overlay_draw(PixbufRenderer *pr, gint x, gint y, gint w, gint h){	GtkWidget *box;	GList *work;	box = GTK_WIDGET(pr);	work = pr->overlay_list;	while (work)		{		OverlayData *od;		gint px, py, pw, ph;		gint rx, ry, rw, rh;		od = work->data;		work = work->next;		if (!od->visible) continue;		pw = gdk_pixbuf_get_width(od->pixbuf);		ph = gdk_pixbuf_get_height(od->pixbuf);		px = od->x;		py = od->y;	        if (od->relative)			{			if (px < 0) px = pr->window_width - pw + px;			if (py < 0) py = pr->window_height - ph + py;			}		if (pr_clip_region(x, y, w, h, px, py, pw, ph, &rx, &ry, &rw, &rh))			{			gdk_draw_pixbuf(box->window,					box->style->fg_gc[GTK_WIDGET_STATE(box)],					od->pixbuf,					rx - px, ry - py,					rx, ry, rw, rh,					pr->dither_quality, rx, ry);			}		}}static void pr_overlay_queue_draw(PixbufRenderer *pr, OverlayData *od, gint hidden){	gint x, y, w, h;	gint old_vis;	w = gdk_pixbuf_get_width(od->pixbuf);	h = gdk_pixbuf_get_height(od->pixbuf);	x = od->x;	y = od->y;	if (od->relative)		{		if (x < 0) x = pr->window_width - w + x;		if (y < 0) y = pr->window_height - h + y;		}	pr_queue(pr, pr->x_scroll - pr->x_offset + x,		 pr->y_scroll - pr->y_offset + y,		 w, h,		 FALSE, TILE_RENDER_ALL, FALSE, FALSE);	old_vis = od->visible;	if (hidden) od->visible = FALSE;	pr_border_draw(pr, x, y, w, h);	od->visible = old_vis;}static void pr_overlay_queue_all(PixbufRenderer *pr){	GList *work;	work = pr->overlay_list;	while (work)		{		OverlayData *od = work->data;		work = work->next;		pr_overlay_queue_draw(pr, od, FALSE);		}}static OverlayData *pr_overlay_find(PixbufRenderer *pr, gint id){	GList *work;	work = pr->overlay_list;	while (work)		{		OverlayData *od = work->data;		work = work->next;		if (od->id == id) return od;		}	return NULL;}gint pixbuf_renderer_overlay_add(PixbufRenderer *pr, GdkPixbuf *pixbuf, gint x, gint y,		 		 gint relative, gint always){	OverlayData *od;	gint id;	g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), -1);	g_return_val_if_fail(pixbuf != NULL, -1);	id = 1;	while (pr_overlay_find(pr, id)) id++;	od = g_new0(OverlayData, 1);	od->id = id;	od->pixbuf = pixbuf;	g_object_ref(G_OBJECT(od->pixbuf));	od->x = x;	od->y = y;	od->relative = relative;	od->visible = TRUE;	od->always = always;	pr->overlay_list = g_list_append(pr->overlay_list, od);	pr_overlay_queue_draw(pr, od, FALSE);	return od->id;}static void pr_overlay_free(PixbufRenderer *pr, OverlayData *od){	pr->overlay_list = g_list_remove(pr->overlay_list, od);	if (od->pixbuf) g_object_unref(G_OBJECT(od->pixbuf));	g_free(od);}static void pr_overlay_list_clear(PixbufRenderer *pr){	while (pr->overlay_list)		{		OverlayData *od;		od = pr->overlay_list->data;		pr_overlay_free(pr, od);		}}void pixbuf_renderer_overlay_set(PixbufRenderer *pr, gint id, GdkPixbuf *pixbuf, gint x, gint y){	OverlayData *od;	g_return_if_fail(IS_PIXBUF_RENDERER(pr));	od = pr_overlay_find(pr, id);	if (!od) return;	if (pixbuf)		{		pr_overlay_queue_draw(pr, od, TRUE);		g_object_ref(G_OBJECT(pixbuf));		g_object_unref(G_OBJECT(od->pixbuf));		od->pixbuf = pixbuf;		od->x = x;		od->y = y;		pr_overlay_queue_draw(pr, od, FALSE);		}	else		{		pr_overlay_queue_draw(pr, od, TRUE);		pr_overlay_free(pr, od);		}}gint pixbuf_renderer_overlay_get(PixbufRenderer *pr, gint id, GdkPixbuf **pixbuf, gint *x, gint *y){	OverlayData *od;	g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE);	od = pr_overlay_find(pr, id);	if (!od) return FALSE;	if (pixbuf) *pixbuf = od->pixbuf;	if (x) *x = od->x;	if (y) *y = od->y;	return TRUE;}void pixbuf_renderer_overlay_remove(PixbufRenderer *pr, gint id){	pixbuf_renderer_overlay_set(pr, id, NULL, 0, 0);}/* *------------------------------------------------------------------- * scroller overlay *------------------------------------------------------------------- */static gboolean pr_scroller_update_cb(gpointer data){	PixbufRenderer *pr = data;	gint x, y;	gint xinc, yinc;	/* this was a simple scroll by difference between scroller and mouse position,	 * but all this math results in a smoother result and accounts for a dead zone.	 */	if (abs(pr->scroller_xpos - pr->scroller_x) < PR_SCROLLER_DEAD_ZONE)		{		x = 0;		}	else		{		gint shift = PR_SCROLLER_DEAD_ZONE / 2 * PR_SCROLLER_UPDATES_PER_SEC;		x = (pr->scroller_xpos - pr->scroller_x) / 2 * PR_SCROLLER_UPDATES_PER_SEC;		x += (x > 0) ? -shift : shift;		}	if (abs(pr->scroller_ypos - pr->scroller_y) < PR_SCROLLER_DEAD_ZONE)		{		y = 0;		}	else		{		gint shift = PR_SCROLLER_DEAD_ZONE / 2 * PR_SCROLLER_UPDATES_PER_SEC;		y = (pr->scroller_ypos - pr->scroller_y) / 2 * PR_SCROLLER_UPDATES_PER_SEC;		y += (y > 0) ? -shift : shift;		}	if (abs(x) < PR_SCROLLER_DEAD_ZONE * PR_SCROLLER_UPDATES_PER_SEC)		{		xinc = x;		}	else		{		xinc = pr->scroller_xinc;		if (x >= 0)			{			if (xinc < 0) xinc = 0;			if (x < xinc) xinc = x;			if (x > xinc) xinc = MIN(xinc + x / PR_SCROLLER_UPDATES_PER_SEC, x);			}		else			{			if (xinc > 0) xinc = 0;			if (x > xinc) xinc = x;			if (x < xinc) xinc = MAX(xinc + x / PR_SCROLLER_UPDATES_PER_SEC, x);			}		}	if (abs(y) < PR_SCROLLER_DEAD_ZONE * PR_SCROLLER_UPDATES_PER_SEC)		{		yinc = y;		}	else		{		yinc = pr->scroller_yinc;		if (y >= 0)			{			if (yinc < 0) yinc = 0;			if (y < yinc) yinc = y;			if (y > yinc) yinc = MIN(yinc + y / PR_SCROLLER_UPDATES_PER_SEC, y);			}		else			{			if (yinc > 0) yinc = 0;			if (y > yinc) yinc = y;			if (y < yinc) yinc = MAX(yinc + y / PR_SCROLLER_UPDATES_PER_SEC, y);			}		}	pr->scroller_xinc = xinc;	pr->scroller_yinc = yinc;	xinc = xinc / PR_SCROLLER_UPDATES_PER_SEC;	yinc = yinc / PR_SCROLLER_UPDATES_PER_SEC;	pixbuf_renderer_scroll(pr, xinc, yinc);	return TRUE;}static void pr_scroller_timer_set(PixbufRenderer *pr, gint start){	if (pr->scroller_id != -1)		{		g_source_remove(pr->scroller_id);		pr->scroller_id = -1;		}	if (start)		{		pr->scroller_id = g_timeout_add(1000 / PR_SCROLLER_UPDATES_PER_SEC,						pr_scroller_update_cb, pr);		}}static void pr_scroller_start(PixbufRenderer *pr, gint x, gint y){	if (pr->scroller_overlay == -1)		{		GdkPixbuf *pixbuf;		gint w, h;#ifdef GQVIEW_BUILD		pixbuf = pixbuf_inline(PIXBUF_INLINE_SCROLLER);#else		pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 32, 32);		gdk_pixbuf_fill(pixbuf, 0x000000ff);#endif		w = gdk_pixbuf_get_width(pixbuf);		h = gdk_pixbuf_get_height(pixbuf);		pr->scroller_overlay = pixbuf_renderer_overlay_add(pr, pixbuf, x - w / 2, y - h / 2, FALSE, TRUE);		g_object_unref(pixbuf);		}	pr->scroller_x = x;	pr->scroller_y = y;	pr->scroller_xpos = x;	pr->scroller_ypos = y;	pr_scroller_timer_set(pr, TRUE);}static void pr_scroller_stop(PixbufRenderer *pr){	if (pr->scroller_id == -1) return;	pixbuf_renderer_overlay_remove(pr, pr->scroller_overlay);	pr->scroller_overlay = -1;	pr_scroller_timer_set(pr, FALSE);}/* *------------------------------------------------------------------- * borders *------------------------------------------------------------------- */static void pr_border_draw(PixbufRenderer *pr, gint x, gint y, gint w, gint h){	GtkWidget *box;	gint rx, ry, rw, rh;	box = GTK_WIDGET(pr);	if (!box->window) return;	if (!pr->pixbuf && !pr->source_tiles_enabled)		{		if (pr_clip_region(x, y, w, h,				   0, 0,				   pr->window_width, pr->window_height,				   &rx, &ry, &rw, &rh))			{			gdk_window_clear_area(box->window, rx, ry, rw, rh);			pr_overlay_draw(pr, rx, ry, rw, rh);			}		return;		}	if (pr->vis_width < pr->window_width)		{		if (pr->x_offset > 0 &&		    pr_clip_region(x, y, w, h,				   0, 0,				   pr->x_offset, pr->window_height,				   &rx, &ry, &rw, &rh))			{			gdk_window_clear_area(box->window, rx, ry, rw, rh);			pr_overlay_draw(pr, rx, ry, rw, rh);			}		if (pr->window_width - pr->vis_width - pr->x_offset > 0 &&		    pr_clip_region(x, y, w, h,				   pr->x_offset + pr->vis_width, 0,				   pr->window_width - pr->vis_width - pr->x_offset, pr->window_height,				   &rx, &ry, &rw, &rh))			{			gdk_window_clear_area(box->window, rx, ry, rw, rh);			pr_overlay_draw(pr, rx, ry, rw, rh);			}		}	if (pr->vis_height < pr->window_height)		{		if (pr->y_offset > 0 &&		    pr_clip_region(x, y, w, h,				   pr->x_offset, 0,				   pr->vis_width, pr->y_offset,				   &rx, &ry, &rw, &rh))			{			gdk_window_clear_area(box->window, rx, ry, rw, rh);			pr_overlay_draw(pr, rx, ry, rw, rh);			}		if (pr->window_height - pr->vis_height - pr->y_offset > 0 &&		    pr_clip_region(x, y, w, h,				   pr->x_offset, pr->y_offset + pr->vis_height,				   pr->vis_width, pr->window_height - pr->vis_height - pr->y_offset,				   &rx, &ry, &rw, &rh))			{			gdk_window_clear_area(box->window, rx, ry, rw, rh);			pr_overlay_draw(pr, rx, ry, rw, rh);			}		}}static void pr_border_clear(PixbufRenderer *pr){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -