Gtk3: paired cairo_save() & cairo_restore() in TGtk3DeviceContext so we can see if there's mismatch.

This commit is contained in:
zeljan1 2025-01-26 15:50:33 +01:00
parent b9e392ee96
commit 522fb6cbd8
4 changed files with 52 additions and 41 deletions

View File

@ -122,7 +122,7 @@ begin
gc := TColortoTGdkRGBA(ColorToRGB(GtkDC.CurrentPen.Color));
DotSize := Max(1, GtkDC.CurrentPen.Width);
cairo_save(GtkDC.pcr);
GtkDC.Save;
//TODO: cairo_get_matrix(pcr, @matrix);
cairo_set_source_rgb(GtkDC.pcr, gc.red, gc.green, gc.blue);
@ -142,7 +142,7 @@ begin
cairo_fill(GtkDC.pcr);
cairo_new_path(GtkDC.pcr);
cairo_restore(GtkDC.pcr);
GtkDC.Restore;
end;

View File

@ -198,6 +198,7 @@ type
TGtk3DeviceContext = class (TGtk3Object)
private
FDCSaveCounter: integer;
FBkColor:TColorRef;
FBgBrush: TGtk3Brush; //solid brush created when BkColor is setted up.
FBrush: TGtk3Brush;
@ -1791,6 +1792,7 @@ begin
FOwnsSurface := False;
FCurrentTextColor := clBlack;
FBkColor := clWhite;
FDCSaveCounter := 0;
if AWidget = nil then
begin
ACairo := gdk_cairo_create(gdk_get_default_root_window);
@ -1844,6 +1846,7 @@ begin
' FromPaintEvent:',BoolToStr(APaintEvent),' )');
{$endif}
inherited Create;
FDCSaveCounter := 0;
FXorSurface := nil;
FCanvasScaleFactor := 1;
FvClipRect := Rect(0, 0, 0, 0);
@ -1874,6 +1877,7 @@ begin
' FromPaintEvent:',BoolToStr(True),' )');
{$endif}
inherited Create;
FDCSaveCounter := 0;
FXorSurface := nil;
FCanvasScaleFactor := 1;
FOwnsCairo := False;
@ -1901,6 +1905,9 @@ begin
if FXorMode then
RasterOp := R2_COPYPEN;
if FDCSaveCounter > 0 then
DebugLn('WARNING: TGtk3DeviceContext: Unpaired Cairo save/restore calls. Current count = ',dbgs(FDCSaveCounter),', but should be 0.');
if FOwnsCairo and (FCairo <> nil) then
cairo_destroy(FCairo);
@ -1999,7 +2006,7 @@ end;
procedure TGtk3DeviceContext.drawRect(x1, y1, w, h: Integer; const AFill, ABorder: Boolean);
begin
cairo_save(pcr);
Save;
try
cairo_rectangle(pcr, x1 + PixelOffset, y1 + PixelOffset, w - 1, h - 1);
@ -2016,7 +2023,7 @@ begin
cairo_new_path(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2035,7 +2042,7 @@ var
UseBack: boolean;
ornt:integer;
begin
cairo_save(pcr);
Save;
try
cairo_move_to(pcr, X, Y);
ornt := Self.FCurrentFont.FLogFont.lfOrientation;
@ -2067,7 +2074,7 @@ begin
pango_attribute_destroy(Attr);
end;
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2076,7 +2083,7 @@ var
save_matrix: Tcairo_matrix_t;
//SaveMode:Integer;
begin
cairo_save(pcr);
Save;
try
cairo_get_matrix(pcr, @save_matrix);
cairo_translate (pcr, x + w / 2.0 + PixelOffset, y + h / 2.0 + PixelOffset);
@ -2100,7 +2107,7 @@ begin
end;
cairo_set_matrix(pcr, @save_matrix);
finally
cairo_restore(pcr);
Restore;
end;
if ABorder then
begin
@ -2120,7 +2127,7 @@ begin
{$IFDEF VerboseGtk3DeviceContext}
DebugLn('TGtk3DeviceContext.DrawSurface ');
{$ENDIF}
cairo_save(pcr);
Save;
try
with targetRect^ do
cairo_rectangle(pcr, Left + PixelOffset, Top + PixelOffset, Right - Left, Bottom - Top);
@ -2134,7 +2141,7 @@ begin
cairo_clip(pcr);
cairo_paint(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2148,7 +2155,7 @@ begin
{$IFDEF VerboseGtk3DeviceContext}
DebugLn('TGtk3DeviceContext.DrawImage ');
{$ENDIF}
cairo_save(pcr);
Save;
try
// pm := Image;
// AData := PByte(gdk_pixbuf_get_pixels(pm));
@ -2159,8 +2166,7 @@ begin
cairo_rectangle(pcr, Left + PixelOffset, Top + PixelOffset, Right - Left, Bottom - Top);
cairo_paint(pcr);
finally
// cairo_surface_destroy(ASurface);
cairo_restore(pcr);
Restore;
end;
end;
@ -2172,7 +2178,7 @@ begin
{$IFDEF VerboseGtk3DeviceContext}
DebugLn('TGtk3DeviceContext.DrawImage ');
{$ENDIF}
cairo_save(pcr);
Save;
try
gdk_cairo_set_source_pixbuf(pcr, Image, 0, 0);
with targetRect^ do
@ -2191,7 +2197,7 @@ begin
cairo_clip(pcr);
cairo_paint(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2204,7 +2210,7 @@ begin
{$IFDEF VerboseGtk3DeviceContext}
DebugLn('TGtk3DeviceContext.DrawPixmap ');
{$ENDIF}
cairo_save(pcr);
Save;
try
AData := PByte(gdk_pixbuf_get_pixels(pm));
ASurface := cairo_image_surface_create_for_data(AData, CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width(pm), gdk_pixbuf_get_height(pm), gdk_pixbuf_get_rowstride(pm));
@ -2212,7 +2218,7 @@ begin
cairo_paint(pcr);
finally
cairo_surface_destroy(ASurface);
cairo_restore(pcr);
Restore;
end;
end;
@ -2220,7 +2226,7 @@ procedure TGtk3DeviceContext.drawPolyLine(P: PPoint; NumPts: Integer);
var
i: Integer;
begin
cairo_save(pcr);
Save;
try
ApplyPen;
cairo_move_to(pcr, P[0].X+PixelOffset, P[0].Y+PixelOffset);
@ -2228,9 +2234,8 @@ begin
cairo_line_to(pcr, P[i].X+PixelOffset, P[i].Y+PixelOffset);
cairo_stroke(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
procedure TGtk3DeviceContext.drawPolygon(P: PPoint; NumPts: Integer;
@ -2238,7 +2243,7 @@ procedure TGtk3DeviceContext.drawPolygon(P: PPoint; NumPts: Integer;
var
i: Integer;
begin
cairo_save(pcr);
Save;
try
// add offset so the center of the pixel is used
cairo_move_to(pcr, P[0].X+PixelOffset, P[0].Y+PixelOffset);
@ -2261,7 +2266,7 @@ begin
cairo_new_path(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2280,7 +2285,7 @@ begin
// we need 3 points left for continuous and 4 for not continous
MaxIndex := NumPoints - 3 - Ord(not Continuous);
cairo_save(pcr);
Save;
try
i := 0;
while i <= MaxIndex do
@ -2322,7 +2327,7 @@ begin
else
cairo_new_path(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2345,7 +2350,7 @@ begin
//DebugLn('TGtk3DeviceContext.fillRect ',Format('x %d y %d w %d h %d',[x, y, w, h]));
{$endif}
cairo_save(pcr);
Save;
try
if ABrush <> 0 then
begin
@ -2370,7 +2375,7 @@ begin
CurrentBrush:= ATempBrush;
cairo_new_path(pcr);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2400,7 +2405,7 @@ procedure TGtk3DeviceContext.EllipseArcPath(CX, CY, RX, RY: Double; Angle1, Angl
begin
if (RX=0) or (RY=0) then //cairo_scale do not likes zero params
Exit;
cairo_save(pcr);
Save;
try
cairo_translate(pcr, SX(CX), SY(CY));
cairo_scale(pcr, SX2(RX), SY2(RY));
@ -2411,7 +2416,7 @@ begin
else
cairo_arc_negative(pcr, 0, 0, 1, Angle1, Angle2);
finally
cairo_restore(pcr);
Restore;
end;
end;
@ -2749,11 +2754,15 @@ end;
procedure TGtk3DeviceContext.Save;
begin
cairo_save(pcr);
inc(FDCSaveCounter);
end;
procedure TGtk3DeviceContext.Restore;
begin
dec(FDCSaveCounter);
cairo_restore(pcr);
if FDCSaveCounter < 0 then
DebugLn('WARNING: TGtk3DeviceContext: Cairo restore called without save.');
end;
procedure TGtk3DeviceContext.SetCanvasScaleFactor(const AValue: double);

View File

@ -1600,7 +1600,7 @@ begin
if IsValidDC(DC)then
begin
cairo_save(GtkDc.pcr);
GtkDC.Save;
if Options and ETO_CLIPPED = ETO_CLIPPED then
begin
cairo_rectangle(GtkDc.pcr, Rect^.Left, Rect^.Top, Rect^.Right - Rect^.Left, Rect^.Bottom - Rect^.Top);
@ -1642,7 +1642,7 @@ begin
LineLen := Count;
end;
end;
cairo_restore(GtkDc.pcr);
GtkDC.Restore;
Result := True;
end;
end;
@ -1710,9 +1710,10 @@ begin
end;
end;
cr := TGtk3DeviceContext(DC).pcr;
cairo_save(cr);
TGtk3DeviceContext(DC).Save;
try
cr := TGtk3DeviceContext(DC).pcr;
cairo_set_line_width(cr, 1);
cairo_set_line_cap(cr, Tcairo_line_cap_t.CAIRO_LINE_CAP_ROUND);
cairo_set_line_join(cr, Tcairo_line_join_t.CAIRO_LINE_JOIN_ROUND);
@ -1736,7 +1737,7 @@ begin
InflateRect(ARect, -1, -1);
end;
finally
cairo_restore(cr);
TGtk3DeviceContext(DC).Restore;
end;
end;
@ -3454,7 +3455,7 @@ begin
Result := False;
if not IsValidDC(DC) then
exit;
cairo_restore(TGtk3DeviceContext(DC).pcr);
TGtk3DeviceContext(DC).Restore;
Result := True;
end;
@ -3475,7 +3476,7 @@ begin
Result := 0;
if not IsValidDC(DC) then
exit;
cairo_save(TGtk3DeviceContext(DC).pcr);
TGtk3DeviceContext(DC).Save;
Result := 1;
end;

View File

@ -337,16 +337,17 @@ class procedure TGtk3WSWinControl.PaintTo(const AWinControl: TWinControl; ADC: H
X, Y: Integer);
var
AWidget: TGtk3Widget;
cr: Pcairo_t;
begin
if not WSCheckHandleAllocated(AWincontrol, 'PaintTo') or (ADC = 0) then
Exit;
AWidget := TGtk3Widget(AWinControl.Handle);
cr := TGtk3DeviceContext(ADC).pcr;
cairo_save(cr);
cairo_translate(cr, X, Y);
gtk_widget_draw(AWidget.Widget, cr);
cairo_restore(cr);
TGtk3DeviceContext(ADC).Save;
with TGtk3DeviceContext(ADC) do
begin
cairo_translate(pcr, X, Y);
gtk_widget_draw(AWidget.Widget, pcr);
end;
TGtk3DeviceContext(ADC).Restore;
end;
class procedure TGtk3WSWinControl.SetBounds(const AWinControl: TWinControl; const ALeft, ATop, AWidth, AHeight: Integer);