gtk2: rework SetWindowOrgEx() and related code

git-svn-id: trunk@38742 -
This commit is contained in:
paul 2012-09-19 01:48:48 +00:00
parent 43c1ff001c
commit 977f05a8ef
8 changed files with 253 additions and 298 deletions

View File

@ -317,6 +317,7 @@ type
procedure SetViewPortExt(const AValue: TPoint);
procedure SetViewPortOrg(const AValue: TPoint);
procedure SetWindowExt(const AValue: TPoint);
procedure SetWindowOrg(AValue: TPoint);
protected
function CreateGC: PGdkGC; virtual;
@ -361,7 +362,7 @@ type
function GetBrush: PGdiObject;
function GetPen: PGdiObject;
function GetBitmap: PGdiObject;
function GetFunction: TGdkFunction; virtual; abstract;
function GetFunction: TGdkFunction;
function IsNullBrush: boolean;
function IsNullPen: boolean;
function SelectObject(AGdiObject: PGdiObject): PGdiObject;
@ -386,8 +387,9 @@ type
// help functions
function CopyDataFrom(ASource: TGtkDeviceContext; AClearSource, AMoveGDIOwnerShip, ARestore: Boolean): Boolean;
function FillRect(ARect: TRect; ABrush: HBrush; SkipRop: Boolean): Boolean;
procedure DrawTextWithColors(AText: PChar; ALength: LongInt; X, Y: Integer; FGColor, BGColor: PGdkColor);
// origins
// device origin
property Offset: TPoint read GetOffset;
// drawing settings
property CurrentBitmap: PGdiObject read FCurrentBitmap write SetCurrentBitmap;
@ -405,7 +407,7 @@ type
property ViewPortExt: TPoint read FViewPortExt write SetViewPortExt;
property ViewPortOrg: TPoint read FViewPortOrg write SetViewPortOrg;
property WindowExt: TPoint read FWindowExt write SetWindowExt;
property WindowOrg: TPoint read FWindowOrg write FWindowOrg;
property WindowOrg: TPoint read FWindowOrg write SetWindowOrg;
// control
property SelectedColors: TDevContextSelectedColorsType read FSelectedColors write SetSelectedColors;
property Flags: TDeviceContextsFlags read FFlags write FFlags;
@ -603,16 +605,7 @@ function dbgs(g: TGDIType): string; overload;
function dbgs(const r: TGDKRectangle): string; overload;
function dbgs(r: PGDKRectangle): string; overload;
type
{ TGtk2DeviceContext }
TGtk2DeviceContext = class(TGtkDeviceContext)
public
procedure DrawTextWithColors(AText: PChar; ALength: LongInt; X, Y: Integer; FGColor, BGColor: PGdkColor);
function GetFunction: TGdkFunction; override;
end;
procedure SetLayoutText(ALayout: PPangoLayout; AText: PChar; ALength: PtrInt);
procedure SetLayoutText(ALayout: PPangoLayout; AText: PChar; ALength: PtrInt);
implementation

View File

