Gtk3: fixed ExtTextOut, if OPAQUE in params we must call fillRect with BkColor brush before text is drawn.

This commit is contained in:
zeljan1 2025-01-14 21:35:28 +01:00
parent 6e243ea04b
commit d7aa102b72
2 changed files with 22 additions and 11 deletions

View File

@ -199,6 +199,7 @@ type
TGtk3DeviceContext = class (TGtk3Object) TGtk3DeviceContext = class (TGtk3Object)
private private
FBkColor:TColorRef; FBkColor:TColorRef;
FBgBrush: TGtk3Brush; //solid brush created when BkColor is setted up.
FBrush: TGtk3Brush; FBrush: TGtk3Brush;
FFont: TGtk3Font; FFont: TGtk3Font;
FvImage: TGtk3Image; FvImage: TGtk3Image;
@ -260,7 +261,7 @@ type
function getPixel(x, y: Integer): TColor; function getPixel(x, y: Integer): TColor;
procedure drawRect(x1, y1, w, h: Integer; const AFill, ABorder: Boolean); procedure drawRect(x1, y1, w, h: Integer; const AFill, ABorder: Boolean);
procedure drawRoundRect(x, y, w, h, rx, ry: Integer); procedure drawRoundRect(x, y, w, h, rx, ry: Integer);
procedure drawText(x, y: Integer; AText: PChar; ALen: Integer); procedure drawText(x, y: Integer; AText: PChar; ALen: Integer; const ABgFilled: boolean);
procedure drawEllipse(x, y, w, h: Integer; AFill, ABorder: Boolean); procedure drawEllipse(x, y, w, h: Integer; AFill, ABorder: Boolean);
procedure drawSurface(targetRect: PRect; Surface: Pcairo_surface_t; sourceRect: PRect; procedure drawSurface(targetRect: PRect; Surface: Pcairo_surface_t; sourceRect: PRect;
mask: PGdkPixBuf; maskRect: PRect); mask: PGdkPixBuf; maskRect: PRect);
@ -295,6 +296,7 @@ type
procedure set_antialiasing(aamode:boolean); procedure set_antialiasing(aamode:boolean);
property BkMode: integer read FBkMode write FBkMode; property BkMode: integer read FBkMode write FBkMode;
property BkColor: TColorRef read GetBkColor write SetBkColor; property BkColor: TColorRef read GetBkColor write SetBkColor;
property BgBrush: TGtk3Brush read FBgBrush; {bgBrush is created when SetBk is called, otherwise is nil}
property CanRelease: Boolean read FCanRelease write FCanRelease; property CanRelease: Boolean read FCanRelease write FCanRelease;
property CurrentBrush: TGtk3Brush read FCurrentBrush write FCurrentBrush; property CurrentBrush: TGtk3Brush read FCurrentBrush write FCurrentBrush;
property CurrentFont: TGtk3Font read FCurrentFont write FCurrentFont; property CurrentFont: TGtk3Font read FCurrentFont write FCurrentFont;
@ -1505,6 +1507,12 @@ end;
procedure TGtk3DeviceContext.setBkColor(AValue:TColorRef); procedure TGtk3DeviceContext.setBkColor(AValue:TColorRef);
begin begin
FBkColor := AValue; FBkColor := AValue;
if Assigned(FBgBrush) then
FBgBrush.Free;
FBgBrush := TGtk3Brush.Create;
FBgBrush.Style := BS_SOLID;
FBgBrush.Color := ColorToRGB(FBkColor);
FBgBrush.Context := Self;
end; end;
procedure TGtk3DeviceContext.SetFont(AValue: TGtk3Font); procedure TGtk3DeviceContext.SetFont(AValue: TGtk3Font);
@ -1911,6 +1919,7 @@ procedure TGtk3DeviceContext.CreateObjects;
var var
Matrix: Tcairo_matrix_t; Matrix: Tcairo_matrix_t;
begin begin
FBgBrush := nil; // created on demand
FBkMode := TRANSPARENT; FBkMode := TRANSPARENT;
FCurrentImage := nil; FCurrentImage := nil;
FCurrentRegion := nil; FCurrentRegion := nil;
@ -1943,6 +1952,8 @@ begin
FreeAndNil(FFont); FreeAndNil(FFont);
if Assigned(FvImage) then if Assigned(FvImage) then
FreeAndNil(FvImage); FreeAndNil(FvImage);
if Assigned(FBgBrush) then
FreeAndNil(FBgBrush);
end; end;
procedure TGtk3DeviceContext.drawPixel(x, y: Integer; AColor: TColor); procedure TGtk3DeviceContext.drawPixel(x, y: Integer; AColor: TColor);
@ -2005,8 +2016,8 @@ begin
RoundRect(x, y, w, h, rx, ry); RoundRect(x, y, w, h, rx, ry);
end; end;
procedure TGtk3DeviceContext.drawText(x, y: Integer; AText: PChar; ALen: Integer procedure TGtk3DeviceContext.drawText(x, y: Integer; AText: PChar; ALen: Integer;
); const ABgFilled: boolean);
var var
R, G, B: Double; R, G, B: Double;
gColor: TGdkColor; gColor: TGdkColor;
@ -2029,10 +2040,10 @@ begin
//This looks like a bug in logic. eg painting TTreeView: SetBkMode(OPAQUE) BkMode is OPAQUE but currentBrush.style is bsClear //This looks like a bug in logic. eg painting TTreeView: SetBkMode(OPAQUE) BkMode is OPAQUE but currentBrush.style is bsClear
//If we don't chech any of them text is not drawn as it should. //If we don't chech any of them text is not drawn as it should.
//TODO: check how this case works with win32 ws. //TODO: check how this case works with win32 ws.
UseBack := (FBkMode = OPAQUE) and (CurrentBrush.Style <> BS_NULL); UseBack := not ABgFilled and (FBkMode = OPAQUE) and (CurrentBrush.Style <> BS_NULL);
if UseBack then if UseBack then
begin begin
gColor := TColorToTGDKColor(FBkColor); gColor := TColorToTGDKColor(clHighlight);
AttrList := pango_attr_list_new; AttrList := pango_attr_list_new;
Attr := pango_attr_background_new(gColor.red, gColor.green, gColor.blue); Attr := pango_attr_background_new(gColor.red, gColor.green, gColor.blue);
pango_attr_list_insert(AttrList, Attr); pango_attr_list_insert(AttrList, Attr);

