mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 12:23:51 +02:00
cocoa: port some of carbon changes related to regions, port LPtoDP, LPtoDP
git-svn-id: trunk@38776 -
This commit is contained in:
parent
f38f091b55
commit
d7554d8ff4
lcl/interfaces/cocoa
@ -85,7 +85,10 @@ type
|
||||
function ContainsPoint(const P: TPoint): Boolean;
|
||||
procedure SetShape(AShape: HIShapeRef);
|
||||
procedure Clear;
|
||||
function CombineWith(ARegion: TCocoaRegion; CombineMode: TCocoaCombine): Boolean;
|
||||
function CombineWith(ARegion: TCocoaRegion; CombineMode: TCocoaCombine): TCocoaRegionType;
|
||||
procedure Offset(dx, dy: Integer);
|
||||
function GetShapeCopy: HIShapeRef;
|
||||
procedure MakeMutable;
|
||||
public
|
||||
property Shape: HIShapeRef read FShape write SetShape;
|
||||
end;
|
||||
@ -278,8 +281,8 @@ type
|
||||
WindowOfs: TPoint;
|
||||
ViewportOfs: TPoint;
|
||||
|
||||
// isClipped: Boolean;
|
||||
// ClipShape: HIShapeRef;
|
||||
isClipped: Boolean;
|
||||
ClipShape: HIShapeRef;
|
||||
end;
|
||||
|
||||
TGlyphArray = array of NSGlyph;
|
||||
@ -354,6 +357,8 @@ type
|
||||
procedure RestoreDCData(const AData: TCocoaDCData); virtual;
|
||||
procedure SetCGFillping(Ctx: CGContextRef; Width, Height: Integer);
|
||||
procedure RestoreCGFillping(Ctx: CGContextRef; Width, Height: Integer);
|
||||
procedure ApplyTransform(Trans: CGAffineTransform);
|
||||
procedure ClearClipping;
|
||||
public
|
||||
ctx: NSGraphicsContext;
|
||||
constructor Create;
|
||||
@ -389,6 +394,7 @@ type
|
||||
function CGContext: CGContextRef; virtual;
|
||||
procedure SetAntialiasing(AValue: Boolean);
|
||||
|
||||
function GetLogicalOffset: TPoint;
|
||||
function GetClipRect: TRect;
|
||||
function SetClipRegion(AClipRegion: TCocoaRegion; Mode: TCocoaCombine): TCocoaRegionType;
|
||||
function CopyClipRegion(ADstRegion: TCocoaRegion): TCocoaRegionType;
|
||||
@ -451,6 +457,17 @@ begin
|
||||
Result := ABitmap <> 0;
|
||||
end;
|
||||
|
||||
procedure GetWindowViewTranslate(const AWindowOfs, AViewOfs: TPoint; out dx, dy: Integer); inline;
|
||||
begin
|
||||
dx := AViewOfs.x - AWindowOfs.x;
|
||||
dy := AViewOfs.y - AWindowOfs.y;
|
||||
end;
|
||||
|
||||
function isSamePoint(const p1, p2: TPoint): Boolean; inline;
|
||||
begin
|
||||
Result:=(p1.x=p2.x) and (p1.y=p2.y);
|
||||
end;
|
||||
|
||||
{ TCocoaBitmap }
|
||||
|
||||
type
|
||||
@ -1038,6 +1055,11 @@ begin
|
||||
ctx.setShouldAntialias(AValue);
|
||||
end;
|
||||
|
||||
function TCocoaContext.GetLogicalOffset: TPoint;
|
||||
begin
|
||||
GetWindowViewTranslate(WindowOfs, ViewportOfs, Result.X, Result.Y);
|
||||
end;
|
||||
|
||||
function TCocoaContext.GetClipRect: TRect;
|
||||
begin
|
||||
Result := CGRectToRect(CGContextGetClipBoundingBox(CGContext));
|
||||
@ -1045,11 +1067,8 @@ end;
|
||||
|
||||
function TCocoaContext.SetClipRegion(AClipRegion: TCocoaRegion; Mode: TCocoaCombine): TCocoaRegionType;
|
||||
begin
|
||||
if FClipped then
|
||||
begin
|
||||
FClipped := False;
|
||||
ctx.restoreGraphicsState;
|
||||
end;
|
||||
ClearClipping;
|
||||
FClipped := False;
|
||||
|
||||
if not Assigned(AClipRegion) then
|
||||
FClipRegion.Clear
|
||||
@ -1065,8 +1084,8 @@ end;
|
||||
|
||||
function TCocoaContext.CopyClipRegion(ADstRegion: TCocoaRegion): TCocoaRegionType;
|
||||
begin
|
||||
if Assigned(ADstRegion) and ADstRegion.CombineWith(FClipRegion, cc_Copy) then
|
||||
Result := ADstRegion.GetType
|
||||
if Assigned(ADstRegion) then
|
||||
Result := ADstRegion.CombineWith(FClipRegion, cc_Copy)
|
||||
else
|
||||
Result := crt_Error;
|
||||
end;
|
||||
@ -1153,17 +1172,6 @@ begin
|
||||
FText.ForegroundColor := TColor(ColorToRGB(AValue));
|
||||
end;
|
||||
|
||||
procedure GetWindowViewTranslate(const AWindowOfs, AViewOfs: TPoint; out dx, dy: Integer); inline;
|
||||
begin
|
||||
dx := AViewOfs.x - AWindowOfs.x;
|
||||
dy := AViewOfs.y - AWindowOfs.y;
|
||||
end;
|
||||
|
||||
function isSamePoint(const p1, p2: TPoint): Boolean; inline;
|
||||
begin
|
||||
Result:=(p1.x=p2.x) and (p1.y=p2.y);
|
||||
end;
|
||||
|
||||
procedure TCocoaContext.UpdateContextOfs(const AWindowOfs, AViewOfs: TPoint);
|
||||
var
|
||||
dx, dy: Integer;
|
||||
@ -1209,8 +1217,8 @@ begin
|
||||
Result.WindowOfs := FWindowOfs;
|
||||
Result.ViewportOfs := FViewportOfs;
|
||||
|
||||
// Result.isClipped := isClipped;
|
||||
// Result.ClipShape := FClipRegion.GetShapeCopy;
|
||||
Result.isClipped := FClipped;
|
||||
Result.ClipShape := FClipRegion.GetShapeCopy;
|
||||
end;
|
||||
|
||||
procedure TCocoaContext.RestoreDCData(const AData: TCocoaDCData);
|
||||
@ -1302,8 +1310,7 @@ end;
|
||||
|
||||
function TCocoaContext.SaveDC: Integer;
|
||||
begin
|
||||
if FClipped then
|
||||
ctx.restoreGraphicsState;
|
||||
ClearClipping;
|
||||
|
||||
Result := 0;
|
||||
|
||||
@ -1322,8 +1329,7 @@ end;
|
||||
|
||||
function TCocoaContext.RestoreDC(ASavedDC: Integer): Boolean;
|
||||
begin
|
||||
if FClipped then
|
||||
ctx.restoreGraphicsState;
|
||||
ClearClipping;
|
||||
|
||||
Result := False;
|
||||
if (FSavedDCList = nil) or (ASavedDC <= 0) or (ASavedDC > FSavedDCList.Count) then
|
||||
@ -1344,8 +1350,8 @@ begin
|
||||
|
||||
if FClipped then
|
||||
begin
|
||||
FClipped := False;
|
||||
FClipRegion.Shape := HIShapeCreateEmpty;
|
||||
ctx.saveGraphicsState;
|
||||
FClipRegion.Apply(Self);
|
||||
end;
|
||||
|
||||
end;
|
||||
@ -1640,6 +1646,29 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCocoaContext.ApplyTransform(Trans: CGAffineTransform);
|
||||
var
|
||||
T2: CGAffineTransform;
|
||||
begin
|
||||
T2 := CGContextGetCTM(CGContext);
|
||||
// restore old CTM since CTM may changed after the clipping
|
||||
if CGAffineTransformEqualToTransform(Trans, T2) = 0 then
|
||||
CGContextTranslateCTM(CGContext, Trans.a * Trans.tx - T2.a * T2.tx,
|
||||
Trans.d * Trans.ty - T2.d * T2.ty);
|
||||
end;
|
||||
|
||||
procedure TCocoaContext.ClearClipping;
|
||||
var
|
||||
Trans: CGAffineTransform;
|
||||
begin
|
||||
if FClipped then
|
||||
begin
|
||||
Trans := CGContextGetCTM(CGContext);
|
||||
ctx.RestoreGraphicsState;
|
||||
ApplyTransform(Trans);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCocoaContext.DrawCGImage(X, Y, Width, Height: Integer;
|
||||
CGImage: CGImageRef): Boolean;
|
||||
begin
|
||||
@ -2038,12 +2067,21 @@ end;
|
||||
Note: Clipping region is only reducing
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TCocoaRegion.Apply(ADC: TCocoaContext);
|
||||
var
|
||||
DeviceShape: HIShapeRef;
|
||||
begin
|
||||
if ADC = nil then Exit;
|
||||
if ADC.CGContext = nil then Exit;
|
||||
if HIShapeIsEmpty(FShape) or (HIShapeReplacePathInCGContext(FShape, ADC.CGContext) <> noErr) then
|
||||
Exit;
|
||||
CGContextClip(ADC.CGContext);
|
||||
DeviceShape := HIShapeCreateMutableCopy(Shape);
|
||||
try
|
||||
with ADC.GetLogicalOffset do
|
||||
HIShapeOffset(DeviceShape, -X, -Y);
|
||||
if HIShapeIsEmpty(DeviceShape) or (HIShapeReplacePathInCGContext(DeviceShape, ADC.CGContext) <> noErr) then
|
||||
Exit;
|
||||
CGContextClip(ADC.CGContext);
|
||||
finally
|
||||
CFRelease(DeviceShape);
|
||||
end;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -2101,44 +2139,77 @@ begin
|
||||
HIShapeSetEmpty(FShape)
|
||||
end;
|
||||
|
||||
function TCocoaRegion.CombineWith(ARegion: TCocoaRegion; CombineMode: TCocoaCombine): Boolean;
|
||||
function TCocoaRegion.CombineWith(ARegion: TCocoaRegion; CombineMode: TCocoaCombine): TCocoaRegionType;
|
||||
var
|
||||
sh1, sh2: HIShapeRef;
|
||||
const
|
||||
MinCoord=-35000;
|
||||
MaxSize=65000;
|
||||
begin
|
||||
Result:=Assigned(ARegion);
|
||||
if not Assigned(ARegion) then Exit;
|
||||
|
||||
if (CombineMode in [cc_AND, cc_OR, cc_XOR]) and HIShapeIsEmpty(FShape) then
|
||||
CombineMode := cc_COPY;
|
||||
|
||||
case CombineMode of
|
||||
cc_AND: Shape:=HIShapeCreateIntersection(FShape, ARegion.Shape);
|
||||
cc_XOR:
|
||||
begin
|
||||
sh1 := HIShapeCreateUnion(FShape, ARegion.Shape);
|
||||
sh2 := HIShapeCreateIntersection(FShape, ARegion.Shape);
|
||||
Shape := HIShapeCreateDifference(sh1, sh2);
|
||||
CFRelease(sh1); CFRelease(sh2);
|
||||
end;
|
||||
cc_OR: Shape:=HIShapeCreateUnion(FShape, ARegion.Shape);
|
||||
cc_DIFF:
|
||||
begin
|
||||
if HIShapeIsEmpty(FShape) then
|
||||
{HIShapeCreateDifference doesn't work properly if original shape is empty}
|
||||
{to simulate "emptieness" very big shape is created }
|
||||
Shape:=HIShapeCreateWithRect(GetCGRect(MinCoord,MinCoord,MaxSize,MaxSize)); // create clip nothing.
|
||||
|
||||
Shape:=HIShapeCreateDifference(FShape, ARegion.Shape);
|
||||
end;
|
||||
cc_COPY: Shape:=HIShapeCreateCopy(ARegion.Shape);
|
||||
if not Assigned(ARegion) then
|
||||
Result := crt_Error
|
||||
else
|
||||
Result := false;
|
||||
begin
|
||||
if (CombineMode in [cc_AND, cc_OR, cc_XOR]) and HIShapeIsEmpty(FShape) then
|
||||
CombineMode := cc_Copy;
|
||||
|
||||
case CombineMode of
|
||||
cc_AND:
|
||||
begin
|
||||
Shape := HIShapeCreateIntersection(FShape, ARegion.Shape);
|
||||
Result := GetType;
|
||||
end;
|
||||
cc_XOR:
|
||||
begin
|
||||
sh1 := HIShapeCreateUnion(FShape, ARegion.Shape);
|
||||
sh2 := HIShapeCreateIntersection(FShape, ARegion.Shape);
|
||||
Shape := HIShapeCreateDifference(sh1, sh2);
|
||||
CFRelease(sh1);
|
||||
CFRelease(sh2);
|
||||
Result := GetType;
|
||||
end;
|
||||
cc_OR:
|
||||
begin
|
||||
Shape := HIShapeCreateUnion(FShape, ARegion.Shape);
|
||||
Result := GetType;
|
||||
end;
|
||||
cc_DIFF:
|
||||
begin
|
||||
if HIShapeIsEmpty(FShape) then
|
||||
{HIShapeCreateDifference doesn't work properly if original shape is empty}
|
||||
{to simulate "emptieness" very big shape is created }
|
||||
Shape := HIShapeCreateWithRect(GetCGRect(MinCoord, MinCoord, MaxSize, MaxSize)); // create clip nothing.
|
||||
|
||||
Shape := HIShapeCreateDifference(FShape, ARegion.Shape);
|
||||
Result := GetType;
|
||||
end;
|
||||
cc_COPY:
|
||||
begin
|
||||
Shape := HIShapeCreateCopy(ARegion.Shape);
|
||||
Result := GetType;
|
||||
end
|
||||
else
|
||||
Result := crt_Error;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCocoaRegion.Offset(dx, dy: Integer);
|
||||
begin
|
||||
MakeMutable;
|
||||
HIShapeOffset(FShape, dx, dy);
|
||||
end;
|
||||
|
||||
function TCocoaRegion.GetShapeCopy: HIShapeRef;
|
||||
begin
|
||||
Result := HIShapeCreateCopy(Shape);
|
||||
end;
|
||||
|
||||
procedure TCocoaRegion.MakeMutable;
|
||||
begin
|
||||
Shape := HIShapeCreateMutableCopy(Shape);
|
||||
end;
|
||||
|
||||
{ TCocoaPen }
|
||||
|
||||
procedure TCocoaPen.Apply(ADC: TCocoaContext; UseROP2: Boolean = True);
|
||||
|
@ -94,10 +94,10 @@ begin
|
||||
if (Dest = 0) or (Src1 = 0) or (fnCombineMode<RGN_AND) or (fnCombineMode>RGN_COPY) then Exit;
|
||||
if (fnCombineMode <> RGN_COPY) and (Src2 = 0) then Exit;
|
||||
|
||||
TCocoaRegion(Dest).CombineWith(TCocoaRegion(Src1), cc_Copy);
|
||||
Result := CocoaRegionTypeToWin32Map[TCocoaRegion(Dest).CombineWith(TCocoaRegion(Src1), cc_Copy)];
|
||||
|
||||
if fnCombineMode <> RGN_COPY then
|
||||
TCocoaRegion(Dest). CombineWith(TCocoaRegion(Src2), CocoaCombineMode(fnCombineMode));
|
||||
Result := CocoaRegionTypeToWin32Map[TCocoaRegion(Dest).CombineWith(TCocoaRegion(Src2), CocoaCombineMode(fnCombineMode))];
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -331,6 +331,26 @@ begin
|
||||
Ico.Destroy;
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.DPtoLP(DC: HDC; var Points; Count: Integer): BOOL;
|
||||
var
|
||||
ctx: TCocoaContext;
|
||||
P: PPoint;
|
||||
begin
|
||||
Result := False;
|
||||
ctx := CheckDC(DC);
|
||||
if not Assigned(ctx) then Exit;
|
||||
P := @Points;
|
||||
with ctx.GetLogicalOffset do
|
||||
while Count > 0 do
|
||||
begin
|
||||
Dec(Count);
|
||||
dec(P^.X, X);
|
||||
dec(P^.Y, Y);
|
||||
inc(P);
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.DrawFocusRect(DC: HDC; const Rect: TRect): boolean;
|
||||
var
|
||||
ctx: TCocoaContext;
|
||||
@ -1154,6 +1174,34 @@ begin
|
||||
ctx.LineTo(X, Y);
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.LPtoDP(DC: HDC; var Points; Count: Integer): BOOL;
|
||||
var
|
||||
ctx: TCocoaContext;
|
||||
P: PPoint;
|
||||
begin
|
||||
Result := False;
|
||||
ctx := CheckDC(DC);
|
||||
if not Assigned(ctx) then Exit;
|
||||
P := @Points;
|
||||
with ctx.GetLogicalOffset do
|
||||
while Count > 0 do
|
||||
begin
|
||||
Dec(Count);
|
||||
inc(P^.X, X);
|
||||
inc(P^.Y, Y);
|
||||
inc(P);
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.OffsetRgn(RGN: HRGN; nXOffset, nYOffset: Integer): Integer;
|
||||
begin
|
||||
if not (TObject(RGN) is TCocoaRegion) then
|
||||
Exit(ERROR);
|
||||
TCocoaRegion(RGN).Offset(nXOffset, nYOffset);
|
||||
Result := CocoaRegionTypeToWin32Map[TCocoaRegion(RGN).GetType];
|
||||
end;
|
||||
|
||||
function TCocoaWidgetSet.MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean;
|
||||
var
|
||||
ctx: TCocoaContext;
|
||||
|
@ -66,7 +66,7 @@ function DeleteDC(hDC: HDC): Boolean; override;
|
||||
function DeleteObject(GDIObject: HGDIOBJ): Boolean; override;
|
||||
function DestroyCaret(Handle : HWND): Boolean; override;
|
||||
function DestroyIcon(Handle: HICON): Boolean; override;
|
||||
{function DPtoLP(DC: HDC; var Points; Count: Integer): BOOL; override;}
|
||||
function DPtoLP(DC: HDC; var Points; Count: Integer): BOOL; override;
|
||||
function DrawFocusRect(DC: HDC; const Rect: TRect): boolean; override;
|
||||
function DrawEdge(DC: HDC; var Rect: TRect; edge: Cardinal; grfFlags: Cardinal): Boolean; override;
|
||||
//function DrawText(DC: HDC; Str: PChar; Count: Integer; var ARect: TRect; Flags: Cardinal): Integer; override;
|
||||
@ -79,7 +79,7 @@ procedure EnterCriticalSection(var CritSection: TCriticalSection); override;
|
||||
function EnumFontFamiliesEx(DC: HDC; lpLogFont: PLogFont; Callback: FontEnumExProc; Lparam: LParam; Flags: dword): longint; override;
|
||||
function EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool; override;
|
||||
{function ExcludeClipRect(dc: hdc; Left, Top, Right, Bottom : Integer) : Integer; override;}
|
||||
function ExtSelectClipRGN(dc: hdc; rgn : hrgn; Mode : Longint) : Integer; override;
|
||||
function ExtSelectClipRGN(dc: hdc; rgn : hrgn; Mode : Longint): Integer; override;
|
||||
function ExtCreatePen(dwPenStyle, dwWidth: DWord; const lplb: TLogBrush; dwStyleCount: DWord; lpStyle: PDWord): HPEN; override;
|
||||
function ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean; override;
|
||||
|
||||
@ -139,6 +139,9 @@ function IsWindowVisible(Handle: HWND): boolean; override;
|
||||
|
||||
procedure LeaveCriticalSection(var CritSection: TCriticalSection); override;
|
||||
function LineTo(DC: HDC; X, Y: Integer): Boolean; override;
|
||||
function LPtoDP(DC: HDC; var Points; Count: Integer): BOOL; override;
|
||||
|
||||
function OffsetRgn(RGN: HRGN; nXOffset, nYOffset: Integer): Integer; override;
|
||||
|
||||
{function MessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: Cardinal): integer; override;}
|
||||
function MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean; override;
|
||||
|
Loading…
Reference in New Issue
Block a user