Skip to content

Commit c51a615

Browse files
committed
OffScreen - Add IRenderHandler and DefaultRenderHandler basic implementation
Only supports OnPaint, will expand to support the other methods
1 parent 61033e6 commit c51a615

File tree

4 files changed

+88
-116
lines changed

4 files changed

+88
-116
lines changed

CefSharp.OffScreen/CefSharp.OffScreen.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
<ItemGroup>
7575
<Compile Include="BitmapBuffer.cs" />
7676
<Compile Include="ChromiumWebBrowser.cs" />
77+
<Compile Include="DefaultRenderHandler.cs" />
7778
<Compile Include="IRenderHandler.cs" />
7879
<Compile Include="OnPaintEventArgs.cs" />
7980
<Compile Include="PopupBlending.cs" />

CefSharp.OffScreen/ChromiumWebBrowser.cs

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,6 @@ public class ChromiumWebBrowser : IRenderWebBrowser
2727
/// </summary>
2828
private ManagedCefBrowserAdapter managedCefBrowserAdapter;
2929

30-
/// <summary>
31-
/// Contains the last bitmap buffer. Direct access
32-
/// to the underlying buffer - there is no locking when trying
33-
/// to access directly, use <see cref="BitmapBuffer.BitmapLock" /> where appropriate.
34-
/// </summary>
35-
/// <value>The bitmap.</value>
36-
public BitmapBuffer BitmapBuffer { get; protected set; }
37-
38-
/// <summary>
39-
/// Need a lock because the caller may be asking for the bitmap
40-
/// while Chromium async rendering has returned on another thread.
41-
/// </summary>
42-
public readonly object BitmapLock = new object();
43-
4430
/// <summary>
4531
/// Size of the Chromium viewport.
4632
/// This must be set to something other than 0x0 otherwise Chromium will not render,
@@ -168,6 +154,11 @@ public class ChromiumWebBrowser : IRenderWebBrowser
168154
/// <value>The request handler.</value>
169155
public IRequestHandler RequestHandler { get; set; }
170156
/// <summary>
157+
/// Implement <see cref="IRenderHandler" /> and assign to handle events related to browser rendering.
158+
/// </summary>
159+
/// <value>The render handler.</value>
160+
public IRenderHandler RenderHandler { get; set; }
161+
/// <summary>
171162
/// Implement <see cref="IDragHandler" /> and assign to handle events related to dragging.
172163
/// </summary>
173164
/// <value>The drag handler.</value>
@@ -294,11 +285,6 @@ public class ChromiumWebBrowser : IRenderWebBrowser
294285
/// </summary>
295286
private Size popupSize;
296287

297-
/// <summary>
298-
/// The popup Bitmap.
299-
/// </summary>
300-
public BitmapBuffer PopupBuffer { get; protected set; }
301-
302288
/// <summary>
303289
/// Create a new OffScreen Chromium Browser
304290
/// </summary>
@@ -329,10 +315,10 @@ public ChromiumWebBrowser(string address = "", BrowserSettings browserSettings =
329315
CreateBrowser(IntPtr.Zero);
330316
}
331317

332-
BitmapBuffer = new BitmapBuffer(BitmapLock);
333-
PopupBuffer = new BitmapBuffer(BitmapLock);
334318
popupPosition = new Point();
335319
popupSize = new Size();
320+
321+
RenderHandler = new DefaultRenderHandler(this);
336322
}
337323

338324
/// <summary>
@@ -468,24 +454,36 @@ public Size Size
468454
/// <returns>Bitmap.</returns>
469455
public Bitmap ScreenshotOrNull(PopupBlending blend = PopupBlending.Main)
470456
{
471-
lock (BitmapLock)
457+
if(RenderHandler == null)
458+
{
459+
throw new NullReferenceException("RenderHandler cannot be null. Use DefaultRenderHandler unless implementing your own");
460+
}
461+
462+
var renderHandler = RenderHandler as DefaultRenderHandler;
463+
464+
if(renderHandler == null)
465+
{
466+
throw new Exception("ScreenshotOrNull and ScreenshotAsync can only be used in combination with the DefaultRenderHandler");
467+
}
468+
469+
lock (renderHandler.BitmapLock)
472470
{
473471
if (blend == PopupBlending.Main)
474472
{
475-
return BitmapBuffer.CreateBitmap();
473+
return renderHandler.BitmapBuffer.CreateBitmap();
476474
}
477475

478476
if (blend == PopupBlending.Popup)
479477
{
480-
return PopupOpen ? PopupBuffer.CreateBitmap() : null;
478+
return PopupOpen ? renderHandler.PopupBuffer.CreateBitmap() : null;
481479
}
482480

483481

484-
var bitmap = BitmapBuffer.CreateBitmap();
482+
var bitmap = renderHandler.BitmapBuffer.CreateBitmap();
485483

486484
if (PopupOpen && bitmap != null)
487485
{
488-
var popup = PopupBuffer.CreateBitmap();
486+
var popup = renderHandler.PopupBuffer.CreateBitmap();
489487
if (popup == null)
490488
{
491489
return bitmap;
@@ -761,9 +759,7 @@ protected virtual void OnPaint(PaintElementType type, Rect dirtyRect, IntPtr buf
761759
{
762760
var isPopup = type == PaintElementType.Popup;
763761

764-
var bitmapBuffer = isPopup ? PopupBuffer : BitmapBuffer;
765-
766-
bitmapBuffer.UpdateBuffer(width, height, buffer, dirtyRect);
762+
RenderHandler?.OnPaint(isPopup, dirtyRect, buffer, width, height);
767763
}
768764

769765
/// <summary>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4+
5+
using System;
6+
using CefSharp.Structs;
7+
8+
namespace CefSharp.OffScreen
9+
{
10+
public class DefaultRenderHandler : IRenderHandler
11+
{
12+
private ChromiumWebBrowser browser;
13+
14+
/// <summary>
15+
/// Contains the last bitmap buffer. Direct access
16+
/// to the underlying buffer - there is no locking when trying
17+
/// to access directly, use <see cref="BitmapBuffer.BitmapLock" /> where appropriate.
18+
/// </summary>
19+
/// <value>The bitmap.</value>
20+
public BitmapBuffer BitmapBuffer { get; private set; }
21+
22+
/// <summary>
23+
/// The popup Bitmap.
24+
/// </summary>
25+
public BitmapBuffer PopupBuffer { get; private set; }
26+
27+
/// <summary>
28+
/// Need a lock because the caller may be asking for the bitmap
29+
/// while Chromium async rendering has returned on another thread.
30+
/// </summary>
31+
public readonly object BitmapLock = new object();
32+
33+
public DefaultRenderHandler(ChromiumWebBrowser browser)
34+
{
35+
this.browser = browser;
36+
37+
BitmapBuffer = new BitmapBuffer(BitmapLock);
38+
PopupBuffer = new BitmapBuffer(BitmapLock);
39+
40+
}
41+
42+
public void Dispose()
43+
{
44+
browser = null;
45+
}
46+
47+
public virtual void OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height)
48+
{
49+
var bitmapBuffer = isPopup ? PopupBuffer : BitmapBuffer;
50+
51+
bitmapBuffer.UpdateBuffer(width, height, buffer, dirtyRect);
52+
}
53+
}
54+
}

CefSharp.OffScreen/IRenderHandler.cs

Lines changed: 8 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,96 +3,17 @@
33
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
44

55
using System;
6-
using CefSharp.Enums;
76
using CefSharp.Structs;
87

98
namespace CefSharp.OffScreen
109
{
11-
public interface IRenderHandler
10+
/// <summary>
11+
/// Implement this interface to handle Offscreen Rendering (OSR).
12+
/// NOTE: Currently only OnPaint is implemented, at some point expand the API to include all
13+
/// of CefRenderHandler methods http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRenderHandler.html
14+
/// </summary>
15+
public interface IRenderHandler : IDisposable
1216
{
13-
/// <summary>
14-
/// Called to allow the client to return a ScreenInfo object with appropriate values.
15-
/// If null is returned then the rectangle from GetViewRect will be used.
16-
/// If the rectangle is still empty or invalid popups may not be drawn correctly.
17-
/// </summary>
18-
/// <returns>Return null if no screenInfo structure is provided.</returns>
19-
ScreenInfo? GetScreenInfo();
20-
21-
/// <summary>
22-
/// Called to retrieve the view rectangle which is relative to screen coordinates.
23-
/// </summary>
24-
/// <returns>Return a ViewRect strict containing the rectangle or null. If the rectangle is
25-
/// still empty or invalid popups may not be drawn correctly. </returns>
26-
ViewRect? GetViewRect();
27-
28-
/// <summary>
29-
/// Called to retrieve the translation from view coordinates to actual screen coordinates.
30-
/// </summary>
31-
/// <param name="viewX">x</param>
32-
/// <param name="viewY">y</param>
33-
/// <param name="screenX">screen x</param>
34-
/// <param name="screenY">screen y</param>
35-
/// <returns>Return true if the screen coordinates were provided.</returns>
36-
bool GetScreenPoint(int viewX, int viewY, out int screenX, out int screenY);
37-
38-
/// <summary>
39-
/// Called when an element should be painted. Pixel values passed to this method are scaled relative to view coordinates based on the
40-
/// value of <see cref="ScreenInfo.ScaleFactor"/> returned from <see cref="GetScreenInfo"/>.
41-
/// Called on the CEF UI Thread
42-
/// </summary>
43-
/// <param name="type">indicates whether the element is the view or the popup widget.</param>
44-
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
45-
/// <param name="buffer">The bitmap will be will be width * height *4 bytes in size and represents a BGRA image with an upper-left origin</param>
46-
/// <param name="width">width</param>
47-
/// <param name="height">height</param>
48-
void OnPaint(PaintElementType type, Rect dirtyRect, IntPtr buffer, int width, int height);
49-
50-
/// <summary>
51-
/// Called when the browser's cursor has changed. .
52-
/// </summary>
53-
/// <param name="cursor">If type is Custom then customCursorInfo will be populated with the custom cursor information</param>
54-
/// <param name="type">cursor type</param>
55-
/// <param name="customCursorInfo">custom cursor Information</param>
56-
void OnCursorChange(IntPtr cursor, CursorType type, CursorInfo customCursorInfo);
57-
58-
/// <summary>
59-
/// Called when the user starts dragging content in the web view. Contextual information about the dragged content is
60-
/// supplied by dragData. (|x|, |y|) is the drag start location in screen coordinates. OS APIs that run a system message
61-
/// loop may be used within the StartDragging call. Return false to abort the drag operation. Don't call any of
62-
/// CefBrowserHost::DragSource*Ended* methods after returning false. Return true to handle the drag operation.
63-
/// Call IBrowserHost::DragSourceEndedAt and DragSourceSystemDragEnded either synchronously or asynchronously to inform
64-
/// the web view that the drag operation has ended.
65-
/// </summary>
66-
/// <param name="dragData">drag data</param>
67-
/// <param name="mask">operation mask</param>
68-
/// <param name="x">x coordinate</param>
69-
/// <param name="y">y coordinate</param>
70-
/// <returns>Return false to abort the drag operation.</returns>
71-
bool StartDragging(IDragData dragData, DragOperationsMask mask, int x, int y);
72-
73-
/// <summary>
74-
/// Called when the web view wants to update the mouse cursor during a drag & drop operation.
75-
/// </summary>
76-
/// <param name="operation">describes the allowed operation (none, move, copy, link). </param>
77-
void UpdateDragCursor(DragOperationsMask operation);
78-
79-
/// <summary>
80-
/// Called when the browser wants to show or hide the popup widget.
81-
/// </summary>
82-
/// <param name="show">The popup should be shown if show is true and hidden if show is false.</param>
83-
void OnPopupShow(bool show);
84-
85-
/// <summary>
86-
/// Called when the browser wants to move or resize the popup widget.
87-
/// </summary>
88-
/// <param name="rect">|rect| contains the new location and size in view coordinates. </param>
89-
void OnPopupSize(Rect rect);
90-
91-
/// <summary>
92-
/// Called when the IME composition range has changed.
93-
/// </summary>
94-
/// <param name="selectedRange">is the range of characters that have been selected</param>
95-
/// <param name="characterBounds">is the bounds of each character in view coordinates.</param>
96-
void OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds);
17+
void OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height);
9718
}
98-
}
19+
}

0 commit comments

Comments
 (0)