Author: Nik Ozniev
Simple function returning rotated region. Pprocedure doing the same with source
region.
Answer:
It's the simple function returning new region rotated to the angle that you want
around the source region. Source region doesn't change.
The second procedure does the same with source region without creating new region.
I hope this will be useful.
Comments are provided along the code
1
2 function _RotateRgn(ARgn: HRGN; ADegree: Real): HRGN;
3 var
4 wXFORM: XFORM; // transformation structure, see Windows API
5 kRgnD: DWord; // count of RGNDATA structures in region
6 RgnData: PRgnData; // pointer to region data
7 Rt: TRect;
8 kX, kY: Integer;
9 begin
10 if (ARgn = 0) or (ADegree = 0) then
11 Exit;
12
13 // Get region's surrounding rectangular
14 GetRgnBox(ARgn, Rt);
15
16 // Move source region so that the centre of its surrounding rectangular
17 // goes to the left top corner of a window
18 kX := Rt.Left + (Rt.Right - Rt.Left) div 2;
19 kY := Rt.Top + (Rt.Bottom - Rt.Top) div 2;
20 OffsetRgn(ARgn, -kX, -kY);
21
22 // Fill XFORM according to task (rotate region)
23 FillChar(wXFORM, SizeOf(wXFORM), #0);
24 wXFORM.eM11 := Cos(ADegree / 180 * pi);
25 wXFORM.eM12 := -Sin(ADegree / 180 * pi);
26 wXFORM.eM21 := -wXFORM.eM12;
27 wXFORM.eM22 := wXFORM.eM11;
28
29 // Prepare buffer to store region data
30 kRgnD := GetRegionData(ARgn, 0, nil);
31 GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
32 // ..and fill the buffer with region's data
33 GetRegionData(ARgn, kRgnD, RgnData);
34 // ..move source region to its initial position
35 OffsetRgn(ARgn, kX, kY);
36
37 // Create output region using data in the buffer and transformation wXFORM
38 Result := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
39 // Move output region on a place of source region
40 OffsetRgn(Result, kX, kY);
41 FreeMem(RgnData);
42 end;
43
44 procedure _RotateRgnEx(var ARgn: HRGN; ADegree: Real);
45 var
46 wXFORM: XFORM; // transformation structure, see Windows API
47 kRgnD: DWord; // count of RGNDATA structures in region
48 RgnData: PRgnData; // pointer to region data
49 Rt: TRect;
50 kX, kY: Integer;
51 begin
52 if (ARgn = 0) or (ADegree = 0) then
53 Exit;
54
55 // Get region's surrounding rectangular
56 GetRgnBox(ARgn, Rt);
57
58 // Move source region so that the centre of its surrounding rectangular
59 // goes to the left top corner of a window
60 kX := Rt.Left + (Rt.Right - Rt.Left) div 2;
61 kY := Rt.Top + (Rt.Bottom - Rt.Top) div 2;
62 OffsetRgn(ARgn, -kX, -kY);
63
64 // Fill XFORM according to task (rotate region)
65 FillChar(wXFORM, SizeOf(wXFORM), #0);
66 wXFORM.eM11 := Cos(ADegree / 180 * pi);
67 wXFORM.eM12 := -Sin(ADegree / 180 * pi);
68 wXFORM.eM21 := -wXFORM.eM12;
69 wXFORM.eM22 := wXFORM.eM11;
70
71 // Prepare buffer to store region data
72 kRgnD := GetRegionData(ARgn, 0, nil);
73 GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
74 // ..and fill the buffer with region's data
75 GetRegionData(ARgn, kRgnD, RgnData);
76 // ..delete source region
77 DeleteObject(ARgn);
78
79 // Create new region using data in the buffer and transformation wXFORM
80 ARgn := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
81 // Move output region to the origin place
82 OffsetRgn(ARgn, kX, kY);
83 FreeMem(RgnData);
84 end;
|