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