📄 gdkdrawable-fb2.c
字号:
#include <config.h>#include "gdkprivate-fb.h"#include "mi.h"#include <string.h>#include <gdkregion-generic.h>#include <pango/pangoft2.h>#include <freetype/ftglyph.h>#ifndef g_alloca#define g_alloca alloca#endifvoid gdk_fb_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height);static void gdk_fb_draw_arc (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height, gint angle1, gint angle2);static void gdk_fb_draw_polygon (GdkDrawable *drawable, GdkGC *gc, gboolean filled, GdkPoint *points, gint npoints);static void gdk_fb_draw_text (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const gchar *text, gint text_length);static void gdk_fb_draw_text_wc (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const GdkWChar *text, gint text_length);static void gdk_fb_draw_glyphs (GdkDrawable *drawable, GdkGC *gc, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs);void gdk_fb_draw_drawable (GdkDrawable *drawable, GdkGC *gc, GdkPixmap *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_fb_draw_image (GdkDrawable *drawable, GdkGC *gc, GdkImage *image, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_fb_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);static void gdk_fb_draw_segments (GdkDrawable *drawable, GdkGC *gc, GdkSegment *segs, gint nsegs);static void gdk_fb_draw_lines (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);static GdkColormap* gdk_fb_get_colormap (GdkDrawable *drawable);static void gdk_fb_set_colormap (GdkDrawable *drawable, GdkColormap *colormap);static gint gdk_fb_get_depth (GdkDrawable *drawable);static GdkScreen* gdk_fb_get_screen (GdkDrawable *drawable);static GdkVisual* gdk_fb_get_visual (GdkDrawable *drawable);static void gdk_fb_drawable_finalize (GObject *object);#ifdef ENABLE_SHADOW_FBstatic void gdk_shadow_fb_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height);static void gdk_shadow_fb_draw_arc (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height, gint angle1, gint angle2);static void gdk_shadow_fb_draw_polygon (GdkDrawable *drawable, GdkGC *gc, gboolean filled, GdkPoint *points, gint npoints);static void gdk_shadow_fb_draw_text (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const gchar *text, gint text_length);static void gdk_shadow_fb_draw_text_wc (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const GdkWChar *text, gint text_length);static void gdk_shadow_fb_draw_glyphs (GdkDrawable *drawable, GdkGC *gc, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs);static void gdk_shadow_fb_draw_drawable (GdkDrawable *drawable, GdkGC *gc, GdkPixmap *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_shadow_fb_draw_image (GdkDrawable *drawable, GdkGC *gc, GdkImage *image, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_shadow_fb_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);static void gdk_shadow_fb_draw_segments (GdkDrawable *drawable, GdkGC *gc, GdkSegment *segs, gint nsegs);static void gdk_shadow_fb_draw_lines (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);#endifstatic gpointer parent_class = NULL;static voidgdk_fb_get_size (GdkDrawable *d, gint *width, gint *height){ if (width) *width = GDK_DRAWABLE_FBDATA (d)->width; if (height) *height = GDK_DRAWABLE_FBDATA (d)->height;}static voidgdk_drawable_impl_fb_class_init (GdkDrawableFBClass *klass){ GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_fb_drawable_finalize; drawable_class->create_gc = _gdk_fb_gc_new; #ifdef ENABLE_SHADOW_FB drawable_class->draw_rectangle = gdk_shadow_fb_draw_rectangle; drawable_class->draw_arc = gdk_shadow_fb_draw_arc; drawable_class->draw_polygon = gdk_shadow_fb_draw_polygon; drawable_class->draw_text = gdk_shadow_fb_draw_text; drawable_class->draw_text_wc = gdk_shadow_fb_draw_text_wc; drawable_class->draw_drawable = gdk_shadow_fb_draw_drawable; drawable_class->draw_points = gdk_shadow_fb_draw_points; drawable_class->draw_segments = gdk_shadow_fb_draw_segments; drawable_class->draw_lines = gdk_shadow_fb_draw_lines; drawable_class->draw_glyphs = gdk_shadow_fb_draw_glyphs; drawable_class->draw_image = gdk_shadow_fb_draw_image;#else drawable_class->draw_rectangle = gdk_fb_draw_rectangle; drawable_class->draw_arc = gdk_fb_draw_arc; drawable_class->draw_polygon = gdk_fb_draw_polygon; drawable_class->draw_text = gdk_fb_draw_text; drawable_class->draw_text_wc = gdk_fb_draw_text_wc; drawable_class->draw_drawable = gdk_fb_draw_drawable; drawable_class->draw_points = gdk_fb_draw_points; drawable_class->draw_segments = gdk_fb_draw_segments; drawable_class->draw_lines = gdk_fb_draw_lines; drawable_class->draw_glyphs = gdk_fb_draw_glyphs; drawable_class->draw_image = gdk_fb_draw_image;#endif drawable_class->set_colormap = gdk_fb_set_colormap; drawable_class->get_colormap = gdk_fb_get_colormap; drawable_class->get_size = gdk_fb_get_size; drawable_class->get_depth = gdk_fb_get_depth; drawable_class->get_screen = gdk_fb_get_screen; drawable_class->get_visual = gdk_fb_get_visual; drawable_class->_copy_to_image = _gdk_fb_copy_to_image;}static voidgdk_fb_drawable_finalize (GObject *object){ gdk_drawable_set_colormap (GDK_DRAWABLE (object), NULL); G_OBJECT_CLASS (parent_class)->finalize (object);}GTypegdk_drawable_impl_fb_get_type (void){ static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (GdkDrawableFBClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gdk_drawable_impl_fb_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GdkDrawableFBData), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (GDK_TYPE_DRAWABLE, "GdkDrawableFB", &object_info, 0); } return object_type;}/***************************************************** * FB specific implementations of generic functions * *****************************************************/static GdkColormap*gdk_fb_get_colormap (GdkDrawable *drawable){ GdkColormap *retval = GDK_DRAWABLE_FBDATA (drawable)->colormap; if (!retval) retval = gdk_colormap_get_system (); return retval;}static voidgdk_fb_set_colormap (GdkDrawable *drawable, GdkColormap *colormap){ GdkDrawableFBData *private; private = GDK_DRAWABLE_FBDATA (drawable); if (private->colormap == colormap) return; if (private->colormap) gdk_colormap_unref (private->colormap); private->colormap = colormap; if (private->colormap) gdk_colormap_ref (private->colormap);}/* Calculates the real clipping region for a drawable, taking into account * other windows, gc clip region and gc clip mask. */GdkRegion *gdk_fb_clip_region (GdkDrawable *drawable, GdkGC *gc, gboolean do_clipping, gboolean do_children, gboolean full_shapes){ GdkRectangle draw_rect; GdkRegion *real_clip_region, *tmpreg, *shape; gboolean skipit = FALSE; GdkDrawableFBData *private; GdkWindowObject *parent; GDK_CHECK_IMPL (drawable); private = GDK_DRAWABLE_FBDATA (drawable); g_assert(!GDK_IS_WINDOW (private->wrapper) || !GDK_WINDOW_P (private->wrapper)->input_only); draw_rect.x = private->llim_x; draw_rect.y = private->llim_y; if (!GDK_IS_WINDOW (private) || GDK_WINDOW_IS_MAPPED (private->wrapper)) { draw_rect.width = private->lim_x - draw_rect.x; draw_rect.height = private->lim_y - draw_rect.y; } else { draw_rect.width = draw_rect.height = 0; skipit = TRUE; } real_clip_region = gdk_region_rectangle (&draw_rect); if (skipit) return real_clip_region; if (GDK_IS_WINDOW (private->wrapper)) { parent = GDK_WINDOW_P (private->wrapper); while (parent != (GdkWindowObject *)_gdk_parent_root) { if (full_shapes) { shape = gdk_fb_window_get_abs_shape (GDK_DRAWABLE (parent)); if (shape) { gdk_region_intersect (real_clip_region, shape); gdk_region_destroy (shape); } } else { gint dx, dy; shape = gdk_fb_window_peek_shape (GDK_DRAWABLE (parent), &dx, &dy); if (shape) { GdkRectangle rect; GdkRegion *reg; gdk_region_get_clipbox (shape, &rect); rect.x += GDK_DRAWABLE_IMPL_FBDATA (parent)->abs_x + dx; rect.y += GDK_DRAWABLE_IMPL_FBDATA (parent)->abs_y + dy; reg = gdk_region_rectangle(&rect); gdk_region_intersect (real_clip_region, reg); gdk_region_destroy (reg); } } parent = parent->parent; } } if (gc && GDK_GC_FBDATA(gc)->values.subwindow_mode == GDK_INCLUDE_INFERIORS) do_children = FALSE; if (do_clipping && GDK_IS_WINDOW (private->wrapper) && GDK_WINDOW_IS_MAPPED (private->wrapper) && !GDK_WINDOW_P (private->wrapper)->input_only) { GdkWindow *parentwin, *lastwin; GdkDrawableFBData *impl_private; lastwin = private->wrapper; if (do_children) parentwin = lastwin; else parentwin = (GdkWindow *)GDK_WINDOW_P (lastwin)->parent; /* Remove the areas of all overlapping windows above parentwin in the hiearachy */ for (; parentwin; lastwin = parentwin, parentwin = (GdkWindow *)GDK_WINDOW_P (parentwin)->parent) { GList *cur; for (cur = GDK_WINDOW_P (parentwin)->children; cur && cur->data != lastwin; cur = cur->next) { if (!GDK_WINDOW_IS_MAPPED (cur->data) || GDK_WINDOW_P (cur->data)->input_only) continue; impl_private = GDK_DRAWABLE_IMPL_FBDATA(cur->data); /* This shortcut is really necessary for performance when there are a lot of windows */ if (impl_private->llim_x >= real_clip_region->extents.x2 || impl_private->lim_x <= real_clip_region->extents.x1 || impl_private->llim_y >= real_clip_region->extents.y2 || impl_private->lim_y <= real_clip_region->extents.y1) continue; draw_rect.x = impl_private->llim_x; draw_rect.y = impl_private->llim_y; draw_rect.width = impl_private->lim_x - draw_rect.x; draw_rect.height = impl_private->lim_y - draw_rect.y; tmpreg = gdk_region_rectangle (&draw_rect); shape = gdk_fb_window_get_abs_shape (impl_private->wrapper); if (shape) { gdk_region_intersect (tmpreg, shape); gdk_region_destroy (shape); } gdk_region_subtract (real_clip_region, tmpreg); gdk_region_destroy (tmpreg); } } } if (gc) { if (GDK_GC_FBDATA (gc)->clip_region) { tmpreg = gdk_region_copy (GDK_GC_FBDATA (gc)->clip_region); gdk_region_offset (tmpreg, private->abs_x + GDK_GC_P (gc)->clip_x_origin, private->abs_y + GDK_GC_P (gc)->clip_y_origin); gdk_region_intersect (real_clip_region, tmpreg); gdk_region_destroy (tmpreg); } if (GDK_GC_FBDATA (gc)->values.clip_mask) { GdkDrawable *cmask = GDK_GC_FBDATA (gc)->values.clip_mask; GdkDrawableFBData *cmask_private; cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask); g_assert (cmask_private->depth == 1); g_assert (cmask_private->abs_x == 0 && cmask_private->abs_y == 0); draw_rect.x = private->abs_x + cmask_private->llim_x + GDK_GC_FBDATA (gc)->values.clip_x_origin; draw_rect.y = private->abs_y + cmask_private->llim_y + GDK_GC_FBDATA (gc)->values.clip_y_origin; draw_rect.width = cmask_private->width; draw_rect.height = cmask_private->height; tmpreg = gdk_region_rectangle (&draw_rect); gdk_region_intersect (real_clip_region, tmpreg); gdk_region_destroy (tmpreg); /* if (!real_clip_region->numRects) g_warning ("Empty clip region"); */ } } return real_clip_region;}struct GdkSpanHelper{ GdkDrawable *drawable; GdkGC *gc; GdkColor color;};static voidgdk_fb_fill_span_helper(GdkSpan *span, gpointer data){ struct GdkSpanHelper *info = (struct GdkSpanHelper *)data; GdkGC * gc = info->gc; (GDK_GC_FBDATA (gc)->fill_span) (info->drawable, gc, span, &info->color);}voidgdk_fb_fill_spans (GdkDrawable *real_drawable, GdkGC *gc, GdkSpan *spans, int nspans, gboolean sorted){ int i; struct GdkSpanHelper info; GdkRegion *real_clip_region; gboolean handle_cursor = FALSE; GdkDrawable *drawable; GdkDrawableFBData *private; drawable = real_drawable; private = GDK_DRAWABLE_FBDATA (drawable); g_assert (gc); if (GDK_IS_WINDOW (private->wrapper) && !GDK_WINDOW_IS_MAPPED (private->wrapper)) return; if (GDK_IS_WINDOW (private->wrapper) && GDK_WINDOW_P (private->wrapper)->input_only) g_error ("Drawing on the evil input-only!"); info.drawable = drawable; info.gc = gc; if (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND) info.color = GDK_GC_FBDATA (gc)->values.foreground; else if (GDK_IS_WINDOW (private->wrapper)) info.color = GDK_WINDOW_P (private->wrapper)->bg_color; else gdk_color_black (private->colormap, &info.color); real_clip_region = gdk_fb_clip_region (drawable, gc, TRUE, GDK_GC_FBDATA (gc)->values.function != GDK_INVERT, TRUE); if (private->mem == GDK_DRAWABLE_IMPL_FBDATA (_gdk_parent_root)->mem && gdk_fb_cursor_region_need_hide (real_clip_region)) { handle_cursor = TRUE; gdk_fb_cursor_hide (); } for (i = 0; i < nspans; i++) { GdkSpan *cur; cur = &spans[i]; cur->x += private->abs_x; cur->y += private->abs_y; if ( (cur->y < private->llim_y) || (cur->y >= private->lim_y)) cur->width = 0; if (cur->x < private->llim_x)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -