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

📄 zoom-region.c

📁 在Linux下实现magnification功能
💻 C
📖 第 1 页 / 共 5 页
字号:
{	GdkWindow *window;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (zoom_region->priv->w && zoom_region->priv->w->window)		window = zoom_region->priv->w->window;	else {		processing_updates = FALSE;		return;	}	zoom_region_unpaint_crosswire_cursor (zoom_region, scroll_rect);	zoom_region_unpaint_cursor (zoom_region, scroll_rect);	gdk_window_scroll (window, dx, dy);	zoom_region_paint_cursor (zoom_region, scroll_rect);	zoom_region_paint_crosswire_cursor (zoom_region, scroll_rect);	gdk_window_process_updates (window, FALSE);	/* sync reduces cursor flicker, but slows things down */	if (zoom_region->smooth_scroll_policy >	    GNOME_Magnifier_ZoomRegion_SCROLL_FASTEST)		gdk_display_sync (gdk_drawable_get_display (window)); }static voidzoom_region_scroll_smooth (ZoomRegion *zoom_region, int dx, int dy,			   GdkRectangle *scroll_rect,			   GdkRectangle *expose_rect_h,			   GdkRectangle *expose_rect_v){	GdkWindow *window = NULL;	GdkRectangle window_rect;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window))		window = zoom_region->priv->w->window;	else		return;	window_rect.x = 0;	window_rect.y = 0;	gdk_drawable_get_size (GDK_DRAWABLE (window),			       &window_rect.width, &window_rect.height);	gdk_window_begin_paint_rect (window, &window_rect);	gdk_window_invalidate_rect (window, &window_rect, FALSE);	gdk_window_process_updates (window, FALSE); 	gdk_window_end_paint (window);}static voidzoom_region_scroll (ZoomRegion *zoom_region, int dx, int dy){	GdkRectangle scroll_rect, expose_rect_h, expose_rect_v;	gboolean can_scroll;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (timing_test) {		mag_timing.num_line_samples++;		mag_timing.dx = abs(dx);		mag_timing.dy = abs(dy);		mag_timing.dx_total += mag_timing.dx;		mag_timing.dy_total += mag_timing.dy;		if (zoom_region->timing_output) {			fprintf(stderr, "  Panning Increment (x)    = %d (avg. %f) lines/frame\n",				mag_timing.dx, (float)mag_timing.dx_total / (float)mag_timing.num_line_samples);			fprintf(stderr, "  Panning Increment (y)    = %d (avg. %f) lines/frame\n",				mag_timing.dy, (float)mag_timing.dy_total / (float)mag_timing.num_line_samples);		}	}    /*     * Currently processing a screen update.  This flag used to disallow     * other updates to occur until this one finishes     */    processing_updates = TRUE;	can_scroll = zoom_region_calculate_scroll_rects (zoom_region, dx, dy,							 &scroll_rect,							 &expose_rect_h,							 &expose_rect_v);		if (can_scroll) {		zoom_region_update_pixmap (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, expose_rect_h), NULL);		zoom_region_update_pixmap (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, expose_rect_v), NULL);		if (zoom_region->smooth_scroll_policy > GNOME_Magnifier_ZoomRegion_SCROLL_FAST) {			zoom_region_scroll_smooth (zoom_region, dx, dy,						   &scroll_rect,						   &expose_rect_h,						   &expose_rect_v);		} else {			zoom_region_scroll_fast (zoom_region, dx, dy,						 &scroll_rect,						 &expose_rect_h,						 &expose_rect_v);		}	} else {		zoom_region_queue_update (zoom_region, zoom_region_source_rect_from_view_rect (zoom_region, scroll_rect));	}}static voidzoom_region_recompute_exposed_bounds (ZoomRegion *zoom_region){	zoom_region->priv->exposed_bounds.x2 = zoom_region->priv->exposed_bounds.x1		+ (zoom_region->viewport.x2 - zoom_region->viewport.x1);	zoom_region->priv->exposed_bounds.y2 = zoom_region->priv->exposed_bounds.y1		+ (zoom_region->viewport.y2 - zoom_region->viewport.y1);}static voidzoom_region_set_cursor_pos (ZoomRegion *zoom_region, int x, int y){	if (zoom_region->priv)	{		zoom_region->priv->last_cursor_pos.x = x;		zoom_region->priv->last_cursor_pos.y = y;	}}static gbooleanzoom_region_update_pointer (ZoomRegion *zoom_region, gboolean draw_cursor){	Magnifier *magnifier;	gint mouse_x_return, mouse_y_return;	guint mask_return;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (!zoom_region->priv || !zoom_region->priv->parent 	    || !zoom_region->poll_mouse)	      return FALSE; 	magnifier = zoom_region->priv->parent;	/* TODO: there's really no reason we should be using magnifier->priv->root here */	if (magnifier && magnifier->priv && magnifier_get_root (magnifier))	{		gdk_window_get_pointer (			magnifier_get_root (magnifier),			&mouse_x_return,			&mouse_y_return,			&mask_return);				if (zoom_region->priv->last_cursor_pos.x != mouse_x_return		    || zoom_region->priv->last_cursor_pos.y != mouse_y_return)		{			zoom_region_set_cursor_pos (zoom_region,						    mouse_x_return, mouse_y_return);			if (draw_cursor)			{				GdkRectangle paint_area, *clip = NULL;				if (GTK_IS_WIDGET (zoom_region->priv->w) && 				    GDK_IS_DRAWABLE (zoom_region->priv->w->window))				{					gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window), &paint_area.width, &paint_area.height);					paint_area.x = 0;					paint_area.y = 0;					clip = &paint_area;					paint_area = 						zoom_region_clip_to_source (							zoom_region,							paint_area);				}				zoom_region_update_cursor (zoom_region, 0, 0,							   clip);			}			return TRUE;		}	}		return FALSE;}static intzoom_region_update_pointer_idle (gpointer data){	ZoomRegion *zoom_region = (ZoomRegion *) data;	if (zoom_region_update_pointer (zoom_region, TRUE))	        return TRUE;	else {		if (zoom_region->priv)			zoom_region->priv->update_pointer_id =			    g_timeout_add_full (G_PRIORITY_DEFAULT,						100,						zoom_region_update_pointer_timeout,						zoom_region,						NULL);                return FALSE;	}}static intzoom_region_update_pointer_timeout (gpointer data){	ZoomRegion *zoom_region = data;	if (zoom_region->priv && zoom_region_update_pointer (zoom_region, TRUE)) {	    zoom_region->priv->update_pointer_id =	        g_idle_add_full (G_PRIORITY_HIGH_IDLE,				 zoom_region_update_pointer_idle,				 data,				 NULL);		return FALSE;	} else 		return TRUE;}static voidzoom_region_moveto (ZoomRegion *zoom_region,		    const long x, const long y){	long dx = x * zoom_region->xscale - zoom_region->priv->exposed_bounds.x1;	long dy = y * zoom_region->yscale - zoom_region->priv->exposed_bounds.y1;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif/* fprintf (stderr, "moveto %ld %ld\n", x, y); */	mag_timing.dx = 0;	mag_timing.dy = 0;	if ((dx != 0) || (dy != 0)) {		zoom_region_update_pointer (zoom_region, FALSE);		zoom_region->priv->exposed_bounds.x1 = x * zoom_region->xscale;		zoom_region->priv->exposed_bounds.y1 = y * zoom_region->yscale;		zoom_region_recompute_exposed_bounds (zoom_region);		zoom_region_scroll (zoom_region,				    -dx, -dy);	}}/* * Process that must be made in-line in the current pixbuf. */static voidzoom_region_process_pixbuf (ZoomRegion *zoom_region, GdkPixbuf *pixbuf){	int rowstride = gdk_pixbuf_get_rowstride (pixbuf);	int i, j, t;	int w = gdk_pixbuf_get_width (pixbuf);	int h = gdk_pixbuf_get_height (pixbuf);	int n_channels = gdk_pixbuf_get_n_channels (pixbuf);	guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);	guchar *pixels_row;#ifdef HAVE_COLORBLIND 	COLORBLIND_RUNTIME *cbr; 	COLORBLIND_XCOLOR *color;#endif /* HAVE_COLORBLIND */	gboolean manipulate_contrast = FALSE;	gboolean manipulate_brightness = FALSE;	gboolean color_blind_filter = FALSE;	if (zoom_region->contrast_r != 0 || zoom_region->contrast_g != 0 ||	    zoom_region->contrast_b != 0) {		manipulate_contrast = TRUE;	}	if (zoom_region->bright_r != 0 || zoom_region->bright_g != 0 ||	    zoom_region->bright_b != 0) {		manipulate_brightness = TRUE;	}#ifdef HAVE_COLORBLIND 	if (zoom_region->color_blind_filter != 	    GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER) { 		color_blind_filter = TRUE; 		cbr = colorblind_create (); 		color = malloc (sizeof (COLORBLIND_XCOLOR)); 		switch (zoom_region->color_blind_filter) { 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_NO_FILTER: 			break; /* This entry is only to avoid a warning */ 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_RED: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_red); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_GREEN: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_green); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE_BLUE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate_blue); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_RED: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_red); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_GREEN: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_green); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE_BLUE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate_blue); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_HUE_SHIFT_POSITIVE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_hue_shift_positive); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_HUE_SHIFT_NEGATIVE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_hue_shift_negative); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_SATURATE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_saturate); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_SELECTIVE_DESSATURATE: 			colorblind_set_filter_type (cbr, colorblind_filter_t_selective_dessaturate); 			break; 		case GNOME_Magnifier_ZoomRegion_COLORBLIND_FILTER_T_MONOCHRONE_OTHERS: 			colorblind_set_filter_type (cbr, colorblind_filter_t_monochrome_others); 			break; 		} 	}#endif /* HAVE_COLORBLIND */	if (!manipulate_contrast && !zoom_region->invert &&	    !manipulate_brightness && !color_blind_filter)		return;#define CLAMP_UCHAR(v) (t = (v), CLAMP (t, 0, 255))#define CLAMP_LOW_MID(v) (t = (v), CLAMP (t, 0, 127))#define CLAMP_MID_HIGH(v) (t = (v), CLAMP (t, 127, 255))	for (j = 0; j < h; ++j) {		pixels_row = pixels;		for (i = 0; i < w; ++i) {			if (manipulate_contrast) {				/* Set the RED contrast */				if (pixels_row[0] <= 127)					pixels_row[0] = CLAMP_LOW_MID (pixels_row[0] - zoom_region->contrast_r * 127);				else					pixels_row[0] = CLAMP_MID_HIGH (pixels_row[0] + zoom_region->contrast_r * 127);				/* Set the GREEN contrast */				if (pixels_row[1] <= 127)					pixels_row[1] = CLAMP_LOW_MID (pixels_row[1] - zoom_region->contrast_g * 127);				else					pixels_row[1] = CLAMP_MID_HIGH (pixels_row[1] + zoom_region->contrast_g * 127);				/* Set the BLUE contrast */				if (pixels_row[2] <= 127)					pixels_row[2] = CLAMP_LOW_MID (pixels_row[2] - zoom_region->contrast_b * 127);				else					pixels_row[2] = CLAMP_MID_HIGH (pixels_row[2] + zoom_region->contrast_b * 127);			}			if (manipulate_brightness) {				/* Set the RED brightness */				pixels_row[0] = CLAMP_UCHAR (pixels_row[0] + zoom_region->bright_r * 255);								/* Set the GREEN brightness */				pixels_row[1] = CLAMP_UCHAR (pixels_row[1] + zoom_region->bright_g * 255);				/* Set the BLUE brightness */				pixels_row[2] = CLAMP_UCHAR (pixels_row[2] + zoom_region->bright_b * 255);			}			if (zoom_region->invert) {				pixels_row[0] = ~(pixels_row[0]);				pixels_row[1] = ~(pixels_row[1]);				pixels_row[2] = ~(pixels_row[2]);			}#ifdef HAVE_COLORBLIND			if (color_blind_filter) {				color->red   = pixels_row[0];				color->green = pixels_row[1];				color->blue  = pixels_row[2];				if (colorblind_filter (cbr, color)) {					pixels_row[0] = color->red;					pixels_row[1] = color->green;					pixels_row[2] = color->blue;				}			}#endif /* HAVE_COLORBLIND */						pixels_row += n_channels;		}		pixels += rowstride;	}}static voidzoom_region_post_process_pixbuf (ZoomRegion *zoom_region,				 GdkPixbuf *subimage,				 GdkPixbuf *scaled_image){	/* nothing yet */	/**	 * ADI: This is where your image smoothing code	 * hooks into the magnifier.  This routine can call others which	 * post-process the GdkPixbuf before rendering to the screen.	 *	 * We can make this a two-stage process also, whereby the post-process code	 * is only called in a lower-priority idle handler, and queues repaints	 * when it is done.	 **/}static GdkPixbuf *zoom_region_get_source_subwindow (ZoomRegion *zoom_region,				  const GdkRectangle bounds){	int i, j, width, height;	Magnifier *magnifier = zoom_region->priv->parent;	GdkPixbuf *subimage = NULL;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	width = gdk_screen_get_width (		gdk_display_get_screen (magnifier->source_display,					magnifier->source_screen_num));	height = gdk_screen_get_height (		gdk_display_get_screen (magnifier->source_display,					magnifier->source_screen_num));	if ((bounds.width <= 0) || (bounds.height <= 0))	{		return NULL;	}		if (!zoom_region->priv->source_drawable)	{		/* TESTING ONLY */		if (zoom_region->priv->test) {			GdkImage *test_image = NULL;

⌨️ 快捷键说明

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