*Hello, Vincent!*
Here are patches for mentioned files. It solves problem with GTK2 crash
in Canvas.Pie (that is working without any troubles in GTK1). Also some
things were changed in graphmath.pp for PolyBezierArcPoints.
I had sent it before, but not as a patch - sorry for that. I am really
not a guru and only now start to teach myself what is diff and how patch
is working.
*Regards, Alexey.*
--- ./graphmath.pp 2006-10-04 00:10:44.000000000 +0400
+++ ./graphmath.pp.new 2007-04-11 22:18:35.000000000 +0400
@@ -568,10 +568,11 @@
end;
If Angle2 = 0 then
exit;
- If (not Assigned(Points)) or (Count <= 0) then begin
- Points := AllocMem(SizeOf(TPoint));
- Count := 0;
- end;
+//Not need to check this - it will be checked in Bezier2Polyline
+// If (not Assigned(Points)) or (Count <= 0) then begin
+// Points := AllocMem(SizeOf(TPoint));
+// Count := 0;
+// end;
Arc2Bezier(X, Y, Width, Height, Angle1, Angle2, Rotation, B);
Bezier2Polyline(B,Points,Count);
end;
@@ -926,52 +927,61 @@
------------------------------------------------------------------------------}
Procedure PolyBezierArcPoints(X, Y, Width, Height : Longint; Angle1, Angle2,
Rotation : Extended; var Points : PPoint; var Count : Longint);
-var
- I,K : Integer;
- FullAngle : Extended;
- TST : Boolean;
-begin
- If Abs(Angle2) > 360*16 then begin
- Angle2 := 360*16;
- Angle1 := 0;
- end;
- If Abs(Rotation) > 360*16 then
- Rotation := Frac(Rotation / 360*16)*360*16;
- FullAngle := Angle1 + Angle2;
- K := Ceil(ABS(Angle2/16) / 45);
- Count := 0;
- If Assigned(Points) then
- Try
- ReallocMem(Points, 0)
- Finally
- Points := nil;
- end;
- If Angle2 > 45*16 then
- Angle2 := 45*16
- else
- If Angle2 < -45*16 then
- Angle2 := -45*16;
- For I := 0 to K - 1 do begin
- BezierArcPoints(X, Y, Width,Height,Angle1,Angle2,Rotation,Points,Count);
- Angle1 := Angle1 + Angle2;
- If Angle2 > 0 then
- TST := (FullAngle - Angle1) > 45*16
- else
- TST := ABS(FullAngle - Angle1) > 45*16;
- If TST then begin
- If Angle2 > 0 then
- Angle2 := 45*16
- else
- Angle2 := -45*16;
- end
- else begin
- If Angle2 > 0 then
- Angle2 := FullAngle - Angle1
- else
- Angle2 := -(FullAngle - Angle1);
- end;
- end;
-end;
+Const
+ Deg16Qnt :Extended = 360.0*16.0;
+ Arc45DegStep:Extended = 45.0*16.0;
+Var
+ B :TBezier;
+ dFullAngle :Extended;
+ dTmpAngle1 :Extended;
+ dDirection :Double;
+// TST :Boolean;
+//-----------------------------------------------------------------------------
+// Function Return2Bounds (Const FAngle:Extended):Extended - checking paremeter
+// to be in 360*16 bounds
+//-----------------------------------------------------------------------------
+Function Return2Bounds (Const FAngle:Extended):Extended;
+Begin
+ Result:=FAngle;
+ While Abs(Result)>Deg16Qnt Do Begin Result:=Frac(Result / Deg16Qnt) *
Deg16Qnt; End;
+End;
+
+begin
+//Checking if our parameters are in Abs(360 * 16) bounds
+ Angle1 :=Return2Bounds(Angle1);
+ Angle2 :=Return2Bounds(Angle2);
+ Rotation :=Return2Bounds(Rotation);
+//Checking the assigment of Points and cleaning it if needed
+ if Assigned(Points) then
+ Try
+ ReallocMem(Points, 0)
+ Finally
+ Points := nil;
+ End;
+//Calculating FullAngle
+ dFullAngle := Abs (Angle2);
+//If dFullAngle is enough to draw somesing - do it
+ if dFullAngle>0.0 then Begin
+ dDirection := Sign(Angle2);
+ Count := 0;
+//Recursively breaking the Arc into Arcs of 45 degrees or less
+ dTmpAngle1 := Angle1;
+ While(dFullAngle>Arc45DegStep) Do Begin
+// BezierArcPoints(X, Y,
Width,Height,dTmpAngle1,dDirection*Arc45DegStep,Rotation,Points,Count);
+ Arc2Bezier(X, Y, Width, Height, dTmpAngle1, dDirection*Arc45DegStep,
Rotation, B);
+ Bezier2Polyline(B,Points,Count);
+
+//Increasing dTmpAngle1 by dDirection*Arc45DegStep and checking Angle1 to be
in 360*16 bounds
+ dTmpAngle1 := dTmpAngle1 + dDirection*Arc45DegStep;
+ dTmpAngle1 := Return2Bounds(dTmpAngle1);
+//Decreasing dFullAngle by 45*16
+ dFullAngle := dFullAngle - Arc45DegStep;
+ End;//While(dFullAngle>Arc45DegStep) Do
+// BezierArcPoints(X, Y,
Width,Height,dTmpAngle1,dDirection*dFullAngle,Rotation,Points,Count);
+ Arc2Bezier(X, Y, Width, Height, dTmpAngle1, dDirection*dFullAngle,
Rotation, B);
+ Bezier2Polyline(B,Points,Count);
+ End;//if dFullAngle>MinAngleStep then
+End;
{------------------------------------------------------------------------------
Method: Quadrant
--- ./intfbaselcl.inc 2007-03-24 19:17:33.000000000 +0300
+++ ./intfbaselcl.inc.new 2007-04-11 22:35:33.000000000 +0400
@@ -532,12 +532,15 @@
Points := nil;
Count := 0;
PolyBezierArcPoints(x1, y1, x2 - x1, y2 - y1, Angle1, Angle2, 0, Points,
Count);
- Inc(Count,2);
- ReallocMem(Points, Count*SizeOf(TPoint));
- Points[Count - 2] := CenterPoint(Rect(x1, y1, x2, y2));
- Points[Count - 1] := Points[0];
- Polygon(DC, Points, Count, True);
- ReallocMem(Points, 0);
+//Checking if Pounts array is filled and Count>0 (fix crash in GTK2)
+ if Count>0 then Begin
+ Inc(Count,2);
+ ReallocMem(Points, Count*SizeOf(TPoint));
+ Points[Count - 2] := CenterPoint(Rect(x1, y1, x2, y2));
+ Points[Count - 1] := Points[0];
+ Polygon(DC, Points, Count, True);
+ ReallocMem(Points, 0);
+ End;
Result := True;
end;