mirror of
https://github.com/salvadordf/CEF4Delphi.git
synced 2024-11-24 08:02:15 +02:00
ca8bc9dff4
Added the PDS file to extract the HTML Help files using PasDoc Added more XML documentation Fixed some XML errors. Removed the license copy from the pas units. Updated the LICENSE.md file
187 lines
4.7 KiB
ObjectPascal
187 lines
4.7 KiB
ObjectPascal
unit uCEFBrowserBitmap;
|
|
|
|
{$IFDEF FPC}
|
|
{$MODE OBJFPC}{$H+}
|
|
{$ENDIF}
|
|
|
|
{$I cef.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF DELPHI16_UP}
|
|
{$IFDEF MSWINDOWS}Winapi.Windows,{$ELSE}System.SyncObjs,{$ENDIF} System.Classes, System.SysUtils, Vcl.Graphics;
|
|
{$ELSE}
|
|
{$IFDEF MSWINDOWS}Windows,{$ENDIF} Classes, SysUtils, Graphics
|
|
{$IFDEF FPC}, LCLProc, LCLType, LCLIntf, LResources, InterfaceBase{$ENDIF}
|
|
{$IFNDEF MSWINDOWS}, SyncObjs{$ENDIF};
|
|
{$ENDIF}
|
|
|
|
type
|
|
TCEFBrowserBitmap = class(TBitmap)
|
|
protected
|
|
FScanlineSize : integer;
|
|
FDeviceScaleFactor : single;
|
|
{$IFDEF MSWINDOWS}
|
|
FSyncObj : THandle;
|
|
{$ELSE}
|
|
FSyncObj : TCriticalSection;
|
|
{$ENDIF}
|
|
|
|
function GetBufferBits : pointer;
|
|
|
|
procedure CreateSyncObj;
|
|
procedure DestroySyncObj;
|
|
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
function BeginBufferDraw : boolean;
|
|
procedure EndBufferDraw;
|
|
function UpdateBufferDimensions(aWidth, aHeight : integer) : boolean;
|
|
function BufferIsResized(aUseMutex : boolean = True) : boolean;
|
|
procedure BufferDraw(const aBitmap : TBitmap; const aSrcRect, aDstRect : TRect);
|
|
|
|
property ScanlineSize : integer read FScanlineSize;
|
|
property BufferBits : pointer read GetBufferBits;
|
|
property DeviceScaleFactor : single read FDeviceScaleFactor write FDeviceScaleFactor;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
uCEFMiscFunctions;
|
|
|
|
constructor TCEFBrowserBitmap.Create;
|
|
begin
|
|
inherited Create;
|
|
|
|
FScanlineSize := 0;
|
|
FDeviceScaleFactor := 1;
|
|
CreateSyncObj;
|
|
end;
|
|
|
|
destructor TCEFBrowserBitmap.Destroy;
|
|
begin
|
|
DestroySyncObj;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCEFBrowserBitmap.CreateSyncObj;
|
|
begin
|
|
{$IFDEF MSWINDOWS}
|
|
FSyncObj := CreateMutex(nil, False, nil);
|
|
{$ELSE}
|
|
FSyncObj := TCriticalSection.Create;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TCEFBrowserBitmap.DestroySyncObj;
|
|
begin
|
|
{$IFDEF MSWINDOWS}
|
|
if (FSyncObj <> 0) then
|
|
begin
|
|
CloseHandle(FSyncObj);
|
|
FSyncObj := 0;
|
|
end;
|
|
{$ELSE}
|
|
if (FSyncObj <> nil) then FreeAndNil(FSyncObj);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TCEFBrowserBitmap.GetBufferBits : pointer;
|
|
begin
|
|
if (Height <> 0) then
|
|
Result := Scanline[pred(Height)]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCEFBrowserBitmap.BeginBufferDraw : boolean;
|
|
begin
|
|
{$IFDEF MSWINDOWS}
|
|
Result := (FSyncObj <> 0) and (WaitForSingleObject(FSyncObj, 5000) = WAIT_OBJECT_0);
|
|
{$ELSE}
|
|
if (FSyncObj <> nil) then
|
|
begin
|
|
FSyncObj.Acquire;
|
|
Result := True;
|
|
end
|
|
else
|
|
Result := False;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TCEFBrowserBitmap.EndBufferDraw;
|
|
begin
|
|
{$IFDEF MSWINDOWS}
|
|
if (FSyncObj <> 0) then ReleaseMutex(FSyncObj);
|
|
{$ELSE}
|
|
if (FSyncObj <> nil) then FSyncObj.Release;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TCEFBrowserBitmap.UpdateBufferDimensions(aWidth, aHeight : integer) : boolean;
|
|
begin
|
|
Result := False;
|
|
FScanlineSize := aWidth * SizeOf(TRGBQuad);
|
|
|
|
if (Width <> aWidth) or
|
|
(Height <> aHeight) then
|
|
begin
|
|
{$IFDEF DELPHI16_UP}
|
|
SetSize(aWidth, aHeight);
|
|
{$ELSE}
|
|
Width := aWidth;
|
|
Height := aHeight;
|
|
{$ENDIF}
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function TCEFBrowserBitmap.BufferIsResized(aUseMutex : boolean) : boolean;
|
|
var
|
|
TempDevWidth, TempLogWidth, TempDevHeight, TempLogHeight : integer;
|
|
begin
|
|
Result := False;
|
|
|
|
if not(aUseMutex) or BeginBufferDraw then
|
|
begin
|
|
if (FDeviceScaleFactor = 1) then
|
|
Result := (Width = Width) and
|
|
(Height = Height)
|
|
else
|
|
begin
|
|
// CEF and Chromium use 'floor' to round the float values in Device <-> Logical unit conversions
|
|
// and Delphi uses MulDiv, which uses the bankers rounding, to resize the components in high DPI mode.
|
|
// This is the cause of slight differences in size between the buffer and the panel in some occasions.
|
|
|
|
TempLogWidth := DeviceToLogical(Width, FDeviceScaleFactor);
|
|
TempLogHeight := DeviceToLogical(Height, FDeviceScaleFactor);
|
|
|
|
TempDevWidth := LogicalToDevice(TempLogWidth, FDeviceScaleFactor);
|
|
TempDevHeight := LogicalToDevice(TempLogHeight, FDeviceScaleFactor);
|
|
|
|
Result := (Width = TempDevWidth) and
|
|
(Height = TempDevHeight);
|
|
end;
|
|
|
|
if aUseMutex then EndBufferDraw;
|
|
end;
|
|
end;
|
|
|
|
procedure TCEFBrowserBitmap.BufferDraw(const aBitmap : TBitmap; const aSrcRect, aDstRect : TRect);
|
|
begin
|
|
if (aBitmap <> nil) then
|
|
begin
|
|
Canvas.Lock;
|
|
aBitmap.Canvas.Lock;
|
|
Canvas.CopyRect(aDstRect, aBitmap.Canvas, aSrcRect);
|
|
aBitmap.Canvas.UnLock;
|
|
Canvas.UnLock;
|
|
end;
|
|
end;
|
|
|
|
end.
|