📄 gdkdrawable-win32.c
字号:
}static voiddraw_glyphs (GdkGCWin32 *gcwin32, HDC hdc, gint x_offset, gint y_offset, va_list args){ PangoFont *font; gint x; gint y; PangoGlyphString *glyphs; font = va_arg (args, PangoFont *); x = va_arg (args, gint); y = va_arg (args, gint); glyphs = va_arg (args, PangoGlyphString *); x -= x_offset; y -= y_offset; pango_win32_render (hdc, font, glyphs, x, y);}static voiddraw_glyphs_transformed (GdkGCWin32 *gcwin32, HDC hdc, gint x_offset, gint y_offset, va_list args){ PangoFont *font; gint x; gint y; PangoGlyphString *glyphs; PangoMatrix *matrix; matrix = va_arg(args, PangoMatrix *); font = va_arg (args, PangoFont *); x = va_arg (args, gint); y = va_arg (args, gint); glyphs = va_arg (args, PangoGlyphString *); x -= x_offset; y -= y_offset; pango_win32_render_transformed (hdc, matrix, font, glyphs, x, y);}static voidgdk_win32_draw_glyphs (GdkDrawable *drawable, GdkGC *gc, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs){ GdkRectangle bounds; GdkRegion *region; PangoRectangle ink_rect; pango_glyph_string_extents (glyphs, font, &ink_rect, NULL); bounds.x = x + PANGO_PIXELS (ink_rect.x) - 1; bounds.y = y + PANGO_PIXELS (ink_rect.y) - 1; bounds.width = PANGO_PIXELS (ink_rect.width) + 2; bounds.height = PANGO_PIXELS (ink_rect.height) + 2; region = gdk_region_rectangle (&bounds); generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT, draw_glyphs, region, font, x, y, glyphs); gdk_region_destroy (region);}static void gdk_win32_draw_glyphs_transformed (GdkDrawable *drawable, GdkGC *gc, PangoMatrix *matrix, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs){ GdkRectangle bounds; GdkRegion *region; PangoRectangle ink_rect; pango_glyph_string_extents (glyphs, font, &ink_rect, NULL); bounds.x = x + PANGO_PIXELS (ink_rect.x) - 1; bounds.y = y + PANGO_PIXELS (ink_rect.y) - 1; bounds.width = PANGO_PIXELS (ink_rect.width) + 2; bounds.height = PANGO_PIXELS (ink_rect.height) + 2; region = gdk_region_rectangle (&bounds); if (matrix) { /* transform region */ bounds.x = bounds.x * matrix->xx + bounds.y * matrix->xy + matrix->x0; bounds.y = bounds.x * matrix->yx + bounds.y * matrix->yy + matrix->x0; bounds.width = bounds.width * matrix->xx + bounds.height * matrix->xy; bounds.height = bounds.height * matrix->yx + bounds.width * matrix->xy; generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT, draw_glyphs_transformed, region, matrix, font, x, y, glyphs); } else { generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT, draw_glyphs, region, font, x/PANGO_SCALE, y/PANGO_SCALE, glyphs); } gdk_region_destroy (region);}static voidblit_from_pixmap (gboolean use_fg_bg, GdkDrawableImplWin32 *dest, HDC hdc, GdkPixmapImplWin32 *src, GdkGCWin32 *gcwin32, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height){ HDC srcdc; HBITMAP holdbitmap; RGBQUAD oldtable[256], newtable[256]; COLORREF bg, fg; gint newtable_size = 0, oldtable_size = 0; gboolean ok = TRUE; GDK_NOTE (MISC, g_print ("blit_from_pixmap\n")); if (!(srcdc = CreateCompatibleDC (NULL))) { WIN32_GDI_FAILED ("CreateCompatibleDC"); return; } if (!(holdbitmap = SelectObject (srcdc, ((GdkDrawableImplWin32 *) src)->handle))) WIN32_GDI_FAILED ("SelectObject"); else { if (GDK_PIXMAP_OBJECT (src->parent_instance.wrapper)->depth <= 8) { /* Blitting from a 1, 4 or 8-bit pixmap */ if ((oldtable_size = GetDIBColorTable (srcdc, 0, 256, oldtable)) == 0) WIN32_GDI_FAILED ("GetDIBColorTable"); else if (GDK_PIXMAP_OBJECT (src->parent_instance.wrapper)->depth == 1) { /* Blitting from an 1-bit pixmap */ gint bgix, fgix; if (use_fg_bg) { bgix = gcwin32->background; fgix = gcwin32->foreground; } else { bgix = 0; fgix = 1; } if (GDK_IS_PIXMAP_IMPL_WIN32 (dest) && GDK_PIXMAP_OBJECT (dest->wrapper)->depth <= 8) { /* Destination is also pixmap, get fg and bg from * its palette. Either use the foreground and * background pixel values in the GC (only in the * case of gdk_image_put(), cf. XPutImage()), or 0 * and 1 to index the palette. */ if (!GDI_CALL (GetDIBColorTable, (hdc, bgix, 1, newtable)) || !GDI_CALL (GetDIBColorTable, (hdc, fgix, 1, newtable+1))) ok = FALSE; } else { /* Destination is a window, get fg and bg from its * colormap */ bg = _gdk_win32_colormap_color (dest->colormap, bgix); fg = _gdk_win32_colormap_color (dest->colormap, fgix); newtable[0].rgbBlue = GetBValue (bg); newtable[0].rgbGreen = GetGValue (bg); newtable[0].rgbRed = GetRValue (bg); newtable[0].rgbReserved = 0; newtable[1].rgbBlue = GetBValue (fg); newtable[1].rgbGreen = GetGValue (fg); newtable[1].rgbRed = GetRValue (fg); newtable[1].rgbReserved = 0; } if (ok) GDK_NOTE (MISC, g_print ("bg: %02x %02x %02x " "fg: %02x %02x %02x\n", newtable[0].rgbRed, newtable[0].rgbGreen, newtable[0].rgbBlue, newtable[1].rgbRed, newtable[1].rgbGreen, newtable[1].rgbBlue)); newtable_size = 2; } else if (GDK_IS_PIXMAP_IMPL_WIN32 (dest)) { /* Destination is pixmap, get its color table */ if ((newtable_size = GetDIBColorTable (hdc, 0, 256, newtable)) == 0) WIN32_GDI_FAILED ("GetDIBColorTable"), ok = FALSE; } /* If blitting between pixmaps, set source's color table */ if (ok && newtable_size > 0) { GDK_NOTE (MISC_OR_COLORMAP, g_print ("blit_from_pixmap: set color table" " hdc=%p count=%d\n", srcdc, newtable_size)); if (!GDI_CALL (SetDIBColorTable, (srcdc, 0, newtable_size, newtable))) ok = FALSE; } } if (ok) GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height, srcdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2))); /* Restore source's color table if necessary */ if (ok && newtable_size > 0 && oldtable_size > 0) { GDK_NOTE (MISC_OR_COLORMAP, g_print ("blit_from_pixmap: reset color table" " hdc=%p count=%d\n", srcdc, oldtable_size)); GDI_CALL (SetDIBColorTable, (srcdc, 0, oldtable_size, oldtable)); } GDI_CALL (SelectObject, (srcdc, holdbitmap)); } GDI_CALL (DeleteDC, (srcdc));}static voidblit_inside_drawable (HDC hdc, GdkGCWin32 *gcwin32, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height){ GDK_NOTE (MISC, g_print ("blit_inside_drawable\n")); GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height, hdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));}static voidblit_from_window (HDC hdc, GdkGCWin32 *gcwin32, GdkDrawableImplWin32 *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height){ HDC srcdc; HPALETTE holdpal = NULL; GdkColormap *cmap = gdk_colormap_get_system (); GDK_NOTE (MISC, g_print ("blit_from_window\n")); if ((srcdc = GetDC (src->handle)) == NULL) { WIN32_GDI_FAILED ("GetDC"); return; } if (cmap->visual->type == GDK_VISUAL_PSEUDO_COLOR || cmap->visual->type == GDK_VISUAL_STATIC_COLOR) { gint k; if (!(holdpal = SelectPalette (srcdc, GDK_WIN32_COLORMAP_DATA (cmap)->hpal, FALSE))) WIN32_GDI_FAILED ("SelectPalette"); else if ((k = RealizePalette (srcdc)) == GDI_ERROR) WIN32_GDI_FAILED ("RealizePalette"); else if (k > 0) GDK_NOTE (MISC_OR_COLORMAP, g_print ("blit_from_window: realized %d\n", k)); } GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height, srcdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2))); if (holdpal != NULL) GDI_CALL (SelectPalette, (srcdc, holdpal, FALSE)); GDI_CALL (ReleaseDC, (src->handle, srcdc));}void_gdk_win32_blit (gboolean use_fg_bg, GdkDrawableImplWin32 *draw_impl, GdkGC *gc, GdkDrawable *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height){ HDC hdc; HRGN src_rgn, draw_rgn, outside_rgn; RECT r; GdkDrawableImplWin32 *src_impl = NULL; gint src_width, src_height; GDK_NOTE (MISC, g_print ("_gdk_win32_blit: src:%s %dx%d@+%d+%d\n" " dst:%s @+%d+%d use_fg_bg=%d\n", _gdk_win32_drawable_description (src), width, height, xsrc, ysrc, _gdk_win32_drawable_description (&draw_impl->parent_instance), xdest, ydest, use_fg_bg)); /* If blitting from the root window, take the multi-monitor offset * into account. */ if (src == ((GdkWindowObject *)_gdk_parent_root)->impl) { GDK_NOTE (MISC, g_print ("... offsetting src coords\n")); xsrc -= _gdk_offset_x; ysrc -= _gdk_offset_y; } if (GDK_IS_DRAWABLE_IMPL_WIN32 (src)) src_impl = (GdkDrawableImplWin32 *) src; else if (GDK_IS_WINDOW (src)) src_impl = (GdkDrawableImplWin32 *) GDK_WINDOW_OBJECT (src)->impl; else if (GDK_IS_PIXMAP (src)) src_impl = (GdkDrawableImplWin32 *) GDK_PIXMAP_OBJECT (src)->impl; else g_assert_not_reached (); hdc = gdk_win32_hdc_get (&draw_impl->parent_instance, gc, GDK_GC_FOREGROUND); gdk_drawable_get_size (src, &src_width, &src_height); if ((src_rgn = CreateRectRgn (0, 0, src_width + 1, src_height + 1)) == NULL) WIN32_GDI_FAILED ("CreateRectRgn"); else if ((draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1)) == NULL) WIN32_GDI_FAILED ("CreateRectRgn"); else { if (GDK_IS_WINDOW_IMPL_WIN32 (draw_impl)) { int comb; /* If we are drawing on a window, calculate the region that is * outside the source pixmap, and invalidate that, causing it to * be cleared. Not completely sure whether this is always needed. XXX */ SetRectEmpty (&r); outside_rgn = CreateRectRgnIndirect (&r); if ((comb = CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF)) == ERROR) WIN32_GDI_FAILED ("CombineRgn"); else if (comb != NULLREGION) { OffsetRgn (outside_rgn, xdest, ydest); GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r), g_print ("...calling InvalidateRgn, " "bbox: %ldx%ld@+%ld+%ld\n", r.right - r.left - 1, r.bottom - r.top - 1, r.left, r.top))); InvalidateRgn (draw_impl->handle, outside_rgn, TRUE); } GDI_CALL (DeleteObject, (outside_rgn)); }#if 1 /* Don't know if this is necessary XXX */ if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION) g_warning ("gdk_win32_blit: CombineRgn returned a COMPLEXREGION"); GetRgnBox (draw_rgn, &r); if (r.left != xsrc || r.top != ysrc || r.right != xsrc + width + 1 || r.bottom != ysrc + height + 1) { xdest += r.left - xsrc; xsrc = r.left; ydest += r.top - ysrc; ysrc = r.top; width = r.right - xsrc - 1; height = r.bottom - ysrc - 1; GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, " "dest: @+%d+%d\n", width, height, xsrc, ysrc, xdest, ydest)); }#endif GDI_CALL (DeleteObject, (src_rgn)); GDI_CALL (DeleteObject, (draw_rgn)); } if (draw_impl->handle == src_impl->handle) blit_inside_drawable (hdc, GDK_GC_WIN32 (gc), xsrc, ysrc, xdest, ydest, width, height); else if (GDK_IS_PIXMAP_IMPL_WIN32 (src_impl)) blit_from_pixmap (use_fg_bg, draw_impl, hdc, (GdkPixmapImplWin32 *) src_impl, GDK_GC_WIN32 (gc), xsrc, ysrc, xdest, ydest, width, height); else blit_from_window (hdc, GDK_GC_WIN32 (gc), src_impl, xsrc, ysrc, xdest, ydest, width, height); gdk_win32_hdc_release (&draw_impl->parent_instance, gc, GDK_GC_FOREGROUND);}static voidgdk_win32_draw_image (GdkDrawable *drawable, GdkGC *gc, GdkImage *image, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height){ g_assert (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable)); _gdk_win32_blit (TRUE, (GdkDrawableImplWin32 *) drawable, gc, (GdkPixmap *) image->windowing_data, xsrc, ysrc, xdest, ydest, width, height);}static gintgdk_win32_get_depth (GdkDrawable *drawable){ /* This is a bit bogus but I'm not sure the other way is better */ return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper);}static GdkScreen*gdk_win32_get_screen (GdkDrawable *drawable){ return gdk_screen_get_default ();} static GdkVisual*gdk_win32_get_visual (GdkDrawable *drawable){ return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper);}HGDIOBJgdk_win32_drawable_get_handle (GdkDrawable *drawable){ return GDK_DRAWABLE_HANDLE (drawable);}gbooleangdk_draw_rectangle_alpha_libgtk_only (GdkDrawable *drawable, gint x, gint y, gint width, gint height, GdkColor *color, guint16 alpha){ return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -