2018-09-10 02:41:13 +02:00
// Copyright © 2018 The CefSharp Authors. All rights reserved.
2018-04-23 13:02:12 +10:00
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
2018-09-17 00:46:21 +02:00
using System ;
2018-04-23 14:15:25 +10:00
using CefSharp.Enums ;
2018-04-23 13:02:12 +10:00
using CefSharp.Structs ;
2018-04-23 14:15:25 +10:00
using Point = System . Drawing . Point ;
2020-07-23 07:21:14 +02:00
using Range = CefSharp . Structs . Range ;
2018-04-23 14:15:25 +10:00
using Size = System . Drawing . Size ;
2018-04-23 13:02:12 +10:00
namespace CefSharp.OffScreen
{
2018-12-17 13:50:29 +10:00
/// <summary>
/// Default implementation of <see cref="IRenderHandler"/>, this class handles Offscreen Rendering (OSR).
/// Upstream documentation at http://magpcss.org/ceforum/apidocs3/projects/(default)/CefRenderHandler.html
/// </summary>
2018-08-24 19:13:59 +10:00
public class DefaultRenderHandler : IRenderHandler
{
private ChromiumWebBrowser browser ;
private Size popupSize ;
private Point popupPosition ;
/// <summary>
/// Need a lock because the caller may be asking for the bitmap
/// while Chromium async rendering has returned on another thread.
/// </summary>
public readonly object BitmapLock = new object ( ) ;
/// <summary>
/// Gets or sets a value indicating whether the popup is open.
/// </summary>
/// <value>
/// <c>true</c> if popup is opened; otherwise, <c>false</c>.
/// </value>
public bool PopupOpen { get ; protected set ; }
/// <summary>
/// Contains the last bitmap buffer. Direct access
/// to the underlying buffer - there is no locking when trying
/// to access directly, use <see cref="BitmapBuffer.BitmapLock" /> where appropriate.
/// </summary>
/// <value>The bitmap.</value>
public BitmapBuffer BitmapBuffer { get ; private set ; }
/// <summary>
/// The popup Bitmap.
/// </summary>
public BitmapBuffer PopupBuffer { get ; private set ; }
/// <summary>
/// Gets the size of the popup.
/// </summary>
public Size PopupSize
{
get { return popupSize ; }
}
/// <summary>
/// Gets the popup position.
/// </summary>
public Point PopupPosition
{
get { return popupPosition ; }
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Create a new instance of DefaultRenderHadler
/// </summary>
/// <param name="browser">reference to the ChromiumWebBrowser</param>
2018-08-24 19:13:59 +10:00
public DefaultRenderHandler ( ChromiumWebBrowser browser )
{
this . browser = browser ;
popupPosition = new Point ( ) ;
popupSize = new Size ( ) ;
BitmapBuffer = new BitmapBuffer ( BitmapLock ) ;
PopupBuffer = new BitmapBuffer ( BitmapLock ) ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Dispose of this instance.
/// </summary>
2018-08-24 19:13:59 +10:00
public void Dispose ( )
{
browser = null ;
2018-12-17 13:50:29 +10:00
BitmapBuffer = null ;
PopupBuffer = null ;
2018-08-24 19:13:59 +10:00
}
2018-04-23 13:02:12 +10:00
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called to allow the client to return a ScreenInfo object with appropriate values.
/// If null is returned then the rectangle from GetViewRect will be used.
/// If the rectangle is still empty or invalid popups may not be drawn correctly.
/// </summary>
/// <returns>Return null if no screenInfo structure is provided.</returns>
2018-08-02 13:20:28 +10:00
public virtual ScreenInfo ? GetScreenInfo ( )
{
2021-11-16 13:40:39 +10:00
var screenInfo = new ScreenInfo { DeviceScaleFactor = browser . DeviceScaleFactor } ;
2018-04-23 14:15:25 +10:00
2018-08-24 19:13:59 +10:00
return screenInfo ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called to retrieve the view rectangle which is relative to screen coordinates.
/// This method must always provide a non-empty rectangle.
/// </summary>
/// <returns>Return a ViewRect strict containing the rectangle.</returns>
2018-12-16 10:48:52 +10:00
public virtual Rect GetViewRect ( )
2018-08-24 19:13:59 +10:00
{
//TODO: See if this can be refactored and remove browser reference
var size = browser . Size ;
var viewRect = new Rect ( 0 , 0 , size . Width , size . Height ) ;
return viewRect ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called to retrieve the translation from view coordinates to actual screen coordinates.
/// </summary>
/// <param name="viewX">x</param>
/// <param name="viewY">y</param>
/// <param name="screenX">screen x</param>
/// <param name="screenY">screen y</param>
/// <returns>Return true if the screen coordinates were provided.</returns>
2018-08-24 19:13:59 +10:00
public virtual bool GetScreenPoint ( int viewX , int viewY , out int screenX , out int screenY )
{
screenX = viewX ;
screenY = viewY ;
return false ;
}
2018-12-16 14:23:19 +10:00
/// <summary>
/// Called when an element has been rendered to the shared texture handle.
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
/// </summary>
/// <param name="type">indicates whether the element is the view or the popup widget.</param>
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
/// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
public virtual void OnAcceleratedPaint ( PaintElementType type , Rect dirtyRect , IntPtr sharedHandle )
{
//NOT USED
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when an element should be painted. Pixel values passed to this method are scaled relative to view coordinates based on the
/// value of <see cref="ScreenInfo.DeviceScaleFactor"/> returned from <see cref="GetScreenInfo"/>.
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to false.
/// Called on the CEF UI Thread
/// </summary>
/// <param name="type">indicates whether the element is the view or the popup widget.</param>
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
/// <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>
/// <param name="width">width</param>
/// <param name="height">height</param>
2018-08-24 19:13:59 +10:00
public virtual void OnPaint ( PaintElementType type , Rect dirtyRect , IntPtr buffer , int width , int height )
{
var isPopup = type = = PaintElementType . Popup ;
var bitmapBuffer = isPopup ? PopupBuffer : BitmapBuffer ;
bitmapBuffer . UpdateBuffer ( width , height , buffer , dirtyRect ) ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the browser's cursor has changed.
/// </summary>
/// <param name="cursor">If type is Custom then customCursorInfo will be populated with the custom cursor information</param>
/// <param name="type">cursor type</param>
/// <param name="customCursorInfo">custom cursor Information</param>
2018-08-24 19:13:59 +10:00
public virtual void OnCursorChange ( IntPtr cursor , CursorType type , CursorInfo customCursorInfo )
{
2018-09-10 02:41:13 +02:00
2018-08-24 19:13:59 +10:00
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the user starts dragging content in the web view. Contextual information about the dragged content is
/// supplied by dragData. OS APIs that run a system message loop may be used within the StartDragging call.
/// Don't call any of the IBrowserHost.DragSource*Ended* methods after returning false.
/// Return true to handle the drag operation. Call <see cref="IBrowserHost.DragSourceEndedAt"/> and <see cref="IBrowserHost.DragSourceSystemDragEnded"/> either synchronously or asynchronously to inform
/// the web view that the drag operation has ended.
/// </summary>
/// <param name="dragData">drag data</param>
/// <param name="mask">operation mask</param>
/// <param name="x">combined x and y provide the drag start location in screen coordinates</param>
/// <param name="y">combined x and y provide the drag start location in screen coordinates</param>
/// <returns>Return false to abort the drag operation.</returns>
2018-08-24 19:13:59 +10:00
public virtual bool StartDragging ( IDragData dragData , DragOperationsMask mask , int x , int y )
{
return false ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the web view wants to update the mouse cursor during a drag & drop operation.
/// </summary>
/// <param name="operation">describes the allowed operation (none, move, copy, link). </param>
2018-08-24 19:13:59 +10:00
public virtual void UpdateDragCursor ( DragOperationsMask operation )
{
2018-09-10 02:41:13 +02:00
2018-08-24 19:13:59 +10:00
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the browser wants to show or hide the popup widget.
/// </summary>
/// <param name="show">The popup should be shown if show is true and hidden if show is false.</param>
2018-08-24 19:13:59 +10:00
public virtual void OnPopupShow ( bool show )
{
PopupOpen = show ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the browser wants to move or resize the popup widget.
/// </summary>
/// <param name="rect">contains the new location and size in view coordinates. </param>
2018-08-24 19:13:59 +10:00
public virtual void OnPopupSize ( Rect rect )
{
popupPosition . X = rect . X ;
popupPosition . Y = rect . Y ;
popupSize . Width = rect . Width ;
popupSize . Height = rect . Height ;
}
2018-12-17 13:50:29 +10:00
/// <summary>
/// Called when the IME composition range has changed.
/// </summary>
/// <param name="selectedRange">is the range of characters that have been selected</param>
/// <param name="characterBounds">is the bounds of each character in view coordinates.</param>
2018-08-24 19:13:59 +10:00
public virtual void OnImeCompositionRangeChanged ( Range selectedRange , Rect [ ] characterBounds )
{
2018-09-10 02:41:13 +02:00
2018-08-24 19:13:59 +10:00
}
2019-03-27 20:08:46 +10:00
/// <summary>
/// Called when an on-screen keyboard should be shown or hidden for the specified browser.
/// </summary>
/// <param name="browser">the browser</param>
/// <param name="inputMode">specifies what kind of keyboard should be opened. If <see cref="TextInputMode.None"/>, any existing keyboard for this browser should be hidden.</param>
public virtual void OnVirtualKeyboardRequested ( IBrowser browser , TextInputMode inputMode )
{
}
2018-08-24 19:13:59 +10:00
}
2018-04-23 13:02:12 +10:00
}