You've already forked lazarus-ccr
fpvectorial: Reworks the brush and pen design to be more efficient
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1589 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -45,6 +45,17 @@ type
|
|||||||
Red, Green, Blue, Alpha: Byte;
|
Red, Green, Blue, Alpha: Byte;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TvPen = record
|
||||||
|
Color: TvColor;
|
||||||
|
Style: TFPPenStyle;
|
||||||
|
Width: Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TvBrush = record
|
||||||
|
Color: TvColor;
|
||||||
|
Style: TFPBrushStyle;
|
||||||
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
FPValphaTransparent = $00;
|
FPValphaTransparent = $00;
|
||||||
FPValphaOpaque = $FF;
|
FPValphaOpaque = $FF;
|
||||||
@ -59,7 +70,7 @@ type
|
|||||||
P3DPoint = ^T3DPoint;
|
P3DPoint = ^T3DPoint;
|
||||||
|
|
||||||
TSegmentType = (
|
TSegmentType = (
|
||||||
st2DLine, st2DBezier,
|
st2DLine, st2DLineWithPen, st2DBezier,
|
||||||
st3DLine, st3DBezier, stMoveTo);
|
st3DLine, st3DBezier, stMoveTo);
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -75,10 +86,6 @@ type
|
|||||||
// Fields for linking the list
|
// Fields for linking the list
|
||||||
Previous: TPathSegment;
|
Previous: TPathSegment;
|
||||||
Next: TPathSegment;
|
Next: TPathSegment;
|
||||||
// Data fields
|
|
||||||
PenColor: TvColor;
|
|
||||||
PenStyle: TFPPenStyle;
|
|
||||||
PenWidth: Integer;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -93,6 +100,11 @@ type
|
|||||||
X, Y: Double;
|
X, Y: Double;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
T2DSegmentWithPen = class(T2DSegment)
|
||||||
|
public
|
||||||
|
Pen: TvPen;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
In Bezier segments, we remain using the X and Y coordinates for the ending point.
|
In Bezier segments, we remain using the X and Y coordinates for the ending point.
|
||||||
The starting point is where the previous segment ended, so that the intermediary
|
The starting point is where the previous segment ended, so that the intermediary
|
||||||
@ -124,6 +136,9 @@ type
|
|||||||
Points: TPathSegment; // Beginning of the double-linked list
|
Points: TPathSegment; // Beginning of the double-linked list
|
||||||
PointsEnd: TPathSegment; // End of the double-linked list
|
PointsEnd: TPathSegment; // End of the double-linked list
|
||||||
CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next
|
CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next
|
||||||
|
Pen: TvPen;
|
||||||
|
Brush: TvBrush;
|
||||||
|
constructor Create();
|
||||||
procedure Assign(APath: TPath);
|
procedure Assign(APath: TPath);
|
||||||
function Count(): TPathSegment;
|
function Count(): TPathSegment;
|
||||||
procedure PrepareForSequentialReading;
|
procedure PrepareForSequentialReading;
|
||||||
@ -149,13 +164,8 @@ type
|
|||||||
}
|
}
|
||||||
TvEntity = class
|
TvEntity = class
|
||||||
public
|
public
|
||||||
// Pen
|
Pen: TvPen;
|
||||||
PenColor: TvColor;
|
Brush: TvBrush;
|
||||||
PenStyle: TFPPenStyle;
|
|
||||||
PenWidth: Integer;
|
|
||||||
// Brush
|
|
||||||
BrushStyle: TFPBrushStyle;
|
|
||||||
BrushColor: TvColor;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -253,6 +263,8 @@ type
|
|||||||
procedure AddLineToPath(AX, AY, AZ: Double); overload;
|
procedure AddLineToPath(AX, AY, AZ: Double); overload;
|
||||||
procedure AddBezierToPath(AX1, AY1, AX2, AY2, AX3, AY3: Double); overload;
|
procedure AddBezierToPath(AX1, AY1, AX2, AY2, AX3, AY3: Double); overload;
|
||||||
procedure AddBezierToPath(AX1, AY1, AZ1, AX2, AY2, AZ2, AX3, AY3, AZ3: Double); overload;
|
procedure AddBezierToPath(AX1, AY1, AZ1, AX2, AY2, AZ2, AX3, AY3, AZ3: Double); overload;
|
||||||
|
procedure SetBrushToPath(ABrush: TvBrush);
|
||||||
|
procedure SetPenToPath(APen: TvPen);
|
||||||
procedure EndPath();
|
procedure EndPath();
|
||||||
procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload;
|
procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload;
|
||||||
procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload;
|
procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload;
|
||||||
@ -550,20 +562,19 @@ begin
|
|||||||
segment.SegmentType := st2DLine;
|
segment.SegmentType := st2DLine;
|
||||||
segment.X := AX;
|
segment.X := AX;
|
||||||
segment.Y := AY;
|
segment.Y := AY;
|
||||||
segment.PenColor := clvBlack;
|
|
||||||
|
|
||||||
AppendSegmentToTmpPath(segment);
|
AppendSegmentToTmpPath(segment);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor);
|
procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor);
|
||||||
var
|
var
|
||||||
segment: T2DSegment;
|
segment: T2DSegmentWithPen;
|
||||||
begin
|
begin
|
||||||
segment := T2DSegment.Create;
|
segment := T2DSegmentWithPen.Create;
|
||||||
segment.SegmentType := st2DLine;
|
segment.SegmentType := st2DLineWithPen;
|
||||||
segment.X := AX;
|
segment.X := AX;
|
||||||
segment.Y := AY;
|
segment.Y := AY;
|
||||||
segment.PenColor := AColor;
|
segment.Pen.Color := AColor;
|
||||||
|
|
||||||
AppendSegmentToTmpPath(segment);
|
AppendSegmentToTmpPath(segment);
|
||||||
end;
|
end;
|
||||||
@ -623,6 +634,23 @@ begin
|
|||||||
AppendSegmentToTmpPath(segment);
|
AppendSegmentToTmpPath(segment);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
Sets a Brush to paint the inner area inside the path.
|
||||||
|
}
|
||||||
|
procedure TvVectorialDocument.SetBrushToPath(ABrush: TvBrush);
|
||||||
|
begin
|
||||||
|
FTmPPath.Brush := ABrush;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
Sets a global Pen for the entire path. This Pen might be overriden by
|
||||||
|
individual elements of the polyline
|
||||||
|
}
|
||||||
|
procedure TvVectorialDocument.SetPenToPath(APen: TvPen);
|
||||||
|
begin
|
||||||
|
FTmPPath.Pen := APen;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Finishes writing a Path, which was created in multiple
|
Finishes writing a Path, which was created in multiple
|
||||||
steps using StartPath and AddPointToPath,
|
steps using StartPath and AddPointToPath,
|
||||||
@ -683,7 +711,7 @@ begin
|
|||||||
lCircularArc.Radius := ARadius;
|
lCircularArc.Radius := ARadius;
|
||||||
lCircularArc.StartAngle := AStartAngle;
|
lCircularArc.StartAngle := AStartAngle;
|
||||||
lCircularArc.EndAngle := AEndAngle;
|
lCircularArc.EndAngle := AEndAngle;
|
||||||
lCircularArc.PenColor := AColor;
|
lCircularArc.Pen.Color := AColor;
|
||||||
FEntities.Add(lCircularArc);
|
FEntities.Add(lCircularArc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1073,6 +1101,12 @@ end;
|
|||||||
|
|
||||||
{ TPath }
|
{ TPath }
|
||||||
|
|
||||||
|
constructor TPath.Create();
|
||||||
|
begin
|
||||||
|
Brush.Style := bsClear;
|
||||||
|
inherited Create();
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPath.Assign(APath: TPath);
|
procedure TPath.Assign(APath: TPath);
|
||||||
begin
|
begin
|
||||||
Len := APath.Len;
|
Len := APath.Len;
|
||||||
|
@ -187,15 +187,22 @@ begin
|
|||||||
Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
st2DLine, st3DLine:
|
st2DLineWithPen:
|
||||||
begin
|
begin
|
||||||
{$ifdef USE_LCL_CANVAS}ADest.Pen.Color := VColorToTColor(Cur2DSegment.PenColor);{$endif}
|
{$ifdef USE_LCL_CANVAS}ADest.Pen.Color := VColorToTColor(T2DSegmentWithPen(Cur2DSegment).Pen.Color);{$endif}
|
||||||
ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
||||||
{$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif}
|
{$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif}
|
||||||
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
st2DLine, st3DLine:
|
||||||
|
begin
|
||||||
|
ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
||||||
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
|
Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
{ To draw a bezier we need to divide the interval in parts and make
|
{ To draw a bezier we need to divide the interval in parts and make
|
||||||
lines between this parts }
|
lines between this parts }
|
||||||
st2DBezier, st3DBezier:
|
st2DBezier, st3DBezier:
|
||||||
@ -321,7 +328,7 @@ begin
|
|||||||
WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
|
WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
|
||||||
[CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
|
[CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
|
||||||
{$endif}
|
{$endif}
|
||||||
ADest.Pen.Color := {$ifdef USE_LCL_CANVAS}VColorToTColor(CurArc.PenColor);{$else}VColorToFPColor(CurArc.PenColor);{$endif}
|
ADest.Pen.Color := {$ifdef USE_LCL_CANVAS}VColorToTColor(CurArc.Pen.Color);{$else}VColorToFPColor(CurArc.Pen.Color);{$endif}
|
||||||
ADest.Arc(
|
ADest.Arc(
|
||||||
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
|
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
|
||||||
IntStartAngle, IntAngleLength
|
IntStartAngle, IntAngleLength
|
||||||
|
Reference in New Issue
Block a user