mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-01 23:20:26 +02:00
TAChart: Add clsRoundRect and clsRoundSides to TChartLabelShape enumeration
git-svn-id: trunk@38579 -
This commit is contained in:
parent
5417050ae2
commit
c7d446ef38
@ -31,6 +31,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Init;
|
constructor Init;
|
||||||
procedure Add(const APoint: TPoint);
|
procedure Add(const APoint: TPoint);
|
||||||
|
procedure AddNoDup(const APoint: TPoint); inline;
|
||||||
function LastPoint: TPoint; inline;
|
function LastPoint: TPoint; inline;
|
||||||
function Purge: TPointArray; inline;
|
function Purge: TPointArray; inline;
|
||||||
end;
|
end;
|
||||||
@ -42,7 +43,7 @@ type
|
|||||||
constructor InitBoundingBox(AX1, AY1, AX2, AY2: Integer);
|
constructor InitBoundingBox(AX1, AY1, AX2, AY2: Integer);
|
||||||
public
|
public
|
||||||
function GetPoint(AParametricAngle: Double): TDoublePoint;
|
function GetPoint(AParametricAngle: Double): TDoublePoint;
|
||||||
procedure RadialPieToPolygon(
|
procedure SliceToPolygon(
|
||||||
AAngleStart, AAngleLength: Double; AStep: Integer; var APoly: TPolygon);
|
AAngleStart, AAngleLength: Double; AStep: Integer; var APoly: TPolygon);
|
||||||
function TesselateRadialPie(
|
function TesselateRadialPie(
|
||||||
AAngleStart, AAngleLength: Double; AStep: Integer): TPointArray;
|
AAngleStart, AAngleLength: Double; AStep: Integer): TPointArray;
|
||||||
@ -82,8 +83,10 @@ function RectIntersectsRect(
|
|||||||
function RotatePoint(const APoint: TDoublePoint; AAngle: Double): TDoublePoint; overload;
|
function RotatePoint(const APoint: TDoublePoint; AAngle: Double): TDoublePoint; overload;
|
||||||
function RotatePoint(const APoint: TPoint; AAngle: Double): TPoint; overload;
|
function RotatePoint(const APoint: TPoint; AAngle: Double): TPoint; overload;
|
||||||
function RotatePointX(AX, AAngle: Double): TPoint;
|
function RotatePointX(AX, AAngle: Double): TPoint;
|
||||||
function RotateRect(const ARect: TRect; AAngle: Double): TPointArray;
|
|
||||||
function RoundPoint(APoint: TDoublePoint): TPoint;
|
function RoundPoint(APoint: TDoublePoint): TPoint;
|
||||||
|
function TesselateRect(const ARect: TRect): TPointArray;
|
||||||
|
function TesselateEllipse(const ABounds: TRect; AStep: Integer): TPointArray;
|
||||||
|
function TesselateRoundRect(const ARect: TRect; ARadius, AStep: Integer): TPointArray;
|
||||||
|
|
||||||
operator +(const A: TPoint; B: TSize): TPoint; overload; inline;
|
operator +(const A: TPoint; B: TSize): TPoint; overload; inline;
|
||||||
operator +(const A, B: TPoint): TPoint; overload; inline;
|
operator +(const A, B: TPoint): TPoint; overload; inline;
|
||||||
@ -430,9 +433,13 @@ begin
|
|||||||
Result.Y := Round(sa * AX);
|
Result.Y := Round(sa * AX);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RotateRect(const ARect: TRect; AAngle: Double): TPointArray;
|
function RoundPoint(APoint: TDoublePoint): TPoint;
|
||||||
var
|
begin
|
||||||
i: Integer;
|
Result.X := Round(APoint.X);
|
||||||
|
Result.Y := Round(APoint.Y);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TesselateRect(const ARect: TRect): TPointArray;
|
||||||
begin
|
begin
|
||||||
SetLength(Result, 4);
|
SetLength(Result, 4);
|
||||||
with ARect do begin
|
with ARect do begin
|
||||||
@ -441,14 +448,54 @@ begin
|
|||||||
Result[2] := BottomRight;
|
Result[2] := BottomRight;
|
||||||
Result[3] := Point(Right, Top);
|
Result[3] := Point(Right, Top);
|
||||||
end;
|
end;
|
||||||
for i := 0 to High(Result) do
|
|
||||||
Result[i] := RotatePoint(Result[i], AAngle);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RoundPoint(APoint: TDoublePoint): TPoint;
|
function TesselateEllipse(const ABounds: TRect; AStep: Integer): TPointArray;
|
||||||
|
var
|
||||||
|
e: TEllipse;
|
||||||
|
p: TPolygon;
|
||||||
begin
|
begin
|
||||||
Result.X := Round(APoint.X);
|
with ABounds do
|
||||||
Result.Y := Round(APoint.Y);
|
e.InitBoundingBox(Left, Top, Right, Bottom);
|
||||||
|
p.Init;
|
||||||
|
e.SliceToPolygon(0, 2 * Pi, AStep, p);
|
||||||
|
Result := p.Purge;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TesselateRoundRect(
|
||||||
|
const ARect: TRect; ARadius, AStep: Integer): TPointArray;
|
||||||
|
var
|
||||||
|
e: TEllipse;
|
||||||
|
p: TPolygon;
|
||||||
|
begin
|
||||||
|
with ARect do begin
|
||||||
|
if Min(Right - Left, Bottom - Top) < 2 * ARadius then exit(nil);
|
||||||
|
|
||||||
|
p.Init;
|
||||||
|
e.FR := DoublePoint(ARadius, ARadius);
|
||||||
|
|
||||||
|
p.AddNoDup(Point(Right, Bottom - ARadius));
|
||||||
|
p.AddNoDup(Point(Right, Top + ARadius));
|
||||||
|
e.FC := DoublePoint(Right - ARadius, Top + ARadius);
|
||||||
|
e.SliceToPolygon(0, Pi / 2, AStep, p);
|
||||||
|
|
||||||
|
p.AddNoDup(Point(Right - ARadius, Top));
|
||||||
|
p.AddNoDup(Point(Left + ARadius, Top));
|
||||||
|
e.FC := DoublePoint(Left + ARadius, Top + ARadius);
|
||||||
|
e.SliceToPolygon(Pi / 2, Pi / 2, AStep, p);
|
||||||
|
|
||||||
|
p.AddNoDup(Point(Left, Top + ARadius));
|
||||||
|
p.AddNoDup(Point(Left, Bottom - ARadius));
|
||||||
|
e.FC := DoublePoint(Left + ARadius, Bottom - ARadius);
|
||||||
|
e.SliceToPolygon(Pi, Pi / 2, AStep, p);
|
||||||
|
|
||||||
|
p.AddNoDup(Point(Left + ARadius, Bottom));
|
||||||
|
p.AddNoDup(Point(Right - ARadius, Bottom));
|
||||||
|
e.FC := DoublePoint(Right - ARadius, Bottom - ARadius);
|
||||||
|
e.SliceToPolygon(Pi * 3/2, Pi / 2, AStep, p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := p.Purge;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
operator + (const A: TPoint; B: TSize): TPoint;
|
operator + (const A: TPoint; B: TSize): TPoint;
|
||||||
@ -554,6 +601,12 @@ begin
|
|||||||
FCount += 1;
|
FCount += 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPolygon.AddNoDup(const APoint: TPoint);
|
||||||
|
begin
|
||||||
|
if (FCount = 0) or (LastPoint <> APoint) then
|
||||||
|
Add(APoint);
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TPolygon.Init;
|
constructor TPolygon.Init;
|
||||||
begin
|
begin
|
||||||
FCount := 0;
|
FCount := 0;
|
||||||
@ -589,7 +642,7 @@ begin
|
|||||||
FR.Y := Abs(AY1 - AY2) / 2;
|
FR.Y := Abs(AY1 - AY2) / 2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TEllipse.RadialPieToPolygon(
|
procedure TEllipse.SliceToPolygon(
|
||||||
AAngleStart, AAngleLength: Double; AStep: Integer; var APoly: TPolygon);
|
AAngleStart, AAngleLength: Double; AStep: Integer; var APoly: TPolygon);
|
||||||
var
|
var
|
||||||
lastAngle: Double;
|
lastAngle: Double;
|
||||||
@ -644,7 +697,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
Rec(tprev, tlast);
|
Rec(tprev, tlast);
|
||||||
Add(tlast);
|
Add(tlast);
|
||||||
SafeAddPoint(RoundPoint(FC), 0);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Represent the ellipse sector with a polygon on an integer grid.
|
// Represent the ellipse sector with a polygon on an integer grid.
|
||||||
@ -655,7 +707,8 @@ var
|
|||||||
resultPoly: TPolygon;
|
resultPoly: TPolygon;
|
||||||
begin
|
begin
|
||||||
resultPoly.Init;
|
resultPoly.Init;
|
||||||
RadialPieToPolygon(AAngleStart, AAngleLength, AStep, resultPoly);
|
SliceToPolygon(AAngleStart, AAngleLength, AStep, resultPoly);
|
||||||
|
resultPoly.AddNoDup(RoundPoint(FC));
|
||||||
Result := resultPoly.Purge;
|
Result := resultPoly.Purge;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ type
|
|||||||
property Top default DEF_LABEL_MARGIN_Y;
|
property Top default DEF_LABEL_MARGIN_Y;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TChartLabelShape = (clsRectangle, clsEllipse);
|
TChartLabelShape = (clsRectangle, clsEllipse, clsRoundRect, clsRoundSide);
|
||||||
|
|
||||||
TChartTextElement = class(TChartElement)
|
TChartTextElement = class(TChartElement)
|
||||||
strict private
|
strict private
|
||||||
@ -349,25 +349,29 @@ end;
|
|||||||
|
|
||||||
function TChartTextElement.GetLabelPolygon(
|
function TChartTextElement.GetLabelPolygon(
|
||||||
ADrawer: IChartDrawer; ASize: TPoint): TPointArray;
|
ADrawer: IChartDrawer; ASize: TPoint): TPointArray;
|
||||||
|
const
|
||||||
|
STEP = 3;
|
||||||
var
|
var
|
||||||
e: TEllipse;
|
|
||||||
a: Double;
|
a: Double;
|
||||||
i: Integer;
|
|
||||||
b: TRect;
|
b: TRect;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
a := GetLabelAngle;
|
|
||||||
b := GetBoundingBox(ADrawer, ASize);
|
b := GetBoundingBox(ADrawer, ASize);
|
||||||
case Shape of
|
case Shape of
|
||||||
clsRectangle:
|
clsRectangle:
|
||||||
Result := RotateRect(b, a);
|
Result := TesselateRect(b);
|
||||||
clsEllipse: begin
|
clsEllipse:
|
||||||
e.InitBoundingBox(b.Left, b.Top, b.Right, b.Bottom);
|
Result := TesselateEllipse(b, STEP);
|
||||||
Result := e.TesselateRadialPie(0, 2 * Pi, 3);
|
clsRoundRect:
|
||||||
SetLength(Result, Length(Result) - 1);
|
Result := TesselateRoundRect(
|
||||||
for i := 0 to High(Result) do
|
b, Min(b.Right - b.Left, b.Bottom - b.Top) div 3, STEP);
|
||||||
Result[i] := RotatePoint(Result[i], a);
|
clsRoundSide:
|
||||||
end;
|
Result := TesselateRoundRect(
|
||||||
|
b, Min(b.Right - b.Left, b.Bottom - b.Top) div 2, STEP);
|
||||||
end;
|
end;
|
||||||
|
a := GetLabelAngle;
|
||||||
|
for i := 0 to High(Result) do
|
||||||
|
Result[i] := RotatePoint(Result[i], a);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TChartTextElement.GetLinkPen: TChartPen;
|
function TChartTextElement.GetLinkPen: TChartPen;
|
||||||
|
Loading…
Reference in New Issue
Block a user