void Paint (WidgetType widgetType, Rectangle bounds, IDeviceContext dc, TransparencyType transparencyType, Color background, DeviceContextType deviceContextType, Rectangle clippingArea, Painter painter, Rectangle excludedArea) { Rectangle painted_area = Rectangle.Intersect (bounds, clippingArea); if (painted_area.Width == 0 || painted_area.Height == 0) return; painted_area.Offset (-bounds.X, -bounds.Y); excludedArea.Offset (-bounds.X, -bounds.Y); GdkDrawablePointer drawable = gdk_pixmap_new (IntPtr.Zero, bounds.Width, bounds.Height, 24); painter.AttachStyle (widgetType, drawable, this); GdkPixbufPointer pixbuf; IntPtr pixel_data; int rowstride; GdkGCPointer gc = gdk_gc_new (drawable); GdkColor color = new GdkColor (background); gdk_gc_set_rgb_fg_color (gc, ref color); Paint (drawable, gc, bounds, widgetType, out pixbuf, out pixel_data, out rowstride, painted_area, painter, excludedArea); GdkPixbufPointer white_pixbuf = IntPtr.Zero; IntPtr white_pixel_data = IntPtr.Zero; int white_rowstride = 0; GdkColor white_color = new GdkColor(); if (transparencyType == TransparencyType.Alpha) { white_color.red = guint16.MaxValue; white_color.green = guint16.MaxValue; white_color.blue = guint16.MaxValue; gdk_gc_set_rgb_fg_color (gc, ref white_color); Paint (drawable, gc, bounds, widgetType, out white_pixbuf, out white_pixel_data, out white_rowstride, painted_area, painter, excludedArea); } g_object_unref (gc); unsafe { byte* row = (byte*)pixel_data; byte* pixel; byte* white_row = (byte*)white_pixel_data; byte* white_pixel; for (int row_index = 0; row_index < painted_area.Height; row_index++) { pixel = row; white_pixel = white_row; for (int pixel_index = 0; pixel_index < painted_area.Width; pixel_index++) { const int GdkRedOffset = 0; const int GdkGreenOffset = 1; const int GdkBlueOffset = 2; const int BitmapAlphaOffset = 3; const int BitmapRedOffset = 2; const int BitmapBlueOffset = 0; switch (transparencyType) { case TransparencyType.Alpha: pixel [BitmapAlphaOffset] = (byte)(pixel [GdkRedOffset] - white_pixel [GdkRedOffset] + byte.MaxValue); break; case TransparencyType.Color: if ( pixel [GdkRedOffset] == background.R && pixel [GdkGreenOffset] == background.G && pixel [GdkBlueOffset] == background.B) { const int AlphaFullyTransparent = 0; pixel [BitmapAlphaOffset] = AlphaFullyTransparent; } break; } byte temporary = pixel [GdkRedOffset]; pixel [BitmapBlueOffset] = pixel [GdkBlueOffset]; pixel [BitmapRedOffset] = temporary; const int PixelSize = 4; pixel += PixelSize; white_pixel += PixelSize; } row += rowstride; white_row += white_rowstride; } } if (transparencyType == TransparencyType.Alpha) g_object_unref (white_pixbuf); g_object_unref (drawable); Bitmap bitmap = new Bitmap (painted_area.Width, painted_area.Height, rowstride, PixelFormat.Format32bppPArgb, pixel_data); Graphics g; bool graphics_is_from_hdc = false; switch (deviceContextType) { case DeviceContextType.Graphics: g = (Graphics)dc; break; case DeviceContextType.Native: g = Graphics.FromHdc (dc.GetHdc ()); break; default: g = dc as Graphics; if (g == null) { graphics_is_from_hdc = true; g = Graphics.FromHdc (dc.GetHdc ()); } else graphics_is_from_hdc = false; break; } painted_area.Offset (bounds.X, bounds.Y); g.DrawImage (bitmap, painted_area.Location); switch (deviceContextType) { case DeviceContextType.Graphics: break; case DeviceContextType.Native: g.Dispose (); dc.ReleaseHdc (); break; default: if (graphics_is_from_hdc) { g.Dispose (); dc.ReleaseHdc (); } break; } bitmap.Dispose (); g_object_unref (pixbuf); }
static extern void gdk_gc_set_rgb_fg_color (GdkGCPointer gc, ref GdkColor color);
public void UpdateBackgroundColor(string color) { var bgColor = new GdkColor(color); WebKit.SetBackgroundColor(Handle, ref bgColor); }
public static extern void SetBackgroundColor(IntPtr webview, ref GdkColor color);
public GtkWebview(WindowConfiguration config, IContentProvider contentProvider, WebviewBridge bridge) { this.config = config ?? throw new ArgumentNullException(nameof(config)); this.contentProvider = contentProvider ?? throw new ArgumentNullException(nameof(contentProvider)); this.bridge = bridge ?? throw new ArgumentNullException(nameof(bridge)); // need to keep the delegates around or they will get garbage collected scriptDelegate = ScriptCallback; loadFailedDelegate = LoadFailedCallback; loadDelegate = LoadCallback; contextMenuDelegate = ContextMenuCallback; closeDelegate = CloseCallback; titleChangeDelegate = TitleChangeCallback; if (config.EnableScriptInterface) { manager = WebKit.Manager.Create(); GLib.ConnectSignal(manager, "script-message-received::external", scriptDelegate, IntPtr.Zero); using (GLibString name = "external") { WebKit.Manager.RegisterScriptMessageHandler(manager, name); } Handle = WebKit.CreateWithUserContentManager(manager); } else { Handle = WebKit.Create(); } GLib.ConnectSignal(Handle, "load-failed", loadFailedDelegate, IntPtr.Zero); GLib.ConnectSignal(Handle, "load-changed", loadDelegate, IntPtr.Zero); GLib.ConnectSignal(Handle, "context-menu", contextMenuDelegate, IntPtr.Zero); GLib.ConnectSignal(Handle, "close", closeDelegate, IntPtr.Zero); if (config.UseBrowserTitle) { GLib.ConnectSignal(Handle, "notify::title", titleChangeDelegate, IntPtr.Zero); } if (string.IsNullOrWhiteSpace(config.ExternalHost)) { const string scheme = "spidereye"; customHost = UriTools.GetRandomResourceUrl(scheme); IntPtr context = WebKit.Context.Get(Handle); using (GLibString gscheme = scheme) { WebKit.Context.RegisterUriScheme(context, gscheme, UriSchemeCallback, IntPtr.Zero, IntPtr.Zero); } } var bgColor = new GdkColor(config.BackgroundColor); WebKit.SetBackgroundColor(Handle, ref bgColor); if (enableDevTools) { var settings = WebKit.Settings.Get(Handle); WebKit.Settings.SetEnableDeveloperExtras(settings, true); var inspector = WebKit.Inspector.Get(Handle); WebKit.Inspector.Show(inspector); } }