📄 zoom-region.c
字号:
{ 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 + -