From f1cea2e7e78e00596688a866d5f5942764bc4c52 Mon Sep 17 00:00:00 2001 From: dmitry Date: Tue, 18 Aug 2009 20:01:11 +0000 Subject: [PATCH] carbon: improve clipping operations: proper implementation of IntersectClipRect, ExcludeClipRect, SaveDC, RestoreDC functions git-svn-id: trunk@21297 - --- lcl/interfaces/carbon/carboncanvas.pp | 27 +++++++++++---- lcl/interfaces/carbon/carbongdiobjects.pp | 3 ++ lcl/interfaces/carbon/carbonprivatecommon.inc | 4 +++ lcl/interfaces/carbon/carbonwinapi.inc | 34 ++++--------------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lcl/interfaces/carbon/carboncanvas.pp b/lcl/interfaces/carbon/carboncanvas.pp index 8afb4cc064..12191db3c9 100644 --- a/lcl/interfaces/carbon/carboncanvas.pp +++ b/lcl/interfaces/carbon/carboncanvas.pp @@ -84,7 +84,6 @@ type FSavedDCList: TFPObjectList; FTextFractional: Boolean; - fLastClipRegion : TCarbonRegion; isClipped : Boolean; procedure SetBkColor(AValue: TColor); @@ -99,6 +98,7 @@ type function GetSize: TPoint; virtual; abstract; function SaveDCData: TCarbonDCData; virtual; procedure RestoreDCData(const AData: TCarbonDCData); virtual; + procedure ExcludeClipRect(Left, Top, Right, Bottom: Integer); public constructor Create; destructor Destroy; override; @@ -119,7 +119,6 @@ type procedure DrawGrid(const ARect: TRect; DX, DY: Integer); procedure Ellipse(X1, Y1, X2, Y2: Integer); - procedure ExcludeClipRect(Left, Top, Right, Bottom: Integer); function ExtTextOut(X, Y: Integer; Options: Longint; Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean; procedure FillRect(Rect: TRect; Brush: TCarbonBrush); procedure Frame(X1, Y1, X2, Y2: Integer); @@ -144,8 +143,6 @@ type public property Size: TPoint read GetSize; - property LastClipRegion: TCarbonRegion read fLastClipRegion; - property CurrentFont: TCarbonFont read FCurrentFont write SetCurrentFont; property CurrentBrush: TCarbonBrush read FCurrentBrush write SetCurrentBrush; property CurrentPen: TCarbonPen read FCurrentPen write SetCurrentPen; @@ -492,6 +489,8 @@ end; ------------------------------------------------------------------------------} function TCarbonDeviceContext.SaveDC: Integer; begin + if isClipped then CGContextRestoreGState(CGContext); // clip rect is on top of the state stack! + Result := 0; if CGContext = nil then begin @@ -507,6 +506,13 @@ begin {$IFDEF VerboseCanvas} DebugLn('TCarbonDeviceContext.SaveDC Result: ', DbgS(Result)); {$ENDIF} + + if isClipped then + begin + // should clip rect be restored? + isClipped:=false; + FClipRegion.Shape := HIShapeCreateEmpty; + end; end; {------------------------------------------------------------------------------ @@ -518,6 +524,8 @@ end; ------------------------------------------------------------------------------} function TCarbonDeviceContext.RestoreDC(ASavedDC: Integer): Boolean; begin + if isClipped then CGContextRestoreGState(CGContext); + Result := False; if (FSavedDCList = nil) or (ASavedDC <= 0) or (ASavedDC > FSavedDCList.Count) then begin @@ -549,6 +557,14 @@ begin {$ENDIF} if FSavedDCList.Count = 0 then FreeAndNil(FSavedDCList); + + + if isClipped then + begin + // should clip be restored? + isClipped:=false; + FClipRegion.Shape := HIShapeCreateEmpty; + end; end; {------------------------------------------------------------------------------ @@ -1468,8 +1484,7 @@ begin isClipped := false; CGContextRestoreGState(CGContext); end; - fLastClipRegion := AClipRegion; - + if not Assigned(AClipRegion) then begin HIShapeSetEmpty(FClipRegion.Shape); diff --git a/lcl/interfaces/carbon/carbongdiobjects.pp b/lcl/interfaces/carbon/carbongdiobjects.pp index 4042231908..322d4b1311 100644 --- a/lcl/interfaces/carbon/carbongdiobjects.pp +++ b/lcl/interfaces/carbon/carbongdiobjects.pp @@ -801,6 +801,9 @@ begin else begin Result := LCLType.ComplexRegion; + if (CombineMode in [RGN_AND, RGN_OR, RGN_XOR]) and HIShapeIsEmpty(FShape) then + CombineMode := RGN_COPY; + case CombineMode of RGN_AND: Shape:=HIShapeCreateIntersection(FShape, ARegion.Shape); RGN_XOR: diff --git a/lcl/interfaces/carbon/carbonprivatecommon.inc b/lcl/interfaces/carbon/carbonprivatecommon.inc index 3a9a4aa1e7..395003b086 100644 --- a/lcl/interfaces/carbon/carbonprivatecommon.inc +++ b/lcl/interfaces/carbon/carbonprivatecommon.inc @@ -101,6 +101,10 @@ begin Dispose(AStruct); end; if AWidget.HasCaret then DrawCaret; + + // resetting clip region for the next paint + TCarbonControlContext(AWidget.Context).SetClipRegion(nil, 0); + finally FreeAndNil(AWidget.Context); diff --git a/lcl/interfaces/carbon/carbonwinapi.inc b/lcl/interfaces/carbon/carbonwinapi.inc index 0927ccceeb..b52cc921c7 100644 --- a/lcl/interfaces/carbon/carbonwinapi.inc +++ b/lcl/interfaces/carbon/carbonwinapi.inc @@ -904,18 +904,8 @@ end; function TCarbonWidgetSet.ExcludeClipRect(DC: HDC; Left, Top, Right, Bottom: Integer): Integer; begin - Result := ERROR; - - {$IFDEF VerboseWinAPI} - DebugLn('TCarbonWidgetSet.ExcludeClipRect DC: ' + DbgS(DC) + ' R: ' + - DbgS(Classes.Rect(Left, Top, Right, Bottom))); - {$ENDIF} - - if not CheckDC(DC, 'ExcludeClipRect') then Exit; - - TCarbonDeviceContext(DC).ExcludeClipRect(Left, Top, Right, Bottom); - - Result := COMPLEXREGION; + //todo: remove, as unused + Result := inherited ExcludeClipRect(DC, Left, Top, Right, Bottom); end; function TCarbonWidgetSet.ExtCreatePen(dwPenStyle, dwWidth: DWord; @@ -2249,19 +2239,8 @@ end; function TCarbonWidgetSet.IntersectClipRect(DC: HDC; Left, Top, Right, Bottom: Integer): Integer; begin - Result := ERROR; - - {$IFDEF VerboseWinAPI} - DebugLn('TCarbonWidgetSet.IntersectClipRect DC: ' + DbgS(DC) + ' R: ' + - DbgS(Classes.Rect(Left, Top, Right, Bottom))); - {$ENDIF} - - if not CheckDC(DC, 'IntersectClipRect') then Exit; - - CGContextClipToRect(TCarbonContext(DC).CGContext, - RectToCGRect(Classes.Rect(Left, Top, Right, Bottom))); - - Result := COMPLEXREGION; + //todo: remove, as not used + Result := inherited IntersectClipRect(DC, Left, Top, Right, Bottom); end; {------------------------------------------------------------------------------ @@ -2461,10 +2440,10 @@ function TCarbonWidgetSet.MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean; begin Result := False; - {$IFDEF VerboseWinAPI} + {.$IFDEF VerboseWinAPI} DebugLn('TCarbonWidgetSet.MoveWindowOrgEx DC: ' + DbgS(DC) + ' ' + DbgS(DX) + ', ' + DbgS(DY)); - {$ENDIF} + {.$ENDIF} if not CheckDC(DC, 'MoveWindowOrgEx') then Exit; @@ -3447,7 +3426,6 @@ const SName = 'TCarbonWidgetSet.StretchMaskBlt'; begin Result := False; - {$IFDEF VerboseWinAPI} DebugLn('TCarbonWidgetSet.StretchMaskBlt DestDC: ' + DbgS(DestDC) + ' SrcDC: ', DbgS(SrcDC) + ' X: ' + DbgS(X) + ' Y: ' + DbgS(Y),