View File

@ -1580,7 +1580,7 @@ var
while CurCount > 0 do while CurCount > 0 do
begin begin
CharLen := UTF8CodepointSize(CurStr); CharLen := UTF8CodepointSize(CurStr);
DevCtx.drawText(CurScreenX, Y, CurStr, CharLen); DevCtx.drawText(CurScreenX, Y, CurStr, CharLen, True);
inc(CurScreenX, CurDx^); inc(CurScreenX, CurDx^);
inc(CurDx); inc(CurDx);
inc(CurStr, CharLen); inc(CurStr, CharLen);
@ -1588,7 +1588,7 @@ var
end; end;
end end
else begin else begin
DevCtx.drawText(X, Y, Str, Count); DevCtx.drawText(X, Y, Str, Count, True);
end; end;
end; end;
@ -1606,8 +1606,8 @@ begin
cairo_rectangle(GtkDc.pcr, Rect^.Left, Rect^.Top, Rect^.Right - Rect^.Left, Rect^.Bottom - Rect^.Top); cairo_rectangle(GtkDc.pcr, Rect^.Left, Rect^.Top, Rect^.Right - Rect^.Left, Rect^.Bottom - Rect^.Top);
cairo_clip(GtkDc.pcr); cairo_clip(GtkDc.pcr);
end; end;
if Options and ETO_OPAQUE = ETO_OPAQUE then // use Color from setBkMode if Options and ETO_OPAQUE = ETO_OPAQUE then
DevCtx.fillRect(Rect, 0{HBRUSH(GtkDC.CurrentBrush)}); DevCtx.fillRect(Rect, HBRUSH(DevCtx.BgBrush)); // use Color from setBkMode
LineLen := FindLineLen(Str,Count); LineLen := FindLineLen(Str,Count);
TopY := Y; TopY := Y;
@ -4174,7 +4174,7 @@ end;
function TGtk3WidgetSet.TextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): Boolean; function TGtk3WidgetSet.TextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): Boolean;
begin begin
{$IFDEF VerboseGtk3DeviceContext} {$IFDEF VerboseGtk3DeviceContext}
DebugLn('TGtk3WidgetSet.TextOut X=',dbgs(x),' Y=',dbgs(y),' Text=',dbgs(Str),' Count=',dbgs(Count)); DebugLn('TGtk3WidgetSet.TextOut X=',dbgs(x),' Y=',dbgs(y),' Text=',dbgs(Str),' Count=',dbgs(Count),' Text=',StrPas(Str));
{$ENDIF} {$ENDIF}
Result := False; Result := False;
if Count <= 0 then if Count <= 0 then
@ -4182,7 +4182,7 @@ begin
if IsValidDC(DC) then if IsValidDC(DC) then
begin begin
Result := True; Result := True;
TGtk3DeviceContext(DC).drawText(X, Y, Str, Count); TGtk3DeviceContext(DC).drawText(X, Y, Str, Count, False);
end; end;
end; end;