Gtk2: introduced TGtkDeviceContext.ClipRect, now gtk_paint_xxx() respects clipping rectangle. issue #14660

git-svn-id: trunk@29537 -
This commit is contained in:
zeljko 2011-02-13 20:26:48 +00:00
parent a5cebb65d2
commit b8d5b4793d
6 changed files with 70 additions and 40 deletions

View File

@ -293,6 +293,7 @@ type
FViewPortOrg: TPoint; // current viewport origin
FWindowExt: TPoint; // current window extent
function GetClipRectangle: TGdkRectangle;
function GetGDIObjects(ID: TGDIType): PGdiObject;
function GetOffset: TPoint;
function GetOwnedGDIObjects(ID: TGDIType): PGdiObject;
@ -395,6 +396,7 @@ type
property CurrentPen: PGdiObject read FCurrentPen write SetCurrentPen;
property CurrentBrush: PGdiObject read FCurrentBrush write SetCurrentBrush;
property CurrentPalette: PGdiObject read FCurrentPalette write SetCurrentPalette;
property ClipRect: TGdkRectangle read GetClipRectangle;
property ClipRegion: PGdiObject read FClipRegion write SetClipRegion;
property GCValues: TGdkGCValues read FGCValues;
property GDIObjects[ID: TGDIType]: PGdiObject read GetGDIObjects write SetGDIObjects;

View File

@ -43,6 +43,24 @@ begin
end;
end;
function TGtkDeviceContext.GetClipRectangle: TGdkRectangle;
var
X,Y: gint;
begin
if FClipRegion = nil then
begin
if (PaintRectangle.Left<>0) or (PaintRectangle.Top<>0) or
(PaintRectangle.Right<>0) or (PaintRectangle.Bottom<>0) then
Result := GdkRectFromRect(PaintRectangle)
else
begin
gdk_window_get_size(Drawable, @X, @Y);
Result := GdkRectFromRect(Rect(0,0, X, Y));
end;
end else
gdk_region_get_clipbox(FClipRegion^.GDIRegionObject, @Result);
end;
{------------------------------------------------------------------------------
function GetOffset
@ -707,6 +725,7 @@ var
OldCurrentBrush: PGdiObject;
DCOrigin: TPoint;
BrushChanged: Boolean;
ClipArea: TGdkRectangle;
begin
BrushChanged := False;
if not IsNullBrush then
@ -735,12 +754,13 @@ begin
gdk_gc_set_function(GC, GDK_COPY);
DCOrigin := Offset;
ClipArea := ClipRect;
if (CurrentBrush^.GDIBrushFill = GDK_SOLID) and
(IsBackgroundColor(CurrentBrush^.GDIBrushColor.ColorRef)) then
StyleFillRectangle(Drawable, GC,
CurrentBrush^.GDIBrushColor.ColorRef,
ARect.Left + DCOrigin.X, ARect.Top + DCOrigin.Y,
Width, Height)
Width, Height, @ClipArea)
else
gdk_draw_rectangle(Drawable, GC, 1,
ARect.Left + DCOrigin.X, ARect.Top + DCOrigin.Y,

View File

@ -8525,7 +8525,8 @@ begin
end;
procedure StyleFillRectangle(drawable : PGDKDrawable; GC : PGDKGC;
Color : TColorRef; x, y, width, height : gint);
Color : TColorRef; x, y, width, height : gint;
AClipArea: PGdkRectangle);
var
style: PGTKStyle;
widget: PGTKWidget;
@ -8583,7 +8584,7 @@ begin
end;
if Assigned(Style) then
gtk_paint_flat_box(style, drawable, state, shadow, nil, widget,
gtk_paint_flat_box(style, drawable, state, shadow, AClipArea, widget,
detail, x, y, width, height)
else
gdk_draw_rectangle(drawable, GC, 1, x, y, width, height);

View File

@ -713,7 +713,8 @@ function GetStyleNotebookFrameBorders: TRect;
function GetStyleFormFrameBorders(WithMenu: boolean): TRect;
procedure StyleFillRectangle(drawable: PGDKDrawable; GC: PGDKGC;
Color: TColorRef; x, y, width, height: gint);
Color: TColorRef; x, y, width, height: gint;
AClipArea: PGdkRectangle);
function StyleForegroundColor(Color: TColorRef; DefaultColor: PGDKColor): PGDKColor;
procedure UpdateWidgetStyleOfControl(AWinControl: TWinControl);

View File

