瀏覽代碼

factor PenVisible/BackVisible

johann 5 年之前
父節點
當前提交
d5886c2e37

+ 25 - 0
lazpaintcontrols/lcvectororiginal.pas

@@ -205,6 +205,9 @@ type
     procedure AddFillDiffHandler(AFill: TVectorialFill; ADiff: TCustomVectorialFillDiff);
     function GetDiffHandler(AClass: TVectorShapeDiffAny): TVectorShapeDiff;
     function GetIsFollowingMouse: boolean; virtual;
+    function GetPenVisible(AAssumePenFill: boolean = False): boolean; virtual;
+    function GetPenVisibleNow: boolean;
+    function GetBackVisible: boolean; virtual;
   public
     constructor Create(AContainer: TVectorOriginal); virtual;
     class function CreateFromStorage(AStorage: TBGRACustomOriginalStorage; AContainer: TVectorOriginal): TVectorShape;
@@ -273,6 +276,8 @@ type
     property Id: integer read FId write SetId;
     property IsFollowingMouse: boolean read GetIsFollowingMouse;
     property IsUpdating: boolean read GetIsUpdating;
+    property BackVisible: boolean read GetBackVisible;
+    property PenVisible: boolean read GetPenVisibleNow;
   end;
   TVectorShapes = specialize TFPGList<TVectorShape>;
   TVectorShapeAny = class of TVectorShape;
@@ -1579,6 +1584,26 @@ begin
   result := false;
 end;
 
+function TVectorShape.GetPenVisible(AAssumePenFill: boolean): boolean;
+var
+  f: TVectorShapeFields;
+begin
+  f := Fields;
+  result := (vsfPenFill in f) and (not PenFill.IsFullyTransparent or AAssumePenFill);
+  if result and (vsfPenWidth in f) then result := result and (PenWidth>0);
+  if result and (vsfPenStyle in f) then result := result and not IsClearPenStyle(PenStyle);
+end;
+
+function TVectorShape.GetPenVisibleNow: boolean;
+begin
+  result := GetPenVisible(False);
+end;
+
+function TVectorShape.GetBackVisible: boolean;
+begin
+  result := (vsfBackFill in Fields) and not BackFill.IsFullyTransparent;
+end;
+
 procedure TVectorShape.TransformFill(const AMatrix: TAffineMatrix; ABackOnly: boolean);
 begin
   BeginUpdate;

+ 16 - 29
lazpaintcontrols/lcvectorpolyshapes.pas

@@ -136,9 +136,6 @@ type
   { TPolylineShape }
 
   TPolylineShape = class(TCustomPolypointShape)
-  protected
-    function PenVisible(AAssumePenFill: boolean = false): boolean;
-    function BackVisible: boolean;
   public
     class function Fields: TVectorShapeFields; override;
     procedure Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); overload; override;
@@ -1161,16 +1158,6 @@ end;
 
 { TPolylineShape }
 
-function TPolylineShape.PenVisible(AAssumePenFill: boolean): boolean;
-begin
-  result := (PenWidth>0) and not IsClearPenStyle(PenStyle) and (not PenFill.IsFullyTransparent or AAssumePenFill);
-end;
-
-function TPolylineShape.BackVisible: boolean;
-begin
-  result := not BackFill.IsFullyTransparent;
-end;
-
 class function TPolylineShape.Fields: TVectorShapeFields;
 begin
   Result:= [vsfPenFill, vsfPenWidth, vsfPenStyle, vsfJoinStyle, vsfBackFill];
@@ -1182,9 +1169,9 @@ var
   pts: array of TPointF;
   backScan, penScan: TBGRACustomScanner;
 begin
-  if not BackVisible and not PenVisible then exit;
+  if not GetBackVisible and not GetPenVisible then exit;
   pts := GetCurve(AMatrix);
-  if BackVisible then
+  if GetBackVisible then
   begin
     if BackFill.FillType = vftSolid then backScan := nil
     else backScan := BackFill.CreateScanner(AMatrix, ADraft);
@@ -1204,7 +1191,7 @@ begin
 
     backScan.Free;
   end;