@ -61,23 +61,11 @@ begin
gdk_region_get_clipbox(FClipRegion^.GDIRegionObject, @Result);
end;
{------------------------------------------------------------------------------
function GetOffset
Returns the DC offset for the DC Origin.
------------------------------------------------------------------------------}
function TGtkDeviceContext.GetOffset: TPoint;
var
Fixed: Pointer;
begin
if Self = nil then
begin
Result.X := 0;
Result.Y := 0;
Exit;
end;
Result := WindowOrg;
Result := Point(0, 0);
if Assigned(FWidget) then
begin
Fixed := GetFixedWidget(FWidget);
@ -181,7 +169,12 @@ begin
end;
FMapMode := AValue;
// to do: combine with affine transformations here when they get implemented
FHasTransf := (FMapMode <> MM_TEXT) or (FViewPortOrg.x <> 0) or (FViewPortOrg.y <> 0);
FHasTransf :=
(FMapMode <> MM_TEXT) or
(FViewPortOrg.x <> 0) or
(FViewPortOrg.y <> 0) or
(FWindowOrg.x <> 0) or
(FWindowOrg.y <> 0);
if not (FMapMode in [MM_TEXT, MM_ANISOTROPIC, MM_ISOTROPIC]) then
begin
FViewPortExt.X := Gtk2WidgetSet.GetDeviceCaps(HDC(Self), LOGPIXELSX);
@ -281,6 +274,16 @@ begin
end;
end;
procedure TGtkDeviceContext.SetWindowOrg(AValue: TPoint);
begin
if (FWindowOrg.x <> AValue.x) or
(FWindowOrg.y <> AValue.y) then
begin
FWindowOrg := AValue;
FHasTransf := True;
end;
end;
procedure TGtkDeviceContext.SetSelectedColors(AValue: TDevContextSelectedColorsType);
begin
if FSelectedColors = AValue then Exit;
@ -303,31 +306,31 @@ end;
procedure TGtkDeviceContext.InvTransfPoint(var X1, Y1: Integer);
begin
X1 := MulDiv(X1 - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y1 := MulDiv(Y1 - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
X1 := MulDiv(X1 + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y1 := MulDiv(Y1 + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
// to do: put affine inverse transformation here (for all Inv.. methods)
end;
function TGtkDeviceContext.InvTransfPointIndirect(const P: TPoint): TPoint;
begin
Result.X := MulDiv(P.X - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Y := MulDiv(P.Y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
Result.X := MulDiv(P.X + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Y := MulDiv(P.Y + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
end;
procedure TGtkDeviceContext.InvTransfRect(var X1, Y1, X2, Y2: Integer);
begin
X1 := MulDiv(X1 - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y1 := MulDiv(Y1 - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
X2 := MulDiv(X2 - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y2 := MulDiv(Y2 - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
X1 := MulDiv(X1 + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y1 := MulDiv(Y1 + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
X2 := MulDiv(X2 + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Y2 := MulDiv(Y2 + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
end;
function TGtkDeviceContext.InvTransfRectIndirect(const R: TRect): TRect;
begin
Result.Left := MulDiv(R.Left - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Top := MulDiv(R.Top - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
Result.Right := MulDiv(R.Right - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Bottom := MulDiv(R.Bottom - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
Result.Left := MulDiv(R.Left + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Top := MulDiv(R.Top + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
Result.Right := MulDiv(R.Right + FWindowOrg.x - FViewPortOrg.x, FWindowExt.x, FViewPortExt.x);
Result.Bottom := MulDiv(R.Bottom + FWindowOrg.y - FViewPortOrg.y, FWindowExt.y, FViewPortExt.y);
end;
procedure TGtkDeviceContext.InvTransfExtent(var ExtX, ExtY: Integer);
@ -373,30 +376,30 @@ end;
procedure TGtkDeviceContext.TransfPoint(var X1, Y1: Integer);
begin
// to do: put affine transformation here (for all Transf.. methods)
X1 := MulDiv(X1, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Y1 := MulDiv(Y1, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
X1 := MulDiv(X1, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Y1 := MulDiv(Y1, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
end;
function TGtkDeviceContext.TransfPointIndirect(const P: TPoint): TPoint;
begin
Result.x := MulDiv(P.x, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Result.Y := MulDiv(P.y, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
Result.x := MulDiv(P.x, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Result.Y := MulDiv(P.y, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
end;
procedure TGtkDeviceContext.TransfRect(var X1, Y1, X2, Y2: Integer);
begin
X1 := MulDiv(X1, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Y1 := MulDiv(Y1, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
X2 := MulDiv(X2, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Y2 := MulDiv(Y2, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
X1 := MulDiv(X1, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Y1 := MulDiv(Y1, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
X2 := MulDiv(X2, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Y2 := MulDiv(Y2, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
end;
function TGtkDeviceContext.TransfRectIndirect(const R: TRect): TRect;
begin
Result.Left := MulDiv(R.Left, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Result.Top := MulDiv(R.Top, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
Result.Right := MulDiv(R.Right, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x;
Result.Bottom := MulDiv(R.Bottom, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y;
Result.Left := MulDiv(R.Left, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Result.Top := MulDiv(R.Top, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
Result.Right := MulDiv(R.Right, FViewPortExt.x, FWindowExt.x) + FViewPortOrg.x - FWindowOrg.x;
Result.Bottom := MulDiv(R.Bottom, FViewPortExt.y, FWindowExt.y) + FViewPortOrg.y - FWindowOrg.y;
end;
procedure TGtkDeviceContext.TransfExtent(var ExtX, ExtY: Integer);
@ -430,7 +433,10 @@ begin
if FCurrentFont^.LogFont.lfHeight > 0 then
AHeight := 1
else
AHeight := -1;
if FCurrentFont^.LogFont.lfHeight < 0 then
AHeight := -1
else
AHeight := 0;
if FCurrentFont^.LogFont.lfHeight <> AHeight then
begin
FontCache.Unreference(FCurrentFont^.GDIFontObject);
@ -438,6 +444,7 @@ begin
TmpObj := {%H-}PGdiObject(PtrUInt(GTK2WidgetSet.CreateFontIndirect(FCurrentFont^.LogFont)));
FCurrentFont^.GDIFontObject := TmpObj^.GDIFontObject;
TmpObj^.GDIFontObject := nil;
TmpObj^.RefCount := 0;
GTK2WidgetSet.DisposeGDIObject(TmpObj);
end;
end;
@ -624,7 +631,7 @@ var
g: TGDIType;
CurGDIObject: PGDIObject;
begin
Result := (Self <> nil) and (ASource <> nil);
Result := Assigned(Self) and Assigned(ASource);
if not Result then Exit;
if ARestore then
@ -633,7 +640,7 @@ begin
RaiseRestoreDifferentWidget;
end else
begin
if FWidget <> nil then
if Assigned(FWidget) then
RaiseWidgetAlreadySet;
FWidget := ASource.FWidget;
end;
@ -642,7 +649,7 @@ begin
FDrawable := ASource.FDrawable;
FOriginalDrawable := ASource.FOriginalDrawable;
if FGC <> nil then
if Assigned(FGC) then
begin
// free old GC
gdk_gc_unref(FGC);
@ -650,7 +657,7 @@ begin
Exclude(FFlags, dcfPenSelected);
end;
if (ASource.FGC <> nil) and (FDrawable <> nil) then
if Assigned(ASource.FGC) and Assigned(FDrawable) then
begin
gdk_gc_get_values(ASource.FGC, @FGCValues);
FGC := gdk_gc_new_with_values(FDrawable, @FGCValues,
@ -666,7 +673,7 @@ begin
else
Exclude(FFlags, dcfTextMetricsValid);
for g:=Low(TGDIType) to High(TGDIType) do
for g := Low(TGDIType) to High(TGDIType) do
begin
GDIObjects[g] := ASource.GDIObjects[g];
if AClearSource then
@ -674,14 +681,12 @@ begin
if AMoveGDIOwnerShip then
begin
if OwnedGDIObjects[g]<>nil then
begin
if Assigned(OwnedGDIObjects[g]) then
DeleteObject(HGDIOBJ({%H-}PtrUInt(OwnedGDIObjects[g])));
end;
CurGDIObject := ASource.OwnedGDIObjects[g];
if CurGDIObject<>nil then
if Assigned(CurGDIObject) then
begin
ASource.OwnedGDIObjects[g] := nil;
OwnedGDIObjects[g] := CurGDIObject;
@ -692,7 +697,6 @@ begin
CopyGDIColor(ASource.CurrentBackColor, CurrentBackColor);
SelectedColors := dcscCustom;
FWindowOrg := ASource.FWindowOrg;
PenPos := ASource.PenPos;
if FHasTransf then
@ -702,6 +706,7 @@ begin
FViewPortExt := Point(1, 1);
FViewPortOrg := Point(0, 0);
FWindowExt := Point(1, 1);
FWindowOrg := Point(0, 0);
TransfUpdateFont;
TransfUpdatePen;
end;
@ -713,6 +718,7 @@ begin
FViewPortExt := ASource.ViewPortExt;
FViewPortOrg := ASource.ViewPortOrg;
FWindowExt := ASource.WindowExt;
FWindowOrg := ASource.WindowOrg;
TransfUpdateFont;
TransfUpdatePen;
end;
@ -1061,6 +1067,7 @@ end;
constructor TGtkDeviceContext.Create;
begin
Clear;
BkMode := OPAQUE;
end;
@ -1221,24 +1228,22 @@ begin
Result := FCurrentBitmap;
end;
function TGtkDeviceContext.GetFunction: TGdkFunction;
begin
Result := GCValues._function;
end;
procedure SetLayoutText(ALayout: PPangoLayout; AText: PChar; ALength: PtrInt);
var
OldStr: PChar;
begin
OldStr := pango_layout_get_text(ALayout);
if (strlcomp(AText, OldStr, ALength) <> 0) or (strlen(OldStr)<>ALength) then
if (strlen(OldStr)<>ALength) or (strlcomp(AText, OldStr, ALength) <> 0) then
pango_layout_set_text(ALayout, AText, ALength);
end;
{ TGtk2DeviceContext }
function TGtk2DeviceContext.GetFunction: TGdkFunction;
begin
Result := GCValues._function;
end;
procedure TGtk2DeviceContext.DrawTextWithColors(AText: PChar; ALength: LongInt;
procedure TGtkDeviceContext.DrawTextWithColors(AText: PChar; ALength: LongInt;
X, Y: Integer; FGColor, BGColor: PGdkColor);
var
WidgetCont: PPangoContext;

View File

@ -84,7 +84,6 @@ type
procedure SetAppActive(const AValue: Boolean);
protected
function CreateThemeServices: TThemeServices; override;
function GetDeviceContextClass: TGtkDeviceContextClass;
protected
FKeyStateList_: TFPList; // Keeps track of which keys are pressed
FDeviceContexts: TDynHashArray;// hasharray of HDC

View File

@ -769,14 +769,13 @@ begin
DebugLn('TGtk2WidgetSet.GetRawImageFromDevice A DCOrigin=',dbgs(DCOrigin.X),',',dbgs(DCOrigin.Y),' SrcRect=',dbgs(ARect.Left),',',dbgs(ARect.Top),',',dbgs(ARect.Right),',',dbgs(ARect.Bottom));
{$ENDIF}
R := ARect;
LPtoDP(ADC, R, 2);
OffSetRect(R, DCOrigin.x, DCOrigin.y);
Drawable := DevCtx.Drawable;
if Drawable = nil
then begin
if Drawable = nil then
// get screen shot
Drawable := gdk_screen_get_root_window(gdk_screen_get_default);
end;
Result := RawImage_FromDrawable(ARawImage, Drawable, nil, @R);
end;

View File

@ -241,7 +241,7 @@ begin
Result.Style := gtk_widget_get_style(Result.Widget);
end;
Result.Window := DevCtx.Drawable;
Result.Origin := DevCtx.Offset;
Result.Origin := DevCtx.TransfPointIndirect(DevCtx.Offset);
Result.Painter := gptDefault;
Result.State := GTK_STATE_NORMAL;

View File

@ -246,13 +246,6 @@ begin
end;
{$EndIf}
{ TGtk2WidgetSet }
function TGtk2WidgetSet.GetDeviceContextClass: TGtkDeviceContextClass;
begin
Result := TGtk2DeviceContext;
end;
{------------------------------------------------------------------------------
Function: TGtk2WidgetSet._SetCallbackEx
@ -4030,6 +4023,9 @@ begin
SrcDevContext.TransfPoint(XSrc, YSrc);
SrcDevContext.TransfExtent(SrcWidth, SrcHeight);
end;
SrcDCOrigin := SrcDevContext.Offset;
Inc(XSrc, SrcDCOrigin.X);
Inc(YSrc, SrcDCOrigin.Y);
if DstDevContext.HasTransf then
begin
@ -4037,6 +4033,9 @@ begin
DstDevContext.TransfPoint(X, Y);
DstDevContext.TransfExtent(Width, Height);
end;
DstDCOrigin := DstDevContext.Offset;
Inc(X, DstDCOrigin.X);
Inc(Y, DstDCOrigin.Y);
FlipHorz := Width < 0;
if FlipHorz then
@ -4058,16 +4057,10 @@ begin
SizeChange := (Width <> SrcWidth) or (Height <> SrcHeight) or FlipVert or FlipHorz;
ROpIsSpecial := (Rop <> SRCCOPY);
SrcDCOrigin := SrcDevContext.Offset;
Inc(XSrc, SrcDCOrigin.X);
Inc(YSrc, SrcDCOrigin.Y);
if SrcDevContext.Drawable = nil then RaiseSrcDrawableNil;
gdk_window_get_size(PGdkWindow(SrcDevContext.Drawable), @SrcWholeWidth, @SrcWholeHeight);
DstDCOrigin := DstDevContext.Offset;
Inc(X, DstDCOrigin.X);
Inc(Y, DstDCOrigin.Y);
if DstDevContext.Drawable = nil then RaiseDestDrawableNil;
gdk_window_get_size(PGdkWindow(DstDevContext.Drawable), @DstWholeWidth, @DstWholeHeight);
@ -5092,9 +5085,9 @@ var
begin
if (DC = nil) or (DC.Drawable = nil) then exit;
DCOrigin := DC.Offset;
inc(X,DCOrigin.X);
inc(Y,DCOrigin.Y);
DCOrigin := DC.TransfPointIndirect(DC.Offset);
inc(X, DCOrigin.X);
inc(Y, DCOrigin.Y);
DC.SelectedColors := dcscCustom;
GDKColor := AllocGDKColor(ColorToRGB(AColor));
@ -5153,9 +5146,9 @@ begin
Result := clNone;
if (DC = nil) or (DC.Drawable = nil) then Exit;
DCOrigin := DC.Offset;
inc(X,DCOrigin.X);
inc(Y,DCOrigin.Y);
DCOrigin := DC.TransfPointIndirect(DC.Offset);
inc(X, DCOrigin.X);
inc(Y, DCOrigin.Y);
gdk_drawable_get_size(DC.Drawable, @MaxX, @MaxY);
if (X<0) or (Y<0) or (X>=MaxX) or (Y>=MaxY) then exit;
@ -5247,7 +5240,7 @@ begin
if FDCManager = nil
then begin
FDCManager := TDeviceContextMemManager.Create(GetDeviceContextClass);
FDCManager := TDeviceContextMemManager.Create(TGtkDeviceContext);
FDCManager.MinimumFreeCount := 1000;
end;
Result := FDCManager.NewDeviceContext;

View File

@ -1876,12 +1876,12 @@ end;
ComplexRegion
------------------------------------------------------------------------------}
function TGtk2WidgetSet.CombineRgn(Dest, Src1, Src2 : HRGN;
fnCombineMode : Longint) : Longint;
function TGtk2WidgetSet.CombineRgn(Dest, Src1, Src2: HRGN;
fnCombineMode: Longint): Longint;
var
Continue : Boolean;
D, S1, S2 : PGDKRegion;
DObj, S1Obj, S2Obj : PGDIObject;
Continue: Boolean;
D, S1, S2: PGDKRegion;
DObj, S1Obj, S2Obj: PGDIObject;
begin
Result := SIMPLEREGION;
DObj := {%H-}PGdiObject(Dest);
@ -1913,7 +1913,7 @@ begin
D := nil;
end;
end;
if DObj^.GDIRegionObject <> nil then
if Assigned(DObj^.GDIRegionObject) then
gdk_region_destroy(DObj^.GDIRegionObject);
DObj^.GDIRegionObject := D;
Result := RegionType(D);
@ -2281,8 +2281,10 @@ var
R: TRect;
begin
Result := False;
if IsValidDC(DC) then begin
with LogPen do begin
if IsValidDC(DC) then
begin
with LogPen do
begin
lopnStyle := PS_DOT;
lopnWidth.X := 2;
lopnColor := clWhite;
@ -2298,8 +2300,8 @@ begin
Origin := DevCtx.Offset;
try
with R do begin
with R do
begin
DrawHorzLine(Left, Top, Right-1);
DrawVertLine(Right-1, Top, Bottom-1);
DrawHorzLine(Right-1, Bottom-1, Left);
@ -2362,85 +2364,80 @@ var
begin
//DebugLn('TGtk2WidgetSet.DrawEdge Edge=',DbgS(Edge),8),' grfFlags=',DbgS(Cardinal(grfFlags));
Result := IsValidDC(DC);
if Result
then with TGtkDeviceContext(DC) do
begin
R := ARect;
if DevCtx.HasTransf then
if Result then
with TGtkDeviceContext(DC) do
begin
R := DevCtx.TransfRectIndirect(R);
TransfNormalize(R.Left, R.Right);
TransfNormalize(R.Top, R.Bottom);
R := ARect;
LPtoDP(DC, R, 2);
DCOrigin := Offset;
OffsetRect(R, DCOrigin.X, DCOrigin.Y);
// try to use the gdk functions, so that the current theme is used
BInner := False;
BOuter := False;
// TODO: change this to real colors
if (edge and BDR_RAISEDINNER) = BDR_RAISEDINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BInner := True;
end;
if (edge and BDR_SUNKENINNER) = BDR_SUNKENINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BInner := True;
end;
if (edge and BDR_RAISEDOUTER) = BDR_RAISEDOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BOuter := True;
end;
if (edge and BDR_SUNKENOUTER) = BDR_SUNKENOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BOuter := True;
end;
gdk_gc_set_fill(GC, GDK_SOLID);
SelectedColors := dcscCustom;
// Draw outer rect
if BOuter then
DrawEdges(R, GC,Drawable,OuterTL,OuterBR);
// Draw inner rect
if BInner then
DrawEdges(R,GC,Drawable,InnerTL,InnerBR);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterBR, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerBR, 1);
//Draw interiour
if ((grfFlags and BF_MIDDLE) = BF_MIDDLE) then
begin
MiddleColor := AllocGDKColor(GetSysColor(COLOR_BTNFACE));
gdk_gc_set_foreground(GC, @MiddleColor);
gdk_draw_rectangle(Drawable, GC, 1, R.Left, R.Top,
R.Right - R.Left, R.Bottom - R.Top);
end;
// adjust rect if needed
if (grfFlags and BF_ADJUST) = BF_ADJUST then
begin
ARect := R;
OffsetRect(ARect, -DCOrigin.X, -DCOrigin.Y);
DPtoLP(DC, ARect, 2);
end;
Result := True;
end;
DCOrigin := Offset;
OffsetRect(R,DCOrigin.X,DCOrigin.Y);
// try to use the gdk functions, so that the current theme is used
BInner := False;
BOuter := False;
// TODO: change this to real colors
if (edge and BDR_RAISEDINNER) = BDR_RAISEDINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BInner := True;
end;
if (edge and BDR_SUNKENINNER) = BDR_SUNKENINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BInner := True;
end;
if (edge and BDR_RAISEDOUTER) = BDR_RAISEDOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BOuter := True;
end;
if (edge and BDR_SUNKENOUTER) = BDR_SUNKENOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BOuter := True;
end;
gdk_gc_set_fill(GC, GDK_SOLID);
SelectedColors := dcscCustom;
// Draw outer rect
if BOuter then
DrawEdges(R, GC,Drawable,OuterTL,OuterBR);
// Draw inner rect
if BInner then
DrawEdges(R,GC,Drawable,InnerTL,InnerBR);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterBR, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerBR, 1);
//Draw interiour
if ((grfFlags and BF_MIDDLE) = BF_MIDDLE) then
begin
MiddleColor := AllocGDKColor(GetSysColor(COLOR_BTNFACE));
gdk_gc_set_foreground(GC, @MiddleColor);
gdk_draw_rectangle(Drawable, GC, 1, R.Left, R.Top,
R.Right - R.Left, R.Bottom - R.Top);
end;
// adjust rect if needed
if (grfFlags and BF_ADJUST) = BF_ADJUST then
begin
OffsetRect(R, -DCOrigin.X, -DCOrigin.Y);
ARect := R;
end;
Result := True;
end;
end;
{------------------------------------------------------------------------------
@ -2631,7 +2628,7 @@ var
function NeedOffsetCalc: Boolean;
begin
Result := (TGtk2DeviceContext(DC).CurrentFont^.LogFont.lfOrientation <> 0) and
Result := (TGtkDeviceContext(DC).CurrentFont^.LogFont.lfOrientation <> 0) and
(Flags and DT_SINGLELINE <> 0) and
(Flags and DT_VCENTER = 0) and (Flags and DT_CENTER = 0) and
(Flags and DT_RIGHT = 0) and (Flags and DT_BOTTOM = 0) and
@ -2665,7 +2662,7 @@ var
begin
Pt.X := SavedRect.Left;
Pt.Y := SavedRect.Top;
CalculateOffsetWithAngle(TGtk2DeviceContext(DC).CurrentFont^.LogFont.lfOrientation, Pt.X, Pt.Y);
CalculateOffsetWithAngle(TGtkDeviceContext(DC).CurrentFont^.LogFont.lfOrientation, Pt.X, Pt.Y);
end;
TextUtf8Out(DC, LeftPos + Pt.X, TopPos + Pt.Y, theLine, lineLength);
end;
@ -2698,7 +2695,7 @@ var
begin
Pt.X := SavedRect.Left;
Pt.Y := SavedRect.Top;
CalculateOffsetWithAngle(TGtk2DeviceContext(DC).CurrentFont^.LogFont.lfOrientation, Pt.X, Pt.Y);
CalculateOffsetWithAngle(TGtkDeviceContext(DC).CurrentFont^.LogFont.lfOrientation, Pt.X, Pt.Y);
end;
// Draw line of Text
TextUtf8Out(DC, LeftPos + Pt.X, TopPos + Pt.Y, theLine, LineLength);
@ -3757,7 +3754,6 @@ var
Clip,
Tmp : hRGN;
X, Y : Longint;
DCOrigin: TPoint;
begin
Result := SIMPLEREGION;
if not IsValidDC(DC) then
@ -3766,7 +3762,8 @@ begin
begin
//DebugLn('TGtk2WidgetSet.ExtSelectClipRGN A ClipRegValid=',dbgs(DCClipRegionValid(DC)),
// ' Mode=',dbgs(Mode),' RGN=',GDKRegionAsString(PGdiObject(RGN)^.GDIRegionObject));
if ClipRegion=nil then begin
if ClipRegion = nil then
begin
// there is no clipping region in the DC
case Mode of
RGN_COPY:
@ -3782,8 +3779,7 @@ begin
begin
// get existing clip
GDK_Window_Get_Size(Drawable, @X, @Y);
DCOrigin:= Offset;
Clip := CreateRectRGN(-DCOrigin.X,-DCOrigin.Y,X-DCOrigin.X,Y-DCOrigin.Y);
Clip := CreateRectRGN(0, 0, X, Y);
// create target clip
Tmp := CreateEmptyRegion;
// combine
@ -3813,7 +3809,7 @@ end;
function TGtk2WidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint;
Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean;
var
DevCtx: TGtk2DeviceContext absolute DC;
DevCtx: TGtkDeviceContext absolute DC;
LineStart, LineEnd, StrEnd: PChar;
Width, Height: Integer;
@ -3878,7 +3874,7 @@ begin
if DevCtx.HasTransf then
begin
if Rect <> nil then
if Assigned(Rect) then
Rect^ := DevCtx.TransfRectIndirect(Rect^);
DevCtx.TransfPoint(X, Y);
end;
@ -4086,17 +4082,12 @@ begin
DevCtx.SelectedColors:= dcscCustom;
EnsureGCColor(DC, dccGDIBrushColor, True, False);//Brush Color
if DevCtx.HasTransf then
begin
R := DevCtx.TransfRectIndirect(ARect);
DevCtx.TransfNormalize(R.Left, R.Right);
DevCtx.TransfNormalize(R.Top, R.Bottom);
end else
R := ARect;
R := ARect;
LPtoDP(DC, R, 2);
DCOrigin := DevCtx.Offset;
gdk_draw_rectangle(DevCtx.Drawable, DevCtx.GC, 0,
R.Left+DCOrigin.X, R.Top+DCOrigin.Y,
R.Left + DCOrigin.X, R.Top + DCOrigin.Y,
R.Right-R.Left-1, R.Bottom-R.Top-1);
end;
@ -4478,28 +4469,31 @@ begin
end;
DCOrigin := DevCtx.Offset;
if DevCtx.ClipRegion = nil
then begin
if DevCtx.ClipRegion = nil then
begin
if (DevCtx.PaintRectangle.Left<>0)
or (DevCtx.PaintRectangle.Top<>0)
or (DevCtx.PaintRectangle.Right<>0)
or (DevCtx.PaintRectangle.Bottom<>0) then begin
lpRect^:=DevCtx.PaintRectangle;
end else begin
or (DevCtx.PaintRectangle.Bottom<>0) then
lpRect^ := DevCtx.PaintRectangle
else
begin
gdk_window_get_size(DevCtx.Drawable, @X, @Y);
lpRect^ := Rect(0,0,X,Y);
end;
OffsetRect(lpRect^,-DCOrigin.X, -DCOrigin.Y);
Result := SIMPLEREGION;
end
else begin
else
begin
Result := RegionType(DevCtx.ClipRegion^.GDIRegionObject);
gdk_region_get_clipbox(DevCtx.ClipRegion^.GDIRegionObject, @CRect);
lpRect^.Left := CRect.X-DCOrigin.X;
lpRect^.Top := CRect.Y-DCOrigin.Y;
lpRect^.Left := CRect.X;
lpRect^.Top := CRect.Y;
lpRect^.Right := lpRect^.Left + CRect.Width;
lpRect^.Bottom := lpRect^.Top + CRect.Height;
end;
DPtoLP(DC, lpRect^, 2);
OffsetRect(lpRect^, -DCOrigin.X, -DCOrigin.Y);
end;
{------------------------------------------------------------------------------
@ -4571,35 +4565,41 @@ begin
Result := SIMPLEREGION;
If (not IsValidDC(DC)) then
Result := ERROR
else If Not IsValidGDIObject(RGN) then begin
else
if Not IsValidGDIObject(RGN) then
begin
Result := ERROR;
DebugLn('WARNING: [TGtk2WidgetSet.GetClipRGN] Invalid HRGN');
end
else if (TGtkDeviceContext(DC).ClipRegion<>nil)
and (not IsValidGDIObject(HGDIOBJ({%H-}PtrUInt(TGtkDeviceContext(DC).ClipRegion)))) then
else
if Assigned(TGtkDeviceContext(DC).ClipRegion) and
not IsValidGDIObject(HGDIOBJ({%H-}PtrUInt(TGtkDeviceContext(DC).ClipRegion))) then
Result := ERROR
else with TGtkDeviceContext(DC) do
begin
CurRegionObject:=nil;
if ClipRegion<>nil then
CurRegionObject:=ClipRegion^.GDIRegionObject;
ARect:=Rect(0,0,0,0);
if CurRegionObject<>nil then begin
CurRegionObject := nil;
if Assigned(ClipRegion) then
CurRegionObject := ClipRegion^.GDIRegionObject;
ARect := Rect(0, 0, 0, 0);
if Assigned(CurRegionObject) then
begin
// create a copy of the current clipregion
ClipRegionWithDCOffset:=gdk_region_copy(CurRegionObject);
ClipRegionWithDCOffset := gdk_region_copy(CurRegionObject);
// move it to the DC offset
// Example: if the ClipRegion is at 10,10 and the DCOrigin is at 10,10,
// then the ClipRegion must be moved to 0,0
DCOrigin := Offset;
//debugln('TGtk2WidgetSet.GetClipRGN DCOrigin=',dbgs(DCOrigin),' CurRegionObject=',dbgs(CurRegionObject),' ',dbgs(ARect));
gdk_region_offset(ClipRegionWithDCOffset,-DCOrigin.x,-DCOrigin.Y);
end else begin
gdk_region_offset(ClipRegionWithDCOffset, -DCOrigin.x, -DCOrigin.Y);
end
else
begin
// create a default clipregion
GetClipBox(DC,@ARect);
ClipRegionWithDCOffset:=CreateRectGDKRegion(ARect);
GetClipBox(DC, @ARect);
ClipRegionWithDCOffset := CreateRectGDKRegion(ARect);
end;
// free the old region in RGN
if {%H-}PGdiObject(RGN)^.GDIRegionObject<>nil then
if Assigned({%H-}PGdiObject(RGN)^.GDIRegionObject) then
gdk_region_destroy({%H-}PGdiObject(RGN)^.GDIRegionObject);
// set the new region in RGN
{%H-}PGdiObject(RGN)^.GDIRegionObject := ClipRegionWithDCOffset;
@ -4657,7 +4657,7 @@ end;
function TGtk2WidgetSet.GetCurrentObject(DC: HDC; uObjectType: UINT): HGDIOBJ;
var
Gtk2DC: TGtk2DeviceContext absolute DC;
Gtk2DC: TGtkDeviceContext absolute DC;
begin
Result := 0;
if not GTK2WidgetSet.IsValidDC(DC) then
@ -4837,25 +4837,25 @@ var
DCWindow: PGdkWindow;
begin
Result := false;
OriginDiff := Point(0,0);
OriginDiff := Point(0, 0);
if not IsValidDC(PaintDC) then exit;
DCOrigin := DevCtx.Offset;
DCWindow:=PGdkWindow(DevCtx.Drawable);
DCWindow := PGdkWindow(DevCtx.Drawable);
gdk_window_get_origin(DCWindow, @(DCScreenOrigin.X), @(DCScreenOrigin.Y));
inc(DCScreenOrigin.X, DCOrigin.X);
inc(DCScreenOrigin.Y, DCOrigin.Y);
Widget := GetFixedWidget({%H-}PGtkWidget(WindowHandle));
if Widget = nil
then Widget := {%H-}PGtkWidget(WindowHandle);
if Widget = nil then
Widget := {%H-}PGtkWidget(WindowHandle);
gdk_window_get_origin(PGdkWindow(Widget^.window), @(WindowScreenOrigin.X), @(WindowScreenOrigin.Y));
OriginDiff.X := DCScreenOrigin.X-WindowScreenOrigin.X;
OriginDiff.Y := DCScreenOrigin.Y-WindowScreenOrigin.Y;
Result := true;
OriginDiff.X := DCScreenOrigin.X - WindowScreenOrigin.X;
OriginDiff.Y := DCScreenOrigin.Y - WindowScreenOrigin.Y;
Result := True;
//DebugLn(['TGtk2WidgetSet.GetDCOriginRelativeToWindow DCScreenOrigin=',dbgs(DCScreenOrigin),' WindowScreenOrigin=',dbgs(WindowScreenOrigin),' OriginDiff=',dbgs(OriginDiff)]);
end;
@ -5982,7 +5982,7 @@ end;
function TGtk2WidgetSet.GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer;
var Size: TSize): Boolean;
var
DevCtx: TGtk2DeviceContext absolute DC;
DevCtx: TGtkDeviceContext absolute DC;
UseFont : PPangoLayout;
begin
Result := IsValidDC(DC);
@ -6152,7 +6152,7 @@ end;
Returns the current offset of the DC.
------------------------------------------------------------------------------}
function TGtk2WidgetSet.GetWindowOrgEx(dc : hdc; P : PPoint): Integer;
function TGtk2WidgetSet.GetWindowOrgEx(dc: hdc; P: PPoint): Integer;
var
DevCtx: TGtkDeviceContext absolute DC;
begin
@ -6160,8 +6160,8 @@ begin
P^ := Point(0,0);
if not IsValidDC(DC) then exit(0);
P^ := DevCtx.Offset;
Result:=1;
P^ := DevCtx.WindowOrg;
Result := 1;
end;
{------------------------------------------------------------------------------
@ -6648,10 +6648,8 @@ var
DevCtx: TGtkDeviceContext absolute DC;
DCOrigin: TPoint;
FromX: Integer;
FromY: Integer;
ToX: Integer;
ToY: Integer;
FromPt: TPoint;
ToPt: TPoint;
begin
if not IsValidDC(DC) then Exit(False);
@ -6660,21 +6658,16 @@ begin
if DevCtx.IsNullPen then Exit(True);
if DevCtx.HasTransf then
DevCtx.TransfPoint(X, Y);
DCOrigin := DevCtx.Offset;
FromX:=DevCtx.PenPos.X+DCOrigin.X;
FromY:=DevCtx.PenPos.Y+DCOrigin.Y;
ToX:=X+DCOrigin.X;
ToY:=Y+DCOrigin.Y;
FromPt := DevCtx.PenPos;
LPtoDP(DC, FromPt, 1);
ToPt := Point(X, Y);
LPToDP(DC, ToPt, 1);
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
gdk_draw_line(DevCtx.Drawable, DevCtx.GC, FromX, FromY, ToX, ToY);
gdk_draw_line(DevCtx.Drawable, DevCtx.GC, FromPt.X, FromPt.Y, ToPt.X, ToPt.Y);
{$IFDEF DebugGDK}EndGDKErrorTrap;{$ENDIF}
DevCtx.PenPos:= Point(X, Y);
DevCtx.PenPos := Point(X, Y);
Result := True;
end;
@ -6831,44 +6824,18 @@ end;
------------------------------------------------------------------------------}
function TGtk2WidgetSet.MoveToEx(DC: HDC; X, Y: Integer;
OldPoint: PPoint): Boolean;
function TGtk2WidgetSet.MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean;
var
DevCtx: TGtkDeviceContext absolute DC;
begin
Result := IsValidDC(DC);
if Result
then with TGtkDeviceContext(DC) do
begin
if OldPoint <> nil then OldPoint^ := PenPos;
if DevCtx.HasTransf then
DevCtx.TransfPoint(X, Y);
PenPos := Point(X, Y);
end;
end;
{------------------------------------------------------------------------------
function MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean; override;
Move the origin of all operations of a DeviceContext.
For example:
Moving the Origin to 10,20 and drawing a point to 50,50, results in
drawing a point to 60,70.
------------------------------------------------------------------------------}
function TGtk2WidgetSet.MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean;
var
NewOrigin: TPoint;
begin
Result := IsValidDC(DC);
if Result then
with TGtkDeviceContext(DC) do
begin
NewOrigin := WindowOrg;
inc(NewOrigin.X, dX);
inc(NewOrigin.Y, dY);
WindowOrg := NewOrigin;
if Assigned(OldPoint) then
OldPoint^ := PenPos;
PenPos := Point(X, Y);
end;
end;
@ -7071,8 +7038,8 @@ begin
begin
if DevCtx.HasTransf then
Points[I] := DevCtx.TransfPointIndirect(Points[I]);
PointArray[i].x:=Points[i].x+DCOrigin.X;
PointArray[i].y:=Points[i].y+DCOrigin.Y;
PointArray[i].x := Points[i].x + DCOrigin.X;
PointArray[i].y := Points[i].y + DCOrigin.Y;
end;
// draw line
@ -7912,7 +7879,7 @@ begin
if not IsValidDC(DC) then Exit(ERROR);
// clear old clipregion
if DevCtx.ClipRegion <> nil
if Assigned(DevCtx.ClipRegion)
then begin
OldClipRegion := DevCtx.ClipRegion;
DevCtx.ClipRegion := nil;// decrease DCCount
@ -9183,16 +9150,17 @@ end;
Sets the DC offset for the specified device context.
------------------------------------------------------------------------------}
function TGtk2WidgetSet.SetWindowOrgEx(DC : HDC; NewX, NewY : Integer;
OldPoint: PPoint) : Boolean;
function TGtk2WidgetSet.SetWindowOrgEx(DC: HDC; NewX, NewY: Integer; OldPoint: PPoint): Boolean;
var
OldP: TPoint;
DevCtx: TGtkDeviceContext absolute DC;
begin
//DebugLn('[TGtk2WidgetSet.SetWindowOrgEx] ',NewX,' ',NewY);
GetWindowOrgEx(DC, @OldP);
Result := MoveWindowOrgEx(DC, -NewX - OldP.X, -NewY - OldP.Y);
if OldPoint <> nil then
OldPoint^ := OldP;
if Assigned(OldPoint) then
GetWindowOrgEx(DC, OldPoint);
if not IsValidDC(DC) then exit(False);
DevCtx.WindowOrg := Point(NewX, NewY);
Result := True;
end;
{------------------------------------------------------------------------------
@ -9654,10 +9622,10 @@ end;
Returns:
------------------------------------------------------------------------------}
function TGtk2WidgetSet.TextOut(DC: HDC; X,Y : Integer; Str : Pchar;
function TGtk2WidgetSet.TextOut(DC: HDC; X, Y: Integer; Str: Pchar;
Count: Integer) : Boolean;
var
DevCtx: TGtk2DeviceContext absolute DC;
DevCtx: TGtkDeviceContext absolute DC;
DCOrigin: TPoint;
yOffset: integer;
BackGroundColor: PGdkColor;
@ -9666,7 +9634,6 @@ begin
if not Result then Exit;
if Count <= 0 then Exit;
if DevCtx.HasTransf then
DevCtx.TransfPoint(X, Y);
@ -9682,8 +9649,8 @@ begin
EnsureGCColor(DC, dccCurrentTextColor, True, False);
BackGroundColor := nil;
if (DevCtx.GDIObjects[gdiBrush] <> nil) and (DevCtx.BkMode = OPAQUE) and
(DevCtx.CurrentBackColor.Colormap <> nil) then
if Assigned(DevCtx.GDIObjects[gdiBrush]) and (DevCtx.BkMode = OPAQUE) and
Assigned(DevCtx.CurrentBackColor.Colormap) then
begin
EnsureGCColor(DC, dccCurrentBackColor, DevCtx.GDIObjects[gdiBrush]^.GDIBrushFill = GDK_SOLID, True);
//do not set BackGroundColor if CurrentBrush.Color = CurrentBackColor.

View File

@ -170,7 +170,6 @@ function LPtoDP(DC: HDC; var Points; Count: Integer): BOOL; override;
function MessageBox({%H-}hWnd: HWND; lpText, lpCaption: PChar; uType: Cardinal): integer; override;
function MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean; override;
function MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean; override;
function OffsetRgn(RGN: HRGN; nXOffset, nYOffset: Integer): Integer; override;