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

📄 zoom-region.c

📁 在Linux下实现magnification功能
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	}	return q;}#endif/*#define _is_horizontal_rect(r)   (((2 * (r)->width / 3 * (r)->height)) > 1)*//*#define _is_vertical_rect(r)   (((2 * (r)->height / 3 * (r)->width)) > 1)*/#define _is_horizontal_rect(r) ((r)->width > (r)->height) #define _is_vertical_rect(r)   ((r)->height > (r)->width)/** * _coalesce_update_rects : * coalesces multiple "vertical" rects and "horizontal" * rects into one of each.  Can result in overlapping/larger * update area for tiled rects, but reduces queue size dramatically. **/static GList *_coalesce_update_rects (GList *q, int min_coalesce_length){	GdkRectangle *v = NULL, *h = NULL;	GList *compact_queue = NULL;/*	fprintf (stderr, "starting queue length = %d\n", g_list_length (q)); */	if (g_list_length (q) < min_coalesce_length) 		return g_list_copy (q);	while (q)	{		if (_is_vertical_rect ((GdkRectangle *) (q->data)))		{			if (v) gdk_rectangle_union (v, q->data, v);			else			{				v = g_new0 (GdkRectangle, 1);				*v = *(GdkRectangle *)q->data;			}		}		else if (_is_horizontal_rect ((GdkRectangle *) (q->data)))		{			if (h) gdk_rectangle_union (h, q->data, h);			else			{				h = g_new0 (GdkRectangle, 1);				*h = *(GdkRectangle *)q->data;			}		}		else			compact_queue = g_list_prepend (compact_queue, q->data);		q = q->next;	};	if (v)		compact_queue = g_list_prepend (compact_queue, v);	if (h)		compact_queue = g_list_prepend (compact_queue, h);/*	fprintf (stderr, "ending queue length = %d\n", g_list_length (compact_queue));*/	/* don't free the original queue, that's the caller's responsibility */	return compact_queue;}#ifdef BROKEN_COALESCE_STUFF_GETS_FIXEDstatic GList *_smartbutbroken_coalesce_update_rects (GList *q, int lookahead_n){	int i = 0, len;	fprintf (stderr, "starting queue length = %d\n", g_list_length (q));	do {		GdkRectangle *a;		len = g_list_length (q);		q = _combine_update_rects (q, lookahead_n);		a = q->data;		while (i < lookahead_n && q && q->next)		{			if (_refactor_rects (a, q->next->data))				break;			else				++i;		}		q = _combine_update_rects (q, lookahead_n);	} while (g_list_length (q) < len);	fprintf (stderr, "ending queue length = %d\n", g_list_length (q));	return q;}#endif/** COORDINATE CONVERSIONS **//** clip an area in source coords to the exposed target area **/static GdkRectangle_rectangle_clip_to_rectangle (GdkRectangle area,			      GdkRectangle clip_rect){        GdkRectangle clipped;        clipped.x = MAX (area.x, clip_rect.x);        clipped.y = MAX (area.y, clip_rect.y);        clipped.width = MIN ((area.x + area.width), (clip_rect.x + clip_rect.width)) - clipped.x;        clipped.height = MIN ((area.y + area.height), (clip_rect.y + clip_rect.height)) - clipped.y;	return clipped;}static GdkRectangle_rectangle_clip_to_bounds (GdkRectangle area,			   GNOME_Magnifier_RectBounds *clip_bounds){	area.x = MAX (area.x, clip_bounds->x1);	area.x = MIN (area.x, clip_bounds->x2);	area.width = MIN (area.width, clip_bounds->x2 - area.x);	area.y = MAX (area.y, clip_bounds->y1);	area.y = MIN (area.y, clip_bounds->y2);	area.height = MIN (area.height, clip_bounds->y2 - area.y);	return area;}static GdkRectanglezoom_region_clip_to_source (ZoomRegion *zoom_region,			    GdkRectangle area){    GNOME_Magnifier_RectBounds *source_rect_ptr;    if (zoom_region && zoom_region->priv && zoom_region->priv->parent)    {	source_rect_ptr = &((Magnifier *)zoom_region->priv->parent)->source_bounds;        DEBUG_RECT ("clipping to source bounds", zoom_region_rect_from_bounds (zoom_region, source_rect_ptr)); 	return _rectangle_clip_to_bounds (area, source_rect_ptr);    }    return area;}static GdkRectanglezoom_region_clip_to_exposed_target (ZoomRegion *zoom_region,				    GdkRectangle area){	GNOME_Magnifier_RectBounds onscreen_target, *source_area;	source_area = &zoom_region->priv->source_area;	onscreen_target.x1 = MAX (floor (zoom_region->priv->exposed_bounds.x1					 / zoom_region->xscale),					 source_area->x1);	onscreen_target.y1 = MAX (floor (zoom_region->priv->exposed_bounds.y1					 / zoom_region->yscale),					 source_area->y1);	onscreen_target.x2 = MIN (ceil (zoom_region->priv->exposed_bounds.x2					/ zoom_region->xscale),					source_area->x2);	onscreen_target.y2 = MIN (ceil (zoom_region->priv->exposed_bounds.y2					/ zoom_region->yscale),					source_area->y2);	return _rectangle_clip_to_bounds (area, &onscreen_target);}static GdkRectanglezoom_region_clip_to_scaled_pixmap (ZoomRegion *zoom_region,				   GdkRectangle area){        GdkRectangle pixmap_area = {0, 0, 0, 0};	if (zoom_region->priv && zoom_region->priv->pixmap)	{	    gdk_drawable_get_size (zoom_region->priv->pixmap, &pixmap_area.width, &pixmap_area.height);	    return _rectangle_clip_to_rectangle (area, pixmap_area);	}	else	    return area;}static GdkRectanglezoom_region_clip_to_window (ZoomRegion *zoom_region,			    GdkRectangle area){	GdkRectangle window_rect;	/* we can just return ATM because _rectangle_clip_to_rectangle is unimplemented now */	return area;	if (zoom_region->priv->w->window)		gdk_drawable_get_size (GDK_DRAWABLE (zoom_region->priv->w->window),				       &window_rect.x,				       &window_rect.y);	else 	{		window_rect.x = 0;		window_rect.y = 0;	}	return _rectangle_clip_to_rectangle (area, window_rect);}static const GdkRectanglezoom_region_source_rect_from_view_bounds (ZoomRegion *zoom_region,					  const GNOME_Magnifier_RectBounds *view_bounds){	GdkRectangle source_rect;	source_rect.x = floor ((view_bounds->x1 + zoom_region->priv->exposed_bounds.x1)			       / zoom_region->xscale);	source_rect.y = floor ((view_bounds->y1 + zoom_region->priv->exposed_bounds.y1)				/ zoom_region->yscale);	source_rect.width = ceil ((view_bounds->x2 - view_bounds->x1) / zoom_region->xscale) + 1;	source_rect.height = ceil ((view_bounds->y2 - view_bounds->y1) / zoom_region->yscale) + 1;	return source_rect;}static GdkRectanglezoom_region_view_rect_from_source_rect (ZoomRegion *zoom_region,					const GdkRectangle source_rect){	GdkRectangle view_rect;	view_rect.x = source_rect.x * zoom_region->xscale - zoom_region->priv->exposed_bounds.x1;	view_rect.y = source_rect.y * zoom_region->yscale - zoom_region->priv->exposed_bounds.y1;	view_rect.width = source_rect.width * zoom_region->xscale;	view_rect.height = source_rect.height * zoom_region->yscale;	DEBUG_RECT ("source", source_rect);	DEBUG_RECT ("converted to view-rect", view_rect);	return view_rect;}static GdkRectanglezoom_region_source_rect_from_view_rect (ZoomRegion *zoom_region,					const GdkRectangle view_rect){	GdkRectangle source_rect;	source_rect.x = floor ((view_rect.x + zoom_region->priv->exposed_bounds.x1)			       / zoom_region->xscale);	source_rect.y = floor ((view_rect.y + zoom_region->priv->exposed_bounds.y1)				/ zoom_region->yscale);	source_rect.width = ceil (view_rect.width / zoom_region->xscale) + 1;	source_rect.height = ceil (view_rect.height / zoom_region->yscale) + 1;	return source_rect;}static GdkRectanglezoom_region_rect_from_bounds (ZoomRegion *zoom_region,			      const GNOME_Magnifier_RectBounds *bounds){	GdkRectangle rect;	rect.x = bounds->x1;	rect.y = bounds->y1;	rect.width = bounds->x2 - bounds->x1;	rect.height = bounds->y2 - bounds->y1;	return rect;}/** **************  **/static CORBA_booleanzoom_region_update_scale (ZoomRegion *zoom_region, gdouble x, gdouble y){	gdouble x_old = zoom_region->xscale;	gdouble y_old = zoom_region->yscale;	zoom_region->xscale = x;	zoom_region->yscale = y;	if (zoom_region->priv->scaled_pixbuf)		g_object_unref (zoom_region->priv->scaled_pixbuf);	zoom_region->priv->scaled_pixbuf =		gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, (zoom_region->priv->source_area.x2 - zoom_region->priv->source_area.x1) * zoom_region->xscale + 1, (zoom_region->priv->source_area.y2 - zoom_region->priv->source_area.y1) * zoom_region->yscale + 1);	if (zoom_region->priv->pixmap)		g_object_unref (zoom_region->priv->pixmap);	if (zoom_region_create_pixmap (zoom_region) ==	    ZOOM_REGION_ERROR_TOO_BIG) {		zoom_region->xscale = x_old;		zoom_region->yscale = y_old;		zoom_region_create_pixmap (zoom_region);		g_object_unref (zoom_region->priv->scaled_pixbuf);		/* only create a scaled image big enough for the target		 * display, for now */		zoom_region->priv->scaled_pixbuf = gdk_pixbuf_new (			GDK_COLORSPACE_RGB, FALSE, 8, (zoom_region->priv->source_area.x2 - zoom_region->priv->source_area.x1) * zoom_region->xscale + 1, (zoom_region->priv->source_area.y2 - zoom_region->priv->source_area.y1) * zoom_region->yscale + 1);		return CORBA_FALSE;	}	return CORBA_TRUE;}static voidzoom_region_queue_update (ZoomRegion *zoom_region,			  const GdkRectangle update_rect){	GdkRectangle *rect =		g_new0 (GdkRectangle, 1);	*rect = update_rect;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	DEBUG_RECT ("queueing update", *rect);	zoom_region->priv->q =		g_list_prepend (zoom_region->priv->q, rect);	if (zoom_region->priv && zoom_region->priv->update_handler_id == 0)		zoom_region->priv->update_handler_id = 			g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,					 zoom_region_process_updates,					 zoom_region,					 NULL);}static voidzoom_region_update_current (ZoomRegion *zoom_region){#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (zoom_region->priv)	{		gboolean pixmap_valid = GDK_IS_DRAWABLE (zoom_region->priv->pixmap);		if (!pixmap_valid)			pixmap_valid = (zoom_region_create_pixmap (zoom_region) == ZOOM_REGION_ERROR_NONE);		if (pixmap_valid)			zoom_region_update (zoom_region,					    zoom_region_source_rect_from_view_bounds (						    zoom_region,						    &zoom_region->viewport));	}}static GdkRectanglezoom_region_cursor_rect (ZoomRegion *zoom_region){	GdkRectangle rect = {0, 0, 0, 0};	Magnifier *magnifier = zoom_region->priv->parent;	GdkDrawable *cursor = NULL;	if (magnifier)		cursor = magnifier_get_cursor (magnifier);	if (cursor)	{		rect.x = zoom_region->priv->last_cursor_pos.x;		rect.y = zoom_region->priv->last_cursor_pos.y;		rect = zoom_region_view_rect_from_source_rect (zoom_region, rect);		rect.x -= magnifier->cursor_hotspot.x;		rect.y -= magnifier->cursor_hotspot.y;		gdk_drawable_get_size (cursor, &rect.width, &rect.height);	}	return rect;}static voidzoom_region_unpaint_crosswire_cursor (ZoomRegion *zoom_region,				      GdkRectangle *clip_rect){	Magnifier *magnifier = zoom_region->priv->parent;	GdkRectangle vline_rect, hline_rect;	GdkPoint cursor_pos;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (!magnifier || magnifier->crosswire_size <= 0) return;	cursor_pos = zoom_region->priv->last_drawn_crosswire_pos;	vline_rect.x = cursor_pos.x - magnifier->crosswire_size/2;	vline_rect.y = clip_rect ? clip_rect->y : 0; 	vline_rect.width = MAX (magnifier->crosswire_size, 1);	vline_rect.height = clip_rect ? clip_rect->height : 4096; 	hline_rect.x = clip_rect ? clip_rect->x : 0; 	hline_rect.y = cursor_pos.y - magnifier->crosswire_size/2;	hline_rect.width = clip_rect ? clip_rect->width : 4096;	hline_rect.height = MAX (magnifier->crosswire_size, 1);	zoom_region_paint_pixmap (zoom_region, &vline_rect);	zoom_region_paint_pixmap (zoom_region, &hline_rect);}static voidzoom_region_paint_crosswire_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_rect){	Magnifier *magnifier = zoom_region->priv->parent;	static GdkColormap *cmap;	static GdkColor last_color;	static gboolean last_color_init = FALSE;	GdkGCValues values;	GdkRectangle rect;	GdkDrawable *cursor;	GdkColor color = {0, 0, 0, 0};	int x_left_clip = 0, x_right_clip = 0, y_top_clip = 0, y_bottom_clip = 0;	int csize = 0;	#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (!(magnifier &&	      zoom_region->priv->w->window &&	      GDK_IS_DRAWABLE (zoom_region->priv->w->window) &&	      magnifier->crosswire_size > 0)) return;	if (zoom_region->priv->crosswire_gc == NULL) 	{		zoom_region->priv->crosswire_gc = gdk_gc_new (zoom_region->priv->w->window);		cmap = gdk_gc_get_colormap(zoom_region->priv->crosswire_gc);		last_color_init = FALSE;	}	if (magnifier->crosswire_color == 0)	{		color.red = 0xFFFF;		color.blue = 0xFFFF;		color.green = 0xFFFF;		values.function = GDK_INVERT;	}	else	{		color.red = (magnifier->crosswire_color & 0xFF0000) >> 8;		color.green = (magnifier->crosswire_color & 0xFF00);		color.blue = (magnifier->crosswire_color & 0xFF) << 8;		values.function = GDK_COPY;	}	values.foreground = color;	/* Only reset colors if they have changed */    if (!last_color_init || color.red != last_color.red ||	    color.blue != last_color.blue || color.green != last_color.green)	{		if (cmap)		{			gdk_rgb_find_color (cmap, &(values.foreground));			gdk_gc_set_values(zoom_region->priv->crosswire_gc, &values, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);		}		else		{			gdk_gc_set_values(zoom_region->priv->crosswire_gc, &values, GDK_GC_FUNCTION);		}		last_color.red   = color.red;		last_color.blue  = color.blue;		last_color.green = color.green;		last_color_init  = TRUE;	}

⌨️ 快捷键说明

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