-  if PenVisible then
+  if GetPenVisible then
   begin
     if PenFill.FillType = vftSolid then penScan := nil
     else penScan := PenFill.CreateScanner(AMatrix, ADraft);
@@ -1233,12 +1220,12 @@ var
   xMargin, yMargin: single;
   fillBounds, penBounds: TRectF;
 begin
-  if not (BackVisible or (rboAssumeBackFill in AOptions)) and not PenVisible(rboAssumePenFill in AOptions) then
+  if not (GetBackVisible or (rboAssumeBackFill in AOptions)) and not GetPenVisible(rboAssumePenFill in AOptions) then
     result:= EmptyRectF
   else
   begin
     pts := GetCurve(AMatrix);
-    if PenVisible(rboAssumePenFill in AOptions) then
+    if GetPenVisible(rboAssumePenFill in AOptions) then
     begin
       if (JoinStyle = pjsRound) and (ArrowStartKind = akNone) and (ArrowEndKind = akNone) then
       begin
@@ -1251,7 +1238,7 @@ begin
         result.Bottom += yMargin;
       end else
       begin
-        if BackVisible or (rboAssumeBackFill in AOptions) then fillBounds := GetPointsBoundsF(pts)
+        if GetBackVisible or (rboAssumeBackFill in AOptions) then fillBounds := GetPointsBoundsF(pts)
         else fillBounds := EmptyRectF;
         pts := ComputeStroke(pts, Closed, AMatrix);
         penBounds := GetPointsBoundsF(pts);
@@ -1268,10 +1255,10 @@ function TPolylineShape.PointInShape(APoint: TPointF): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if not BackVisible and not PenVisible then exit(false);
+  if not GetBackVisible and not GetPenVisible then exit(false);
   pts := GetCurve(AffineMatrixIdentity);
-  if BackVisible and IsPointInPolygon(pts, APoint, true) then exit(true);
-  if PenVisible then
+  if GetBackVisible and IsPointInPolygon(pts, APoint, true) then exit(true);
+  if GetPenVisible then
   begin
     pts := ComputeStroke(pts, Closed, AffineMatrixIdentity);
     if IsPointInPolygon(pts, APoint, true) then exit(true);
@@ -1283,7 +1270,7 @@ function TPolylineShape.PointInShape(APoint: TPointF; ARadius: single): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if not BackVisible and not PenVisible then exit(false);
+  if not GetBackVisible and not GetPenVisible then exit(false);
   pts := GetCurve(AffineMatrixIdentity);
   pts := ComputeStrokeEnvelope(pts, Closed, ARadius*2);
   result := IsPointInPolygon(pts, APoint, true);
@@ -1294,7 +1281,7 @@ var
   pts: ArrayOfTPointF;
   scan: TBGRACustomScanner;
 begin
-  if BackVisible then
+  if GetBackVisible then
   begin
     pts := GetCurve(AffineMatrixIdentity);
     result := IsPointInPolygon(pts, APoint, true);
@@ -1312,7 +1299,7 @@ function TPolylineShape.PointInPen(APoint: TPointF): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if BackVisible then
+  if GetBackVisible then
   begin
     pts := GetCurve(AffineMatrixIdentity);
     pts := ComputeStroke(pts, Closed, AffineMatrixIdentity);
@@ -1328,13 +1315,13 @@ var pts: ArrayOfTPointF;
   backSurface: Single;
   penLength, zoomFactor, penSurface, totalSurface: single;
 begin
-  if not PenVisible and not BackVisible or (PointCount = 0) then exit(false);
+  if not GetPenVisible and not GetBackVisible or (PointCount = 0) then exit(false);
 
   setlength(pts, PointCount);
   for i := 0 to high(pts) do
     pts[i] := AMatrix * Points[i];
 
-  if PenVisible then
+  if GetPenVisible then
   begin
     penLength := 0;
     zoomFactor := max(VectLen(AMatrix[1,1],AMatrix[2,1]), VectLen(AMatrix[1,2],AMatrix[2,2]));
@@ -1354,14 +1341,14 @@ begin
     penSurface := penLength*PenWidth*zoomFactor;
   end else penSurface := 0;
 
-  if BackVisible then
+  if GetBackVisible then
   begin
     ptsBounds := GetPointsBoundsF(pts);
     backSurface := ptsBounds.Width*ptsBounds.Height;
   end else
     backSurface := 0;
 
-  if PenVisible and BackVisible then totalSurface := backSurface+penSurface/2
+  if GetPenVisible and GetBackVisible then totalSurface := backSurface+penSurface/2
   else totalSurface := backSurface+penSurface;
 
   Result:= (PointCount > 40) or

+ 36 - 66
lazpaintcontrols/lcvectorrectshapes.pas

@@ -95,8 +95,6 @@ type
 
   TRectShape = class(TCustomRectShape)
   protected
-    function PenVisible(AAssumePenFill: boolean = false): boolean;
-    function BackVisible: boolean;
     function GetCornerPositition: single; override;
   public
     class function Fields: TVectorShapeFields; override;
@@ -114,8 +112,6 @@ type
 
   TEllipseShape = class(TCustomRectShape)
   protected
-    function PenVisible(AAssumePenFill: boolean = false): boolean;
-    function BackVisible: boolean;
     function GetCornerPositition: single; override;
   public
     constructor Create(AContainer: TVectorOriginal); override;
@@ -174,7 +170,6 @@ type
     procedure SetLightPosition(AValue: TPointF);
     procedure SetShapeAltitudePercent(AValue: single);
     procedure SetShapeKind(AValue: TPhongShapeKind);
-    function BackVisible: boolean;
     function GetEnvelope: ArrayOfTPointF;
   public
     constructor Create(AContainer: TVectorOriginal); override;
@@ -892,16 +887,6 @@ end;
 
 { TRectShape }
 
-function TRectShape.PenVisible(AAssumePenFill: boolean): boolean;
-begin
-  result := (PenWidth>0) and not IsClearPenStyle(PenStyle) and (not PenFill.IsFullyTransparent or AAssumePenFill);
-end;
-
-function TRectShape.BackVisible: boolean;
-begin
-  result := not BackFill.IsFullyTransparent;
-end;
-
 function TRectShape.GetCornerPositition: single;
 begin
   result := 1;
@@ -912,24 +897,24 @@ var
   ab: TAffineBox;
   backSurface, totalSurface, penSurface: Single;
 begin
-  if not PenVisible and not BackVisible then
+  if not GetPenVisible and not GetBackVisible then
     result := false
   else
   begin
     ab := GetAffineBox(AMatrix, true);
     backSurface := ab.Surface;
-    if PenVisible then
+    if GetPenVisible then
     begin
       penSurface := (ab.Width+ab.Height)*2*PenWidth;
-      if BackVisible then
+      if GetBackVisible then
         totalSurface:= backSurface+penSurface/2
       else
         totalSurface := penSurface;
     end else
       totalSurface := backSurface;
     result := (totalSurface > 800*600) or
-              ((backSurface > 320*240) and BackVisible and BackFill.IsSlow(AMatrix)) or
-              ((penSurface > 320*240) and PenVisible and PenFill.IsSlow(AMatrix));
+              ((backSurface > 320*240) and GetBackVisible and BackFill.IsSlow(AMatrix)) or
+              ((penSurface > 320*240) and GetPenVisible and PenFill.IsSlow(AMatrix));
   end;
 end;
 
@@ -950,7 +935,7 @@ var
   i: Integer;
 begin
   pts := GetAffineBox(AMatrix, true).AsPolygon;
-  If BackVisible then
+  If GetBackVisible then
   begin
     if (BackFill.FillType = vftSolid) then backScan := nil
     else backScan := BackFill.CreateScanner(AMatrix, ADraft);
@@ -1015,7 +1000,7 @@ begin
 
     backScan.Free;
   end;
-  if PenVisible then
+  if GetPenVisible then
   begin
     if (PenFill.FillType = vftSolid) then penScan := nil
     else penScan := PenFill.CreateScanner(AMatrix, ADraft);
