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