mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 08:59:10 +02:00
Qt: introduced TQtGDIObjects class to track gdi objects validity, added missing TQtRegion into SelectObject()
git-svn-id: trunk@33483 -
This commit is contained in:
parent
5c5bd65faa
commit
014bdd4735
@ -85,6 +85,7 @@ begin
|
|||||||
{$J+}
|
{$J+}
|
||||||
QtVersionInt(QtVersionMajor, QtVersionMinor, QtVersionMicro);
|
QtVersionInt(QtVersionMajor, QtVersionMinor, QtVersionMicro);
|
||||||
{$J-}
|
{$J-}
|
||||||
|
QtGDIObjects := TQtGDIObjects.Create;
|
||||||
InitStockItems;
|
InitStockItems;
|
||||||
QtWidgetSet := Self;
|
QtWidgetSet := Self;
|
||||||
ClearCachedColors;
|
ClearCachedColors;
|
||||||
@ -147,6 +148,9 @@ begin
|
|||||||
|
|
||||||
System.DoneCriticalsection(CriticalSection);
|
System.DoneCriticalsection(CriticalSection);
|
||||||
|
|
||||||
|
if Assigned(QtGDIObjects) then
|
||||||
|
FreeThenNil(QtGDIObjects);
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -902,8 +906,9 @@ var
|
|||||||
aObject: TObject;
|
aObject: TObject;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
if GDIObject = 0 then Exit;
|
if not QtGDIObjects.IsValidGDIObject(GDIObject) then
|
||||||
|
exit;
|
||||||
|
|
||||||
aObject := TObject(GDIObject);
|
aObject := TObject(GDIObject);
|
||||||
try
|
try
|
||||||
@ -917,8 +922,8 @@ begin
|
|||||||
(aObject is TQtRegion);
|
(aObject is TQtRegion);
|
||||||
end;
|
end;
|
||||||
except
|
except
|
||||||
DebugLn(['Gdi object: ', GDIObject, ' is not an object!']);
|
// DebugLn(['TQtWidgetSet.IsValidGDIObject: Gdi object ', GDIObject, ' is not an object!']);
|
||||||
raise Exception.CreateFmt('TQtWidgetSet.IsValidGDIObject: %u is not valid object!',[PtrUInt(GdiObject)]);
|
raise Exception.CreateFmt('TQtWidgetSet.IsValidGDIObject: %u is not an object ',[PtrUInt(GDIObject)]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ uses
|
|||||||
// Free Pascal
|
// Free Pascal
|
||||||
Classes, SysUtils, Types,
|
Classes, SysUtils, Types,
|
||||||
// LCL
|
// LCL
|
||||||
LCLType, LCLIntf, Menus, LCLProc, Graphics, ClipBrd, ExtCtrls, Interfacebase;
|
LCLType, LCLIntf, Menus, LCLProc, Graphics, ClipBrd, ExtCtrls, Interfacebase,
|
||||||
|
maps;
|
||||||
|
|
||||||
type
|
type
|
||||||
// forward declarations
|
// forward declarations
|
||||||
@ -812,6 +813,25 @@ type
|
|||||||
property ObjList: TFPList read FObjList;
|
property ObjList: TFPList read FObjList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TQtGDIObjects }
|
||||||
|
|
||||||
|
TQtGDIObjects = class(TObject)
|
||||||
|
private
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
FMaxCount: Int64;
|
||||||
|
FInvalidCount: Int64;
|
||||||
|
{$ENDIF}
|
||||||
|
FCount: Integer;
|
||||||
|
FSavedHandlesList: TMap;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure AddGDIObject(AObject: TObject);
|
||||||
|
procedure RemoveGDIObject(AObject: TObject);
|
||||||
|
function IsValidGDIObject(AGDIObject: PtrUInt): Boolean;
|
||||||
|
property Count: PtrInt read FCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
LCLQt_Destroy = QEventType(Ord(QEventUser) + $1000);
|
LCLQt_Destroy = QEventType(Ord(QEventUser) + $1000);
|
||||||
@ -832,6 +852,9 @@ function QtScreenContext: TQtDeviceContext;
|
|||||||
procedure AssignQtFont(FromFont: QFontH; ToFont: QFontH);
|
procedure AssignQtFont(FromFont: QFontH; ToFont: QFontH);
|
||||||
function IsFontEqual(AFont1, AFont2: TQtFont): Boolean;
|
function IsFontEqual(AFont1, AFont2: TQtFont): Boolean;
|
||||||
|
|
||||||
|
var
|
||||||
|
QtGDIObjects: TQtGDIObjects = nil;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -1255,6 +1278,7 @@ begin
|
|||||||
FHandle := QImage_create();
|
FHandle := QImage_create();
|
||||||
FData := nil;
|
FData := nil;
|
||||||
FDataOwner := False;
|
FDataOwner := False;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1267,6 +1291,7 @@ begin
|
|||||||
FHandle := vHandle;
|
FHandle := vHandle;
|
||||||
FData := nil;
|
FData := nil;
|
||||||
FDataOwner := False;
|
FDataOwner := False;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1287,6 +1312,7 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
FHandle := QImage_create(FData, width, height, format);
|
FHandle := QImage_create(FData, width, height, format);
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TQtImage.Create(AData: PByte; width: Integer; height: Integer;
|
constructor TQtImage.Create(AData: PByte; width: Integer; height: Integer;
|
||||||
@ -1299,6 +1325,7 @@ begin
|
|||||||
FHandle := QImage_create(width, height, format)
|
FHandle := QImage_create(width, height, format)
|
||||||
else
|
else
|
||||||
FHandle := QImage_create(FData, width, height, bytesPerLine, format);
|
FHandle := QImage_create(FData, width, height, bytesPerLine, format);
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1314,6 +1341,8 @@ begin
|
|||||||
WriteLn('TQtImage.Destroy Handle:', dbgs(Handle));
|
WriteLn('TQtImage.Destroy Handle:', dbgs(Handle));
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
QtGDIObjects.RemoveGDIObject(Self);
|
||||||
|
|
||||||
if FHandle <> nil then
|
if FHandle <> nil then
|
||||||
QImage_destroy(FHandle);
|
QImage_destroy(FHandle);
|
||||||
if (FDataOwner) and (FData <> nil) then
|
if (FDataOwner) and (FData <> nil) then
|
||||||
@ -1477,6 +1506,7 @@ begin
|
|||||||
FMetrics := nil;
|
FMetrics := nil;
|
||||||
FDefaultFont := nil;
|
FDefaultFont := nil;
|
||||||
FFontInfo := nil;
|
FFontInfo := nil;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TQtFont.Create(AFromFont: QFontH);
|
constructor TQtFont.Create(AFromFont: QFontH);
|
||||||
@ -1490,6 +1520,7 @@ begin
|
|||||||
FMetrics := nil;
|
FMetrics := nil;
|
||||||
FDefaultFont := nil;
|
FDefaultFont := nil;
|
||||||
GetFontInfo;
|
GetFontInfo;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1503,6 +1534,8 @@ begin
|
|||||||
WriteLn('TQtFont.Destroy');
|
WriteLn('TQtFont.Destroy');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
QtGDIObjects.RemoveGDIObject(Self);
|
||||||
|
|
||||||
if FMetrics <> nil then
|
if FMetrics <> nil then
|
||||||
FMetrics.Free;
|
FMetrics.Free;
|
||||||
|
|
||||||
@ -1515,6 +1548,7 @@ begin
|
|||||||
if FDefaultFont <> nil then
|
if FDefaultFont <> nil then
|
||||||
QFont_destroy(FDefaultFont);
|
QFont_destroy(FDefaultFont);
|
||||||
|
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1759,6 +1793,7 @@ begin
|
|||||||
|
|
||||||
FShared := False;
|
FShared := False;
|
||||||
FSelected := False;
|
FSelected := False;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1772,6 +1807,8 @@ begin
|
|||||||
WriteLn('TQtBrush.Destroy');
|
WriteLn('TQtBrush.Destroy');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
QtGDIObjects.RemoveGDIObject(Self);
|
||||||
|
|
||||||
if not FShared and (FHandle <> nil) and not FSelected then
|
if not FShared and (FHandle <> nil) and not FSelected then
|
||||||
QBrush_destroy(FHandle);
|
QBrush_destroy(FHandle);
|
||||||
|
|
||||||
@ -1867,6 +1904,7 @@ begin
|
|||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
FShared := False;
|
FShared := False;
|
||||||
FIsExtPen := False;
|
FIsExtPen := False;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -1880,6 +1918,8 @@ begin
|
|||||||
WriteLn('TQtPen.Destroy');
|
WriteLn('TQtPen.Destroy');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
QtGDIObjects.RemoveGDIObject(Self);
|
||||||
|
|
||||||
if not FShared and (FHandle <> nil) then
|
if not FShared and (FHandle <> nil) then
|
||||||
QPen_destroy(FHandle);
|
QPen_destroy(FHandle);
|
||||||
|
|
||||||
@ -2009,6 +2049,7 @@ begin
|
|||||||
FHandle := QRegion_create()
|
FHandle := QRegion_create()
|
||||||
else
|
else
|
||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
@ -2039,6 +2080,7 @@ begin
|
|||||||
FHandle := QRegion_create(X1, Y1, W, H, RegionType);
|
FHandle := QRegion_create(X1, Y1, W, H, RegionType);
|
||||||
end else
|
end else
|
||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TQtRegion.Create(CreateHandle: Boolean; Poly: QPolygonH;
|
constructor TQtRegion.Create(CreateHandle: Boolean; Poly: QPolygonH;
|
||||||
@ -2054,6 +2096,7 @@ begin
|
|||||||
FHandle := QRegion_create(FPolygon, Fill);
|
FHandle := QRegion_create(FPolygon, Fill);
|
||||||
end else
|
end else
|
||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
|
QtGDIObjects.AddGDIObject(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -2067,6 +2110,7 @@ begin
|
|||||||
{$ifdef VerboseQt}
|
{$ifdef VerboseQt}
|
||||||
WriteLn('TQtRegion.Destroy');
|
WriteLn('TQtRegion.Destroy');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
QtGDIObjects.RemoveGDIObject(Self);
|
||||||
if FPolygon <> nil then
|
if FPolygon <> nil then
|
||||||
QPolygon_destroy(FPolygon);
|
QPolygon_destroy(FPolygon);
|
||||||
if FHandle <> nil then
|
if FHandle <> nil then
|
||||||
@ -5014,6 +5058,68 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TQtGDIObjects }
|
||||||
|
|
||||||
|
constructor TQtGDIObjects.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
FMaxCount := 0;
|
||||||
|
FInvalidCount := 0;
|
||||||
|
{$ENDIF}
|
||||||
|
FCount := 0;
|
||||||
|
FSavedHandlesList := TMap.Create(TMapIdType(ituPtrSize), SizeOf(TObject));
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
DebugLn('TQtGDIObjects.Create ');
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TQtGDIObjects.Destroy;
|
||||||
|
begin
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
DebugLn('TQtGDIObjects.Destroy: Count (must be zero) ',dbgs(FCount),
|
||||||
|
' FMaxCount ',dbgs(FMaxCount),' FInvalidCount ',dbgs(FInvalidCount));
|
||||||
|
{$ENDIF}
|
||||||
|
FSavedHandlesList.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TQtGDIObjects.AddGDIObject(AObject: TObject);
|
||||||
|
begin
|
||||||
|
if not FSavedHandlesList.HasId(AObject) then
|
||||||
|
begin
|
||||||
|
FSavedHandlesList.Add(AObject, AObject);
|
||||||
|
inc(FCount);
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
if FMaxCount < FCount then
|
||||||
|
FMaxCount := FCount;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TQtGDIObjects.RemoveGDIObject(AObject: TObject);
|
||||||
|
begin
|
||||||
|
if FSavedHandlesList.HasId(AObject) then
|
||||||
|
begin
|
||||||
|
FSavedHandlesList.Delete(AObject);
|
||||||
|
dec(FCount);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TQtGDIObjects.IsValidGDIObject(AGDIObject: PtrUInt): Boolean;
|
||||||
|
begin
|
||||||
|
if (AGDIObject = 0) then
|
||||||
|
Exit(False);
|
||||||
|
Result := FSavedHandlesList.HasId(TObject(AGDIObject));
|
||||||
|
{$IFDEF DebugQTGDIObjects}
|
||||||
|
if not Result then
|
||||||
|
begin
|
||||||
|
inc(FInvalidCount);
|
||||||
|
DebugLn('TQtGDIObjects.IsValidGDIObject: Invalid object ',dbgs(AGDIObject));
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -5325,6 +5325,11 @@ begin
|
|||||||
|
|
||||||
// TODO: is this also saved in qpainter_save?
|
// TODO: is this also saved in qpainter_save?
|
||||||
TQtDeviceContext(DC).setImage(TQtImage(aObject));
|
TQtDeviceContext(DC).setImage(TQtImage(aObject));
|
||||||
|
end else
|
||||||
|
if AObject is TQtRegion then
|
||||||
|
begin
|
||||||
|
Result := HGDIOBJ(TQtDeviceContext(DC).getClipRegion);
|
||||||
|
SelectClipRGN(DC, HRGN(GDIObj));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef VerboseQtWinAPI}
|
{$ifdef VerboseQtWinAPI}
|
||||||
|
Loading…
Reference in New Issue
Block a user