@@ -1044,12 +1029,12 @@ var
   pts: ArrayOfTPointF;
   xMargin, yMargin: single;
 begin
-  if not (BackVisible or (rboAssumeBackFill in AOptions)) and not PenVisible(rboAssumePenFill in AOptions) then
+  if not (GetBackVisible or (rboAssumeBackFill in AOptions)) and not GetPenVisible(rboAssumePenFill in AOptions) then
     result:= EmptyRectF
   else
   begin
     result := inherited GetRenderBounds(ADestRect, AMatrix, AOptions);
-    if PenVisible(rboAssumePenFill in AOptions) then
+    if GetPenVisible(rboAssumePenFill in AOptions) then
     begin
       if (JoinStyle <> pjsMiter) or (Stroker.MiterLimit <= 1) then
       begin
@@ -1080,9 +1065,9 @@ var
   box: TAffineBox;
 begin
   box := GetAffineBox(AffineMatrixIdentity, true);
-  if BackVisible and box.Contains(APoint) then
+  if GetBackVisible and box.Contains(APoint) then
     result := true else
-  if PenVisible then
+  if GetPenVisible then
   begin
     pts := ComputeStroke(box.AsPolygon, true, AffineMatrixIdentity);
     result:= IsPointInPolygon(pts, APoint, true);
@@ -1095,7 +1080,7 @@ var
   pts: ArrayOfTPointF;
   box: TAffineBox;
 begin
-  if PenVisible or BackVisible then
+  if GetPenVisible or GetBackVisible then
   begin
     box := GetAffineBox(AffineMatrixIdentity, true);
     pts := ComputeStrokeEnvelope(box.AsPolygon, true, ARadius*2);
@@ -1109,7 +1094,7 @@ var
   box: TAffineBox;
   scan: TBGRACustomScanner;
 begin
-  if BackVisible then
+  if GetBackVisible then
   begin
     box := GetAffineBox(AffineMatrixIdentity, true);
     result := box.Contains(APoint);
@@ -1127,7 +1112,7 @@ function TRectShape.PointInPen(APoint: TPointF): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if PenVisible then
+  if GetPenVisible then
   begin
     pts := GetAffineBox(AffineMatrixIdentity, true).AsPolygon;
     pts := ComputeStroke(pts,true, AffineMatrixIdentity);
@@ -1143,16 +1128,6 @@ end;
 
 { TEllipseShape }
 
-function TEllipseShape.PenVisible(AAssumePenFill: boolean): boolean;
-begin
-  result := (PenWidth>0) and not IsClearPenStyle(PenStyle) and (not PenFill.IsFullyTransparent or AAssumePenFill);
-end;
-
-function TEllipseShape.BackVisible: boolean;
-begin
-  result := not BackFill.IsFullyTransparent;
-end;
-
 function TEllipseShape.GetCornerPositition: single;
 begin
   result := sqrt(2)/2;
@@ -1196,7 +1171,7 @@ begin
   IncludePoint(m*YAxis);
   IncludePoint(m*(Origin-(XAxis-Origin)));
   IncludePoint(m*(Origin-(YAxis-Origin)));
-  if PenVisible then
+  if GetPenVisible then
   begin
     zoom := (VectLen(AMatrix[1,1],AMatrix[2,1])+VectLen(AMatrix[1,2],AMatrix[2,2]))/2;
     result.Left -= zoom*PenWidth/2;
@@ -1223,7 +1198,7 @@ begin
   begin
     center := (orthoRect.TopLeft+orthoRect.BottomRight)*0.5;
     radius := (orthoRect.BottomRight-orthoRect.TopLeft)*0.5;
-    If BackVisible then
+    If GetBackVisible then
     begin
       if BackFill.FillType = vftSolid then backScan := nil
       else backScan := BackFill.CreateScanner(AMatrix, ADraft);
@@ -1244,7 +1219,7 @@ begin
 
       backScan.Free;
     end;
-    if PenVisible then
+    if GetPenVisible then
     begin
       if PenFill.FillType = vftSolid then penScan := nil
       else penScan := PenFill.CreateScanner(AMatrix, ADraft);