@ -750,6 +750,7 @@ procedure TGtk2ThemeServices.Gtk1DrawElement(DC: HDC;
var
DevCtx: TGtkDeviceContext absolute DC;
Area: TGdkRectangle;
ClipArea: TGdkRectangle;
StyleParams: TGtkStyleParams;
i: integer;
RDest: TRect;
@ -768,12 +769,10 @@ begin
DevCtx.TransfNormalize(RDest.Left, RDest.Right);
DevCtx.TransfNormalize(RDest.Top, RDest.Bottom);
Area := GdkRectFromRect(RDest);
end
else if ClipRect <> nil then
Area := GdkRectFromRect(ClipRect^)
else
end else
Area := GdkRectFromRect(R);
ClipArea := DevCtx.ClipRect;
// move to origin
inc(Area.x, StyleParams.Origin.x);
@ -814,93 +813,93 @@ begin
gtk_paint_box(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptBoxGap:
gtk_paint_box_gap(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height,
GapSide, GapX, GapWidth);
gptHLine : gtk_paint_hline(
Style, Window,
State, @Area,
State, @ClipArea,
Widget, PChar(Detail),
Area.x, Area.x + Area.Width, Area.y);
gptVLine : gtk_paint_vline(
Style, Window,
State, @Area,
State, @ClipArea,
Widget, PChar(Detail),
Area.y, Area.y + Area.Height, Area.x);
gptShadow : gtk_paint_shadow(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptFlatBox: gtk_paint_flat_box(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptCheck : gtk_paint_check(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptOption : gtk_paint_option(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptTab : gtk_paint_tab(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptSlider : gtk_paint_slider(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height,
Orientation);
gptHandle : gtk_paint_handle(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height,
Orientation);
gptExpander: gtk_paint_expander(
Style, Window, State,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x + Area.width shr 1, Area.y + Area.height shr 1,
Expander);
gptResizeGrip: gtk_paint_resize_grip(
Style, Window, State,
@Area, Widget,
@ClipArea, Widget,
PChar(Detail), Edge,
Area.x, Area.y,
Area.Width, Area.Height);
gptFocus : gtk_paint_focus(
Style, Window, State,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
Area.x, Area.y,
Area.Width, Area.Height);
gptArrow: gtk_paint_arrow(
Style, Window,
State, Shadow,
@Area, Widget, PChar(Detail),
@ClipArea, Widget, PChar(Detail),
ArrowType, Fill,
Area.x, Area.y, Area.width, Area.height
);

View File

@ -1904,6 +1904,7 @@ var
DevCtx: TGtkDeviceContext absolute DC;
Widget: PGtkWidget;
R: TRect;
ClipArea: TGdkRectangle;
procedure DrawButtonPush;
var
@ -1955,18 +1956,19 @@ var
aStyle := gtk_widget_get_style(Widget)
else
aStyle := GetStyle(lgsButton);
If aStyle = nil then
if aStyle = nil then
aStyle := GetStyle(lgsGTK_Default);
// MG: You can't assign a style to any window. Why it is needed anyway?
//aStyle := gtk_style_attach(gtk_style_ref(aStyle),aDC.Drawable);
if aStyle<>nil then begin
If (Shadow=GTK_SHADOW_NONE) then
if aStyle<>nil then
begin
if (Shadow=GTK_SHADOW_NONE) then
gtk_paint_flat_box(aStyle,aDC.Drawable,
State,
Shadow,
nil,
@ClipArea,
GetStyleWidget(lgsButton),
'button',
R.Left+DCOrigin.X,R.Top+DCOrigin.Y,
@ -1975,7 +1977,7 @@ var
gtk_paint_box(aStyle,aDC.Drawable,
State,
Shadow,
nil,
@ClipArea,
GetStyleWidget(lgsButton),
'button',
R.Left+DCOrigin.X,R.Top+DCOrigin.Y,
@ -2017,28 +2019,30 @@ var
Style := GetStyle(LazGtkStyleMap[IsRadioButton]);
If Style = nil then begin
if Style = nil then
begin
Style := GetStyle(lgsGTK_Default);
If Style <> nil then
if Style <> nil then
Style := gtk_style_attach(gtk_style_ref(Style),aDC.Drawable);
end;
Widget := GetStyleWidget(LazGtkStyleMap[IsRadioButton]);
If Widget = nil then
if Widget = nil then
Widget := GetStyleWidget(lgsDefault);
If Widget <> nil then
if Widget <> nil then
Widget^.Window := aDC.Drawable;
Result := Style <> nil;
If Result then begin
if Result then
begin
if IsRadioButton then
gtk_paint_option(Style,aDC.Drawable, State,
Shadow, nil, Widget, 'radiobutton',
Shadow, @ClipArea, Widget, 'radiobutton',
R.Left+DCOrigin.X,R.Top+DCOrigin.Y,
R.Right-R.Left, R.Bottom-R.Top)
else
gtk_paint_check(Style,aDC.Drawable, State,
Shadow, nil, Widget, 'checkbutton',
Shadow, @ClipArea, Widget, 'checkbutton',
R.Left+DCOrigin.X,R.Top+DCOrigin.Y,
R.Right-R.Left, R.Bottom-R.Top);
end;
@ -2069,6 +2073,7 @@ begin
end else
Widget:=nil;
ClipArea := DevCtx.ClipRect;
case uType of
DFC_CAPTION:
begin //all draw CAPTION commands here
@ -6923,6 +6928,7 @@ var
Left, Top, Width, Height: Integer;
DCOrigin: TPoint;
Brush: PGdiObject;
ClipArea: TGdkRectangle;
begin
Assert(False, Format('trace:> [TGtk2WidgetSet.Rectangle] DC:0x%x, X1:%d, Y1:%d, X2:%d, Y2:%d', [DC, X1, Y1, X2, Y2]));
if not IsValidDC(DC) then Exit(False);
@ -6942,14 +6948,15 @@ begin
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
if not DevCtx.IsNullBrush
then begin
if not DevCtx.IsNullBrush then
begin
ClipArea := DevCtx.ClipRect;
Brush := DevCtx.GetBrush;
if (Brush^.GDIBrushFill = GDK_SOLID)
and (IsBackgroundColor(TColor(Brush^.GDIBrushColor.ColorRef)))
if (Brush^.GDIBrushFill = GDK_SOLID) and
(IsBackgroundColor(TColor(Brush^.GDIBrushColor.ColorRef)))
then
StyleFillRectangle(DevCtx.Drawable, DevCtx.GC, Brush^.GDIBrushColor.ColorRef,
Left+DCOrigin.X, Top+DCOrigin.Y, Width, Height)
Left+DCOrigin.X, Top+DCOrigin.Y, Width, Height, @ClipArea)
else
gdk_draw_rectangle(DevCtx.Drawable, DevCtx.GC, 1,
Left+DCOrigin.X, Top+DCOrigin.Y, Width, Height);