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

📄 pixbuf-renderer.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
	pr_queue(pr, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, new_data, FALSE);}/* *------------------------------------------------------------------- * signal emission *------------------------------------------------------------------- */static void pr_update_signal(PixbufRenderer *pr){#if 0	printf("FIXME: send updated signal\n");#endif}static void pr_zoom_signal(PixbufRenderer *pr){	g_signal_emit(pr, signals[SIGNAL_ZOOM], 0, pr->zoom);}static void pr_clicked_signal(PixbufRenderer *pr, GdkEventButton *bevent){	g_signal_emit(pr, signals[SIGNAL_CLICKED], 0, bevent);}static void pr_scroll_notify_signal(PixbufRenderer *pr){	g_signal_emit(pr, signals[SIGNAL_SCROLL_NOTIFY], 0);}static void pr_render_complete_signal(PixbufRenderer *pr){	if (!pr->complete)		{		g_signal_emit(pr, signals[SIGNAL_RENDER_COMPLETE], 0);		g_object_set(G_OBJECT(pr), "complete", TRUE, NULL);		}}/* *------------------------------------------------------------------- * sync and clamp *------------------------------------------------------------------- */static gint pr_scroll_clamp(PixbufRenderer *pr){	gint old_xs;	gint old_ys;	if (pr->zoom == 0.0)		{		pr->x_scroll = 0;		pr->y_scroll = 0;		return FALSE;		}	old_xs = pr->x_scroll;	old_ys = pr->y_scroll;	if (pr->x_offset > 0)		{		pr->x_scroll = 0;		}	else		{		pr->x_scroll = CLAMP(pr->x_scroll, 0, pr->width - pr->vis_width);		}	if (pr->y_offset > 0)		{		pr->y_scroll = 0;		}	else		{		pr->y_scroll = CLAMP(pr->y_scroll, 0, pr->height - pr->vis_height);		}	return (old_xs != pr->x_scroll || old_ys != pr->y_scroll);}static gint pr_size_clamp(PixbufRenderer *pr){	gint old_vw, old_vh;	old_vw = pr->vis_width;	old_vh = pr->vis_height;	if (pr->width < pr->window_width)		{		pr->vis_width = pr->width;		pr->x_offset = (pr->window_width - pr->width) / 2;		}	else		{		pr->vis_width = pr->window_width;		pr->x_offset = 0;		}	if (pr->height < pr->window_height)		{		pr->vis_height = pr->height;		pr->y_offset = (pr->window_height - pr->height) / 2;		}	else		{		pr->vis_height = pr->window_height;		pr->y_offset = 0;		}	return (old_vw != pr->vis_width || old_vh != pr->vis_height);}static gint pr_zoom_clamp(PixbufRenderer *pr, gdouble zoom,			  gint force, gint new, gint invalidate,			  gint *redrawn){	gint w, h;	gdouble scale;	gint invalid;	zoom = CLAMP(zoom, pr->zoom_min, pr->zoom_max);	if (pr->zoom == zoom && !force) return FALSE;	w = pr->image_width;	h = pr->image_height;	if (zoom == 0.0 && !pr->pixbuf)		{		scale = 1.0;		}	else if (zoom == 0.0)		{		gint max_w;		gint max_h;		gint sizeable;		sizeable = (new && pr_parent_window_sizable(pr));		if (sizeable)			{			max_w = gdk_screen_width();			max_h = gdk_screen_height();			if (pr->window_limit)				{				max_w = max_w * pr->window_limit_size / 100;				max_h = max_h * pr->window_limit_size / 100;				}			}		else			{			max_w = pr->window_width;			max_h = pr->window_height;			}		if ((pr->zoom_expand && !sizeable) || w > max_w || h > max_h)			{			if ((gdouble)max_w / w > (gdouble)max_h / h)				{				scale = (gdouble)max_h / h;				h = max_h;				w = w * scale + 0.5;				if (w > max_w) w = max_w;				}			else				{				scale = (gdouble)max_w / w;				w = max_w;				h = h * scale + 0.5;				if (h > max_h) h = max_h;				}			if (w < 1) w = 1;			if (h < 1) h = 1;			}		else			{			scale = 1.0;			}		}	else if (zoom > 0.0) /* zoom orig, in */		{		scale = zoom;		w = w * scale;		h = h * scale;		}	else /* zoom out */		{		scale = 1.0 / (0.0 - zoom);		w = w * scale;		h = h * scale;		}	invalid = (pr->width != w || pr->height != h);	pr->zoom = zoom;	pr->width = w;	pr->height = h;	pr->scale = scale;	if (invalidate || invalid)		{		pr_tile_invalidate_all(pr);		pr_redraw(pr, TRUE);		}	if (redrawn) *redrawn = (invalidate || invalid);	return TRUE;}static void pr_zoom_sync(PixbufRenderer *pr, gdouble zoom,			 gint force, gint blank, gint new,			 gint center_point, gint px, gint py){	gdouble old_scale;	gint old_cx, old_cy;	gint clamped;	gint sized;	gint redrawn = FALSE;	old_scale = pr->scale;	if (center_point)		{		px = CLAMP(px, 0, pr->width);		py = CLAMP(py, 0, pr->height);		old_cx = pr->x_scroll + (px - pr->x_offset);		old_cy = pr->y_scroll + (py - pr->y_offset);		}	else		{		px = py = 0;		old_cx = pr->x_scroll + pr->vis_width / 2;		old_cy = pr->y_scroll + pr->vis_height / 2;		}	if (!pr_zoom_clamp(pr, zoom, force, new, force, &redrawn)) return;	clamped = pr_size_clamp(pr);	sized = pr_parent_window_resize(pr, pr->width, pr->height);	if (force)		{		switch (pr->scroll_reset)			{			case PR_SCROLL_RESET_NOCHANGE:				/* maintain old scroll position, do nothing */				break;			case PR_SCROLL_RESET_CENTER:				/* center new image */				pr->x_scroll = ((double)pr->image_width / 2.0 * pr->scale) - pr->vis_width / 2;				pr->y_scroll = ((double)pr->image_height / 2.0 * pr->scale) - pr->vis_height / 2;				break;			case PR_SCROLL_RESET_TOPLEFT:			default:				/* reset to upper left */				pr->x_scroll = 0;				pr->y_scroll = 0;				break;			}		}	else		{		/* user zoom does not force, so keep visible center point */		if (center_point)			{			pr->x_scroll = old_cx / old_scale * pr->scale - (px - pr->x_offset);			pr->y_scroll = old_cy / old_scale * pr->scale - (py - pr->y_offset);			}		else			{			pr->x_scroll = old_cx / old_scale * pr->scale - (pr->vis_width / 2);			pr->y_scroll = old_cy / old_scale * pr->scale - (pr->vis_height / 2);			}		}	pr_scroll_clamp(pr);#if 0	pr_tile_sync(pr, blank);#endif	/* If the window was not sized, redraw the image - we know there will be no size/expose signal.	 * But even if a size is claimed, there is no guarantee that the window manager will allow it,	 * so redraw the window anyway :/	 */	if (sized || clamped) pr_border_clear(pr);	pr_redraw(pr, redrawn);	pr_scroll_notify_signal(pr);	pr_zoom_signal(pr);	pr_update_signal(pr);}static void pr_size_sync(PixbufRenderer *pr, gint new_width, gint new_height){	gint zoom_changed = FALSE;	if (pr->window_width == new_width && pr->window_height == new_height) return;	pr->window_width = new_width;	pr->window_height = new_height;	if (pr->zoom == 0.0)		{		gdouble old_scale = pr->scale;		pr_zoom_clamp(pr, 0.0, TRUE, FALSE, FALSE, NULL);		zoom_changed = (old_scale != pr->scale);		}	pr_size_clamp(pr);	pr_scroll_clamp(pr);	/* ensure scroller remains visible */	if (pr->scroller_overlay != -1)		{		gint update = FALSE;		if (pr->scroller_x > new_width)			{			pr->scroller_x = new_width;			pr->scroller_xpos = new_width;			update = TRUE;			}		if (pr->scroller_y > new_height)			{			pr->scroller_y = new_height;			pr->scroller_ypos = new_height;			update = TRUE;			}		if (update)			{			GdkPixbuf *pixbuf;			if (pixbuf_renderer_overlay_get(pr, pr->scroller_overlay, &pixbuf, NULL, NULL))				{				gint w, h;				w = gdk_pixbuf_get_width(pixbuf);				h = gdk_pixbuf_get_height(pixbuf);				pixbuf_renderer_overlay_set(pr, pr->scroller_overlay, pixbuf,							    pr->scroller_x - w / 2, pr->scroller_y - h / 2);				}			}		}	pr_border_clear(pr);#if 0	pr_tile_sync(pr, pr->width, pr->height, FALSE);#endif	pr_scroll_notify_signal(pr);	if (zoom_changed) pr_zoom_signal(pr);	pr_update_signal(pr);}static void pr_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data){	PixbufRenderer *pr = data;	pr_size_sync(pr, allocation->width, allocation->height);}static void pixbuf_renderer_paint(PixbufRenderer *pr, GdkRectangle *area){	gint x, y;	pr_border_draw(pr, area->x, area->y, area->width, area->height);	x = MAX(0, (gint)area->x - pr->x_offset + pr->x_scroll);	y = MAX(0, (gint)area->y - pr->y_offset + pr->y_scroll);	pr_queue(pr, x, y,		 MIN((gint)area->width, pr->width - x),		 MIN((gint)area->height, pr->height - y),		 FALSE, TILE_RENDER_ALL, FALSE, FALSE);}/* *------------------------------------------------------------------- * scrolling *------------------------------------------------------------------- */void pixbuf_renderer_scroll(PixbufRenderer *pr, gint x, gint y){	gint old_x, old_y;	gint x_off, y_off;	gint w, h;	g_return_if_fail(IS_PIXBUF_RENDERER(pr));	if (!pr->pixbuf && !pr->source_tiles_enabled) return;	old_x = pr->x_scroll;	old_y = pr->y_scroll;	pr->x_scroll += x;	pr->y_scroll += y;	pr_scroll_clamp(pr);	if (pr->x_scroll == old_x && pr->y_scroll == old_y) return;	pr_scroll_notify_signal(pr);	if (pr->overlay_list)		{		gint new_x, new_y;		new_x = pr->x_scroll;		new_y = pr->y_scroll;		pr->x_scroll = old_x;		pr->y_scroll = old_y;		pr_overlay_queue_all(pr);		pr->x_scroll = new_x;		pr->y_scroll = new_y;		}	x_off = pr->x_scroll - old_x;	y_off = pr->y_scroll - old_y;	w = pr->vis_width - abs(x_off);	h = pr->vis_height - abs(y_off);	if (w < 1 || h < 1)		{		/* scrolled completely to new material */		pr_queue(pr, 0, 0, pr->width, pr->height, TRUE, TILE_RENDER_ALL, FALSE, FALSE);		return;		}	else		{		gint x1, y1;		gint x2, y2;		GtkWidget *box;		GdkGC *gc;		if (x_off < 0)			{			x1 = abs(x_off);			x2 = 0;			}		else			{			x1 = 0;			x2 = abs(x_off);			}		if (y_off < 0)			{			y1 = abs(y_off);			y2 = 0;			}		else			{			y1 = 0;			y2 = abs(y_off);			}		box = GTK_WIDGET(pr);		gc = gdk_gc_new(box->window);		gdk_gc_set_exposures(gc, TRUE);		gdk_draw_drawable(box->window, gc,				  box->window,				  x2 + pr->x_offset, y2 + pr->y_offset,				  x1 + pr->x_offset, y1 + pr->y_offset, w, h);		g_object_unref(gc);		if (pr->overlay_list)			{			pr_overlay_queue_all(pr);			}		w = pr->vis_width - w;		h = pr->vis_height - h;		if (w > 0)			{			pr_queue(pr,				 x_off > 0 ? pr->x_scroll + (pr->vis_width - w) : pr->x_scroll, pr->y_scroll,				 w, pr->vis_height, TRUE, TILE_RENDER_ALL, FALSE, FALSE);			}		if (h > 0)			{			/* FIXME, to optimize this, remove overlap */			pr_queue(pr,				 pr->x_scroll, y_off > 0 ? pr->y_scroll + (pr->vis_height - h) : pr->y_scroll,				 pr->vis_width, h, TRUE, TILE_RENDER_ALL, FALSE, FALSE);			}		}}void pixbuf_renderer_scroll_to_point(PixbufRenderer *pr, gint x, gint y,				     gdouble x_align, gdouble y_align){	gint px, py;	gint ax, ay;	x_align = CLAMP(x_align, 0.0, 1.0);	y_align = CLAMP(y_align, 0.0, 1.0);	ax = (gdouble)pr->vis_width * x_align;	ay = (gdouble)pr->vis_height * y_align;	px = (gdouble)x * pr->scale - (pr->x_scroll + ax);	py = (gdouble)y * pr->scale - (pr->y_scroll + ay);	pixbuf_renderer_scroll(pr, px, py);}/* *------------------------------------------------------------------- * mouse *------------------------------------------------------------------- */static gint pr_mouse_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	PixbufRenderer *pr;	gint accel;	pr = PIXBUF_RENDERER(widget);	if (pr->scroller_id != -1)		{		pr->scroller_xpos = bevent->x;		pr->scroller_ypos = bevent->y;		}	if (!pr->in_drag || !gdk_pointer_is_grabbed()) return FALSE;	if (pr->drag_moved < PR_DRAG_SCROLL_THRESHHOLD)		{		pr->drag_moved++;		}	else		{		widget_set_cursor(widget, GDK_FLEUR);		}	if (bevent->state & GDK_SHIFT_MASK)		{		accel = PR_PAN_SHIFT_MULTIPLIER;		}	else		{		accel = 1;		}	/* do the scroll */	pixbuf_renderer_scroll(pr, (pr->drag_last_x - bevent->x) * accel,			       (pr->drag_last_y - bevent->y) * accel);	pr->drag_last_x = bevent->x;	pr->drag_last_y = bevent->y;	return FALSE;}static gint pr_mouse_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	PixbufRenderer *pr;	GtkWidget *parent;	pr = PIXBUF_RENDERER(widget);	if (pr->scroller_id != -1) return TRUE;	switch (bevent->button)		{		case 1:			pr->in_drag = TRUE;			pr->d

⌨️ 快捷键说明

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