@@ -1288,7 +1263,7 @@ begin
   begin
     m:= MatrixForPixelCentered(AMatrix);
     pts := ComputeEllipse(m*FOrigin, m*FXAxis, m*FYAxis);
-    If BackVisible then
+    If GetBackVisible then
     begin
       if BackFill.FillType = vftSolid then backScan := nil
       else backScan := BackFill.CreateScanner(AMatrix, ADraft);
@@ -1308,7 +1283,7 @@ begin
 
       backScan.Free;
     end;
-    if PenVisible then
+    if GetPenVisible then
     begin
       if PenFill.FillType = vftSolid then penScan := nil
       else penScan := PenFill.CreateScanner(AMatrix, ADraft);
@@ -1336,12 +1311,12 @@ function TEllipseShape.GetRenderBounds({%H-}ADestRect: TRect; AMatrix: TAffineMa
 var
   xMargin, yMargin: single;
 begin
-  if not (BackVisible or (rboAssumeBackFill in AOptions)) and not PenVisible(rboAssumePenFill in AOptions) then
+  if not (GetBackVisible or (rboAssumeBackFill in AOptions)) and not GetPenVisible(rboAssumePenFill in AOptions) then
     result:= EmptyRectF
   else
   begin
     result := inherited GetRenderBounds(ADestRect, AMatrix, AOptions);
-    if PenVisible(rboAssumePenFill in AOptions) then
+    if GetPenVisible(rboAssumePenFill in AOptions) then
     begin
       xMargin := (abs(AMatrix[1,1])+abs(AMatrix[1,2]))*PenWidth*0.5;
       yMargin := (abs(AMatrix[2,1])+abs(AMatrix[2,2]))*PenWidth*0.5;
@@ -1358,9 +1333,9 @@ var
   pts: ArrayOfTPointF;
 begin
   pts := ComputeEllipse(FOrigin, FXAxis, FYAxis);
-  if BackVisible and IsPointInPolygon(pts, APoint, true) then
+  if GetBackVisible and IsPointInPolygon(pts, APoint, true) then
     result := true else
-  if PenVisible then
+  if GetPenVisible then
   begin
     pts := ComputeStroke(pts, true, AffineMatrixIdentity);
     result:= IsPointInPolygon(pts, APoint, true);
@@ -1372,7 +1347,7 @@ function TEllipseShape.PointInShape(APoint: TPointF; ARadius: single): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if PenVisible or BackVisible then
+  if GetPenVisible or GetBackVisible then
   begin
     pts := ComputeEllipse(FOrigin, FXAxis, FYAxis);
     pts := ComputeStrokeEnvelope(pts, true, ARadius*2);
@@ -1386,7 +1361,7 @@ var
   pts: ArrayOfTPointF;
   scan: TBGRACustomScanner;
 begin
-  if BackVisible then
+  if GetBackVisible then
   begin
     pts := ComputeEllipse(FOrigin, FXAxis, FYAxis);
     result:= IsPointInPolygon(pts, APoint, true);
@@ -1404,7 +1379,7 @@ function TEllipseShape.PointInPen(APoint: TPointF): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if PenVisible then
+  if GetPenVisible then
   begin
     pts := ComputeEllipse(FOrigin, FXAxis, FYAxis);
     pts := ComputeStroke(pts,true, AffineMatrixIdentity);
@@ -1418,24 +1393,24 @@ var
   ab: TAffineBox;
   backSurface, totalSurface, penSurface: Single;
 begin
-  if not PenVisible and not BackVisible then
+  if not GetPenVisible and not GetBackVisible then
     result := false
   else
   begin
     ab := GetAffineBox(AMatrix, true);
     backSurface := ab.Surface*Pi/4;
-    if PenVisible then
+    if GetPenVisible then
     begin
       penSurface := (ab.Width+ab.Height)*(Pi/2)*PenWidth;
-      if BackVisible then
+      if GetBackVisible then
         totalSurface:= backSurface+penSurface/2
       else
         totalSurface := penSurface;
     end else
       totalSurface := backSurface;
     result := (totalSurface > 640*480) or
-              ((backSurface > 320*240) and BackVisible and BackFill.IsSlow(AMatrix)) or
-              ((penSurface > 320*240) and PenVisible and PenFill.IsSlow(AMatrix));
+              ((backSurface > 320*240) and GetBackVisible and BackFill.IsSlow(AMatrix)) or
+              ((penSurface > 320*240) and GetPenVisible and PenFill.IsSlow(AMatrix));
   end;
 end;
 
@@ -1484,11 +1459,6 @@ begin
   EndUpdate;
 end;
 
-function TPhongShape.BackVisible: boolean;
-begin
-  result := not BackFill.IsFullyTransparent;
-end;
-
 function TPhongShape.GetEnvelope: ArrayOfTPointF;
 var
   box: TAffineBox;
@@ -1662,7 +1632,7 @@ var
   rectRenderF,rectRasterF: TRectF;
   rectRender,rectRaster, prevClip: TRect;
 begin
-  if not BackVisible then exit;
+  if not GetBackVisible then exit;
 
   //determine final render bounds
   rectRenderF := GetRenderBounds(InfiniteRect,AMatrix);
@@ -1790,7 +1760,7 @@ end;
 function TPhongShape.GetRenderBounds(ADestRect: TRect; AMatrix: TAffineMatrix;
   AOptions: TRenderBoundsOptions): TRectF;
 begin
-  if not (BackVisible or (rboAssumeBackFill in AOptions)) then
+  if not (GetBackVisible or (rboAssumeBackFill in AOptions)) then
     result:= EmptyRectF
   else
     result := inherited GetRenderBounds(ADestRect, AMatrix, AOptions);
@@ -1800,7 +1770,7 @@ function TPhongShape.PointInShape(APoint: TPointF): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if not BackVisible then exit(false);
+  if not GetBackVisible then exit(false);
   pts := GetEnvelope;
   result := IsPointInPolygon(pts, APoint, true);
 end;
@@ -1809,7 +1779,7 @@ function TPhongShape.PointInShape(APoint: TPointF; ARadius: single): boolean;
 var
   pts: ArrayOfTPointF;
 begin
-  if BackVisible then
+  if GetBackVisible then
   begin
     pts := ComputeStrokeEnvelope(GetEnvelope, true, ARadius*2);
     result:= IsPointInPolygon(pts, APoint, true);
@@ -1834,7 +1804,7 @@ function TPhongShape.GetIsSlow(const AMatrix: TAffineMatrix): boolean;
 var
   ab: TAffineBox;
 begin
-  if not BackVisible then exit(false);
+  if not GetBackVisible then exit(false);
   ab := GetAffineBox(AMatrix, true);
   result := ab.Surface > 320*240;
 end;

+ 1 - 7
lazpaintcontrols/lcvectortextshapes.pas

@@ -120,7 +120,6 @@ type
     FGlobalMatrix: TAffineMatrix;
     procedure DoOnChange(ABoundsBefore: TRectF; ADiff: TVectorShapeDiff); override;
     procedure SetGlobalMatrix(AMatrix: TAffineMatrix);
-    function PenVisible(AAssumePenFill: boolean = false): boolean;
     function ShowArrows: boolean; override;
     function GetTextLayout: TBidiTextLayout;
     function GetFontRenderer: TBGRACustomFontRenderer;
@@ -731,11 +730,6 @@ begin
   FGlobalMatrix := AMatrix;
 end;
 
-function TTextShape.PenVisible(AAssumePenFill: boolean): boolean;
-begin
-  result := not PenFill.IsFullyTransparent or AAssumePenFill;
-end;
-
 function TTextShape.AllowShearTransform: boolean;
 begin
   Result:= true;
@@ -1469,7 +1463,7 @@ var
   u: TPointF;
   lenU, margin: Single;
 begin
-  if (PenVisible(rboAssumePenFill in AOptions) or HasOutline) and
+  if (GetPenVisible(rboAssumePenFill in AOptions) or HasOutline) and
     (Text <> '') then
   begin
     ab := GetAffineBox(AMatrix, false);