From b4af90ab8828a583ddcee88ab150d878efbc30ff Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Thu, 21 Apr 2011 11:30:40 +0000 Subject: [PATCH] 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 --- .../fpvviewer/fpvectorialsrc/fpvectorial.pas | 70 ++++++++++++++----- .../fpvviewer/fpvectorialsrc/fpvtocanvas.pas | 13 +++- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas index bab9c4e24..92f086094 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas @@ -45,6 +45,17 @@ type Red, Green, Blue, Alpha: Byte; end; + TvPen = record + Color: TvColor; + Style: TFPPenStyle; + Width: Integer; + end; + + TvBrush = record + Color: TvColor; + Style: TFPBrushStyle; + end; + const FPValphaTransparent = $00; FPValphaOpaque = $FF; @@ -59,7 +70,7 @@ type P3DPoint = ^T3DPoint; TSegmentType = ( - st2DLine, st2DBezier, + st2DLine, st2DLineWithPen, st2DBezier, st3DLine, st3DBezier, stMoveTo); {@@ @@ -75,10 +86,6 @@ type // Fields for linking the list Previous: TPathSegment; Next: TPathSegment; - // Data fields - PenColor: TvColor; - PenStyle: TFPPenStyle; - PenWidth: Integer; end; {@@ @@ -93,6 +100,11 @@ type X, Y: Double; end; + T2DSegmentWithPen = class(T2DSegment) + public + Pen: TvPen; + end; + {@@ 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 @@ -124,6 +136,9 @@ type Points: TPathSegment; // Beginning of the double-linked list PointsEnd: TPathSegment; // End of the double-linked list CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next + Pen: TvPen; + Brush: TvBrush; + constructor Create(); procedure Assign(APath: TPath); function Count(): TPathSegment; procedure PrepareForSequentialReading; @@ -149,13 +164,8 @@ type } TvEntity = class public - // Pen - PenColor: TvColor; - PenStyle: TFPPenStyle; - PenWidth: Integer; - // Brush - BrushStyle: TFPBrushStyle; - BrushColor: TvColor; + Pen: TvPen; + Brush: TvBrush; end; {@@ @@ -253,6 +263,8 @@ type procedure AddLineToPath(AX, AY, AZ: 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 SetBrushToPath(ABrush: TvBrush); + procedure SetPenToPath(APen: TvPen); procedure EndPath(); procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload; procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload; @@ -550,20 +562,19 @@ begin segment.SegmentType := st2DLine; segment.X := AX; segment.Y := AY; - segment.PenColor := clvBlack; AppendSegmentToTmpPath(segment); end; procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor); var - segment: T2DSegment; + segment: T2DSegmentWithPen; begin - segment := T2DSegment.Create; - segment.SegmentType := st2DLine; + segment := T2DSegmentWithPen.Create; + segment.SegmentType := st2DLineWithPen; segment.X := AX; segment.Y := AY; - segment.PenColor := AColor; + segment.Pen.Color := AColor; AppendSegmentToTmpPath(segment); end; @@ -623,6 +634,23 @@ begin AppendSegmentToTmpPath(segment); 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 steps using StartPath and AddPointToPath, @@ -683,7 +711,7 @@ begin lCircularArc.Radius := ARadius; lCircularArc.StartAngle := AStartAngle; lCircularArc.EndAngle := AEndAngle; - lCircularArc.PenColor := AColor; + lCircularArc.Pen.Color := AColor; FEntities.Add(lCircularArc); end; @@ -1073,6 +1101,12 @@ end; { TPath } +constructor TPath.Create(); +begin + Brush.Style := bsClear; + inherited Create(); +end; + procedure TPath.Assign(APath: TPath); begin Len := APath.Len; diff --git a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas index 1e5f07301..62bca6733 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas @@ -187,15 +187,22 @@ begin Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)])); {$endif} end; - st2DLine, st3DLine: + st2DLineWithPen: 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)); {$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif} {$ifdef FPVECTORIAL_TOCANVAS_DEBUG} Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)])); {$endif} 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 lines between this parts } st2DBezier, st3DBezier: @@ -321,7 +328,7 @@ begin WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f', [CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16])); {$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( BoundsLeft, BoundsTop, BoundsRight, BoundsBottom, IntStartAngle, IntAngleLength