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

📄 zoom-region.c

📁 在Linux下实现magnification功能
💻 C
📖 第 1 页 / 共 5 页
字号:
	rect.x = zoom_region->priv->last_cursor_pos.x;	rect.y = zoom_region->priv->last_cursor_pos.y;	rect.width = 0;	rect.height = 0;	rect = zoom_region_view_rect_from_source_rect (zoom_region, rect);	if (clip_rect) gdk_gc_set_clip_rectangle (zoom_region->priv->crosswire_gc, clip_rect);	else gdk_gc_set_clip_rectangle (zoom_region->priv->crosswire_gc, NULL);	if ((cursor = magnifier_get_cursor (magnifier))) {		gdk_drawable_get_size (cursor, &csize, &csize);	}	if (magnifier->crosswire_clip)	{		y_top_clip = rect.y - magnifier->cursor_hotspot.y -			magnifier->crosswire_size;		y_bottom_clip = rect.y +			(csize - magnifier->cursor_hotspot.y) +			magnifier->crosswire_size;		x_left_clip = rect.x - magnifier->cursor_hotspot.x -			magnifier->crosswire_size;		x_right_clip = rect.x +			(csize - magnifier->cursor_hotspot.x) +			magnifier->crosswire_size;	}	if (magnifier->crosswire_size == 1)	{		if (magnifier->crosswire_clip)		{			gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, rect.x, 0,				       rect.x, y_top_clip);			gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, 0, rect.y,				       x_left_clip, rect.y);		}		gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, rect.x,			       y_bottom_clip, rect.x, 4096);		gdk_draw_line (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, x_right_clip,			       rect.y, 4096, rect.y);	}	else	{		if (magnifier->crosswire_clip )		{			gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE,					    rect.x - magnifier->crosswire_size / 2,					    0, magnifier->crosswire_size, y_top_clip);			gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, 0,					    rect.y - magnifier->crosswire_size / 2,					    x_left_clip, magnifier->crosswire_size);		}		gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE,				    rect.x - magnifier->crosswire_size / 2,				    y_bottom_clip, magnifier->crosswire_size, 4096);		gdk_draw_rectangle (zoom_region->priv->w->window, zoom_region->priv->crosswire_gc, TRUE, x_right_clip,				    rect.y - magnifier->crosswire_size / 2,				    4096, magnifier->crosswire_size);	}}static voidzoom_region_unpaint_cursor (ZoomRegion *zoom_region, GdkRectangle *clip_rect){#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	zoom_region_paint_pixmap (zoom_region,				  &zoom_region->priv->cursor_backing_rect);}static voidzoom_region_paint_cursor (ZoomRegion *zoom_region,			  GdkRectangle *clip_rect){	GdkGCValues values;	GdkRectangle rect, intersct;	GdkRectangle fullscreen;	Magnifier *magnifier = zoom_region->priv->parent;	rect = zoom_region_cursor_rect (zoom_region);#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (clip_rect == NULL)	{		fullscreen = zoom_region_rect_from_bounds (zoom_region,							   &zoom_region->viewport);		clip_rect = &fullscreen;	}	/* save the unclipped cursor pos for 'undrawing' the crosswire, the clipped one is no good */	zoom_region->priv->last_drawn_crosswire_pos.x = rect.x + magnifier->cursor_hotspot.x;	zoom_region->priv->last_drawn_crosswire_pos.y = rect.y + magnifier->cursor_hotspot.y;	if (gdk_rectangle_intersect (clip_rect, &rect, &intersct))	{		int width = 0, height = 0;				GdkDrawable *cursor = magnifier_get_cursor (magnifier);		if (!cursor)			return;		else if (!GDK_IS_DRAWABLE (cursor)) g_message ("cursor isn't DRAWABLE!");		zoom_region->priv->cursor_backing_rect = rect;		if (zoom_region->priv->cursor_backing_pixels) {			gdk_drawable_get_size (zoom_region->priv->cursor_backing_pixels,					       &width, &height);		}		if (rect.width != width || rect.height != height)		{			if (zoom_region->priv->cursor_backing_pixels) {				g_object_unref (zoom_region->priv->cursor_backing_pixels);			}			zoom_region->priv->cursor_backing_pixels =				gdk_pixmap_new (zoom_region->priv->w->window,						rect.width,						rect.height,						-1);		}		if (zoom_region->priv->w->window != NULL)		{			if (zoom_region->priv->default_gc == NULL) 				zoom_region->priv->default_gc = gdk_gc_new(zoom_region->priv->w->window);			gdk_draw_drawable (zoom_region->priv->cursor_backing_pixels,				     zoom_region->priv->default_gc,				     zoom_region->priv->w->window,				     rect.x,				     rect.y,				     0, 0,				     rect.width,				     rect.height);		}		DEBUG_RECT ("painting", rect);		if (cursor && zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window))		{		    if (zoom_region->priv->paint_cursor_gc == NULL)				zoom_region->priv->paint_cursor_gc = gdk_gc_new (zoom_region->priv->w->window);			gdk_gc_set_clip_rectangle (zoom_region->priv->paint_cursor_gc, clip_rect);			values.clip_x_origin = rect.x;			values.clip_y_origin = rect.y;			values.clip_mask = magnifier->priv->cursor_mask;			gdk_gc_set_values(zoom_region->priv->paint_cursor_gc, &values, GDK_GC_CLIP_X_ORIGIN |					  GDK_GC_CLIP_Y_ORIGIN  | GDK_GC_CLIP_MASK);			gdk_draw_rectangle (zoom_region->priv->w->window,					   zoom_region->priv->paint_cursor_gc,					   TRUE,					   rect.x, rect.y, rect.width, rect.height);			gdk_draw_drawable (zoom_region->priv->w->window,					   zoom_region->priv->paint_cursor_gc,					   cursor,					   0, 0,					   rect.x,					   rect.y,					   rect.width,					   rect.height);		}	}}/** * zoom_region_coalesce_updates: *  **/static voidzoom_region_coalesce_updates (ZoomRegion *zoom_region){	/* TODO: lock the queue ? */	GList *q;	int lookahead_n = 4; /* 'distance' to look ahead in queue */	int max_qlen = 50;	if (zoom_region->priv && zoom_region->priv->q && g_list_length (zoom_region->priv->q) > max_qlen)	{		g_list_free (zoom_region->priv->q);		zoom_region->priv->q = NULL; /* just discard and update everything */		/* CAUTION: this can be an expensive operation! */		zoom_region_queue_update (zoom_region, zoom_region_rect_from_bounds					  (zoom_region, &zoom_region->priv->source_area));	}	else         if (zoom_region->priv && zoom_region->priv->q && 	    (g_list_length (zoom_region->priv->q) > 1) && can_coalesce)	{				q = g_list_reverse (g_list_copy (zoom_region->priv->q));		if (q)		{			GList *coalesce_copy;			if (zoom_region->coalesce_func)			{				GList *new;				coalesce_copy = (*zoom_region->coalesce_func) (q, lookahead_n);				new = g_list_reverse (coalesce_copy);				g_list_free (zoom_region->priv->q);				zoom_region->priv->q = new;			}			g_list_free (q);		}	}}static voidzoom_region_paint_border (ZoomRegion *zoom_region){	GdkColor color;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if ((zoom_region->border_size > 0) &&	    (zoom_region->priv->border->window)) {		color.red = (((zoom_region->border_color & 0xFF0000) >> 16) *			     65535) / 255;		color.green = (((zoom_region->border_color & 0xFF00) >> 8) *			       65535) / 255;		color.blue = ((zoom_region->border_color & 0xFF) * 65535) /			255;#ifdef DEBUG_BORDER		fprintf (stderr, "border color triple RGB=%d|%d|%d\n",			 color.red, color.green, color.blue);#endif		gtk_widget_modify_bg (zoom_region->priv->border,				      GTK_STATE_NORMAL, &color);	}}static voidzoom_region_paint_pixmap (ZoomRegion *zoom_region,			  GdkRectangle *area){#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	g_assert (zoom_region->priv);	g_assert (zoom_region->priv->w);        if (!GDK_IS_DRAWABLE (zoom_region->priv->w->window)) return;	if (zoom_region->priv->default_gc == NULL) 		zoom_region->priv->default_gc = gdk_gc_new (zoom_region->priv->w->window);	if (zoom_region->priv->pixmap && GDK_IS_DRAWABLE (zoom_region->priv->w->window))	{		gdk_draw_drawable (zoom_region->priv->w->window,				   zoom_region->priv->default_gc,				   zoom_region->priv->pixmap,				   area->x + zoom_region->priv->exposed_bounds.x1 - zoom_region->priv->source_area.x1 * zoom_region->xscale,				   area->y + zoom_region->priv->exposed_bounds.y1 - zoom_region->priv->source_area.y1 * zoom_region->yscale,				   area->x,				   area->y,				   area->width,				   area->height);	}}/** * Note: clips to region's current GdkWindow. **/static voidzoom_region_paint (ZoomRegion *zoom_region,		   GdkRectangle *area){	GdkRectangle paint_area;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	DEBUG_RECT ("painting (clipped)", *area);	paint_area = zoom_region_clip_to_window (zoom_region, *area);	zoom_region_paint_pixmap (zoom_region, &paint_area);	zoom_region_paint_cursor (zoom_region, &paint_area);	zoom_region_paint_crosswire_cursor (zoom_region, &paint_area);}static ZoomRegionPixmapCreationErrorzoom_region_create_pixmap (ZoomRegion *zoom_region){#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (zoom_region->priv->w && GDK_IS_DRAWABLE (zoom_region->priv->w->window))	{		long width = (zoom_region->priv->source_area.x2 -			      zoom_region->priv->source_area.x1) * zoom_region->xscale;		long height = (zoom_region->priv->source_area.y2 -			       zoom_region->priv->source_area.y1) * zoom_region->yscale;		zoom_region->priv->pixmap =			gdk_pixmap_new (				zoom_region->priv->w->window,				width,				height,				gdk_drawable_get_depth (					zoom_region->priv->w->window));		if (magnifier_error_check ()) {			zoom_region->priv->pixmap = NULL;			return ZOOM_REGION_ERROR_TOO_BIG;		}		DEBUG_RECT("viewport", zoom_region_source_rect_from_view_bounds			   (zoom_region, &zoom_region->viewport));		DEBUG_RECT("source", zoom_region_rect_from_bounds			   (zoom_region, &((Magnifier*)zoom_region->priv->parent)->source_bounds));		zoom_region_update (zoom_region,/*				    zoom_region_source_rect_from_view_bounds (				    zoom_region,				    &zoom_region->viewport));*/				    zoom_region_rect_from_bounds 				    (zoom_region, 				     &((Magnifier *)zoom_region->priv->parent)->source_bounds));		return ZOOM_REGION_ERROR_NONE;	}		return ZOOM_REGION_ERROR_NO_TARGET_DRAWABLE;}static voidzoom_region_expose_handler (GtkWindow * w,			    GdkEventExpose *event,			    gpointer data){	ZoomRegion *zoom_region = data;	DEBUG_RECT ("expose", event->area);#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	if (zoom_region->priv->pixmap == NULL)	{	        ZoomRegionPixmapCreationError ret; 		/* TODO: scale down if this fails here */		while ((ret = zoom_region_create_pixmap (zoom_region)) ==		    ZOOM_REGION_ERROR_TOO_BIG) {			zoom_region->xscale -= 1.0;			zoom_region->yscale -= 1.0;			zoom_region->priv->pixmap = NULL;			g_warning ("Scale factor too big to fit in memory; shrinking.");		}		if (ret == ZOOM_REGION_ERROR_NO_TARGET_DRAWABLE) 		    g_warning ("create-pixmap: no target drawable");	}	zoom_region_paint (zoom_region, &event->area);}static voidzoom_region_update_cursor (ZoomRegion *zoom_region, int dx, int dy,			   GdkRectangle *clip_rect){#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	zoom_region_unpaint_crosswire_cursor (zoom_region, clip_rect);	zoom_region_unpaint_cursor (zoom_region, clip_rect);	zoom_region->priv->cursor_backing_rect.x += dx;	zoom_region->priv->cursor_backing_rect.y += dy;	zoom_region->priv->last_drawn_crosswire_pos.x += dx;	zoom_region->priv->last_drawn_crosswire_pos.y += dy;	zoom_region_paint_cursor (zoom_region, clip_rect);	zoom_region_paint_crosswire_cursor (zoom_region, clip_rect);	if (GTK_IS_WIDGET (zoom_region->priv->w) &&	    GDK_IS_WINDOW (zoom_region->priv->w->window))		gdk_display_sync (gdk_drawable_get_display (					  zoom_region->priv->w->window));}static gbooleanzoom_region_calculate_scroll_rects (ZoomRegion *zoom_region,				    int dx, int dy,				    GdkRectangle *scroll_rect,				    GdkRectangle *expose_rect_h,				    GdkRectangle *expose_rect_v){	GdkWindow *window = NULL;	GdkRectangle rect = {0, 0, 0, 0};	gboolean retval = TRUE;#ifdef ZOOM_REGION_DEBUG	g_assert (zoom_region->alive);#endif	rect.x = 0;	rect.y = 0;	if (zoom_region && zoom_region->priv->w &&	    zoom_region->priv->w->window)		window = zoom_region->priv->w->window;	else		retval = FALSE;	if (!window)		retval = FALSE;	if (window != NULL)	  gdk_drawable_get_size (GDK_DRAWABLE (window),				 &rect.width,				 &rect.height);	if ((ABS (dx) >= rect.width) || (ABS (dy) >= rect.height)) {		*scroll_rect = rect;		DBG(fprintf (stderr, "deltas too big to scroll\n"));		retval = FALSE;	}	else {	    scroll_rect->x = MAX (0, dx);	    scroll_rect->y = MAX (0, dy);	    scroll_rect->width = MIN (rect.width + dx, rect.width - dx);	    scroll_rect->height = MIN (rect.height + dy, rect.height - dy);	}	expose_rect_h->x = 0;	expose_rect_h->y = (scroll_rect->y == 0) ? scroll_rect->height : 0;	expose_rect_h->width = rect.width;	expose_rect_h->height = rect.height - scroll_rect->height;	expose_rect_v->x = (scroll_rect->x == 0) ? scroll_rect->width : 0;	expose_rect_v->y = scroll_rect->y;	expose_rect_v->width = rect.width - scroll_rect->width;	expose_rect_v->height = scroll_rect->height;	return retval;}static voidzoom_region_scroll_fast (ZoomRegion *zoom_region, int dx, int dy,			 GdkRectangle *scroll_rect,			 GdkRectangle *expose_rect_h,			 GdkRectangle *expose_rect_v)

⌨️ 快捷键说明

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