johann 5 роки тому
батько
коміт
4d853ad4a1

+ 0 - 6
lazpaint/tools/utoolphong.pas

@@ -17,7 +17,6 @@ type
     procedure ShapeChange({%H-}ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff); override;
     procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     function CreateShape: TVectorShape; override;
-    function SlowShape: boolean; override;
   public
     constructor Create(AManager: TToolManager); override;
     function GetContextualToolbars: TContextualToolbars; override;
@@ -67,11 +66,6 @@ begin
   result := TPhongShape.Create(nil);
 end;
 
-function TToolPhong.SlowShape: boolean;
-begin
-  Result:= true;
-end;
-
 initialization
 
   RegisterTool(ptPhong,TToolPhong);

+ 0 - 6
lazpaint/tools/utooltext.pas

@@ -26,7 +26,6 @@ type
     procedure ShapeChange(ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff); override;
     procedure ShapeEditingChange(ASender: TObject); override;
     procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
-    function SlowShape: boolean; override;
     procedure QuickDefineEnd; override;
     function RoundCoordinate(ptF: TPointF): TPointF; override;
     function ForeGradTexMode: TVectorShapeUsermode; override;
@@ -197,11 +196,6 @@ begin
   end;
 end;
 
-function TToolText.SlowShape: boolean;
-begin
-  Result:= true;
-end;
-
 procedure TToolText.QuickDefineEnd;
 begin
   FShape.Usermode := vsuEditText;

+ 32 - 8
lazpaint/tools/utoolvectorial.pas

@@ -29,6 +29,7 @@ type
   protected
     FLayerWasEmpty: boolean;
     FShape: TVectorShape;
+    FLastDraftUpdate: Boolean;
     FSwapColor: boolean;
     FQuickDefine: Boolean;
     FQuickDefineStartPoint, FQuickDefineEndPoint: TPointF;
@@ -50,6 +51,7 @@ type
     function RoundCoordinate(ptF: TPointF): TPointF; virtual;
     function GetIsSelectingTool: boolean; override;
     function UpdateShape(toolDest: TBGRABitmap): TRect; virtual;
+    function PreferDraftUpdate: boolean;
     function VectorTransform(APixelCentered: boolean): TAffineMatrix;
     procedure UpdateCursor(ACursor: TOriginalEditorCursor);
     function FixLayerOffset: boolean; override;
@@ -110,6 +112,7 @@ type
     FIsEditingGradient: boolean;
     procedure RetrieveLightPosition;
     procedure UpdateToolManagerFromShape(AShape: TVectorShape);
+    procedure UpdateDraftMode;
     procedure BindOriginalEvent(ABind: boolean);
     procedure SelectShape({%H-}ASender: TObject; AShape: TVectorShape; {%H-}APreviousShape: TVectorShape);
     function DoToolDown({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF; rightBtn: boolean): TRect; override;
@@ -459,6 +462,15 @@ begin
   end;
 end;
 
+procedure TEditShapeTool.UpdateDraftMode;
+begin
+  case GetEditMode of
+  esmShape: Manager.Image.DraftOriginal:= GetVectorOriginal.PreferDraftMode(Manager.Image.CurrentState.LayeredBitmap.OriginalEditor, GetOriginalTransform);
+  esmNoShape: Manager.Image.DraftOriginal:= false;
+  else Manager.Image.DraftOriginal:= FLeftButton or FRightButton;
+  end;
+end;
+
 procedure TEditShapeTool.BindOriginalEvent(ABind: boolean);
 begin
   case GetCurrentLayerKind of
@@ -495,7 +507,6 @@ var
   ptView: TPointF;
 begin
   Result:= EmptyRect;
-  Manager.Image.DraftOriginal := true;
   FRightButton:= rightBtn;
   FLeftButton:= not rightBtn;
   FRectEditorCapture:= false;
@@ -542,6 +553,8 @@ var
 begin
   FLastPos := ptF;
   Result:= EmptyRect;
+  UpdateDraftMode;
+
   case GetEditMode of
   esmGradient, esmShape, esmNoShape:
     begin
@@ -1218,7 +1231,6 @@ begin
   Result:= EmptyRect;
   if FLeftButton or FRightButton then
   begin
-    Manager.Image.DraftOriginal := false;
     handled := false;
     if not handled and FRectEditorCapture and Assigned(FRectEditor) then
     begin
@@ -1328,6 +1340,8 @@ begin
     end;
     FLeftButton:= false;
     FRightButton:= false;
+    if Manager.Image.DraftOriginal then
+      UpdateDraftMode;
   end;
 end;
 
@@ -1565,7 +1579,10 @@ end;
 
 function TVectorialTool.SlowShape: boolean;
 begin
-  result := false;
+  if Assigned(FShape) then
+    result := FShape.GetIsSlow(VectorTransform(false))
+  else
+    result := false;
 end;
 
 procedure TVectorialTool.QuickDefineEnd;
@@ -1849,21 +1866,28 @@ function TVectorialTool.UpdateShape(toolDest: TBGRABitmap): TRect;
 var
   newBounds: TRect;
   oldClip: TRect;
-  draft: Boolean;
   matrix: TAffineMatrix;
 begin
   result := FPreviousUpdateBounds;
   RestoreBackupDrawingLayer;
   matrix := VectorTransform(false);
-  draft := (FRightDown or FLeftDown) and SlowShape;
-  newBounds := GetCustomShapeBounds(toolDest.ClipRect,matrix,draft);
+  FLastDraftUpdate := PreferDraftUpdate;
+  newBounds := GetCustomShapeBounds(toolDest.ClipRect,matrix,FLastDraftUpdate);
   result := RectUnion(result, newBounds);
   oldClip := toolDest.IntersectClip(newBounds);
-  DrawCustomShape(toolDest,matrix,draft);
+  DrawCustomShape(toolDest,matrix,FLastDraftUpdate);
   toolDest.ClipRect := oldClip;
   FPreviousUpdateBounds := newBounds;
 end;
 
+function TVectorialTool.PreferDraftUpdate: boolean;
+begin
+  if Assigned(FShape) then
+    result := (FEditor.IsMovingPoint or FShape.IsFollowingMouse) and SlowShape
+  else
+    result := false;
+end;
+
 function TVectorialTool.VectorTransform(APixelCentered: boolean): TAffineMatrix;
 begin
   if not UseOriginal then
@@ -2048,7 +2072,7 @@ begin
     UpdateCursor(cur);
     result := EmptyRect;
   end;
-  if SlowShape and Assigned(FShape) then
+  if (FLastDraftUpdate and not PreferDraftUpdate) and Assigned(FShape) then
     result := UpdateShape(GetToolDrawingLayer);
 end;
 

+ 2 - 2
lazpaintcontrols/lcvectorialfill.pas

@@ -564,7 +564,7 @@ begin
       result := bmpTransf;
   end else
   if Assigned(FGradient) then
-    result := FGradient.CreateScanner(AMatrix)
+    result := FGradient.CreateScanner(AMatrix, ADraft)
   else if FIsSolid then
     result := TBGRAConstantScanner.Create(FColor)
   else
@@ -580,7 +580,7 @@ begin
     m := AMatrix*FTextureMatrix;
     result := not TBGRABitmap.IsAffineRoughlyTranslation(m, rect(0,0,FTexture.Width,FTexture.Height));
   end else
-    result := false;
+    result := (FillType = vftGradient);
 end;
 
 function TVectorialFill.IsFullyTransparent: boolean;

+ 18 - 0
lazpaintcontrols/lcvectororiginal.pas

@@ -202,6 +202,7 @@ type
     function CanHaveRenderStorage: boolean;
     function AddDiffHandler(AClass: TVectorShapeDiffAny): TVectorShapeDiff;
     function GetDiffHandler(AClass: TVectorShapeDiffAny): TVectorShapeDiff;
+    function GetIsFollowingMouse: boolean; virtual;
   public
     constructor Create(AContainer: TVectorOriginal); virtual;
     class function CreateFromStorage(AStorage: TBGRACustomOriginalStorage; AContainer: TVectorOriginal): TVectorShape;
@@ -263,6 +264,7 @@ type
     property IsBack: boolean read GetIsBack;
     property IsRemoving: boolean read FRemoving;
     property Id: integer read FId write SetId;
+    property IsFollowingMouse: boolean read GetIsFollowingMouse;
   end;
   TVectorShapes = specialize TFPGList<TVectorShape>;
   TVectorShapeAny = class of TVectorShape;
@@ -376,6 +378,7 @@ type
     procedure SelectShape(AShape: TVectorShape); overload;
     procedure DeselectShape;
     function GetShapesCost: integer;
+    function PreferDraftMode(AEditor: TBGRAOriginalEditor; const AMatrix: TAffineMatrix): boolean;
     function MouseClick(APoint: TPointF; ARadius: single): boolean;
     procedure Render(ADest: TBGRABitmap; ARenderOffset: TPoint; AMatrix: TAffineMatrix; ADraft: boolean); override;
     procedure ConfigureEditor(AEditor: TBGRAOriginalEditor); override;
@@ -1556,6 +1559,11 @@ begin
   result := Assigned(Container) and (Container.IndexOfShape(self)=0);
 end;
 
+function TVectorShape.GetIsFollowingMouse: boolean;
+begin
+  result := false;
+end;
+
 function TVectorShape.GetIsFront: boolean;
 begin
   result := Assigned(Container) and (Container.IndexOfShape(self)=Container.ShapeCount-1);
@@ -2646,6 +2654,16 @@ begin
     inc(result, Shape[i].GetGenericCost);
 end;
 
+function TVectorOriginal.PreferDraftMode(AEditor: TBGRAOriginalEditor; const AMatrix: TAffineMatrix): boolean;
+begin
+  if Assigned(SelectedShape) then
+  begin
+    result := (AEditor.IsMovingPoint or SelectedShape.IsFollowingMouse) and
+              SelectedShape.GetIsSlow(AMatrix);
+  end else
+    result := false;
+end;
+
 function TVectorOriginal.MouseClick(APoint: TPointF; ARadius: single): boolean;
 var
   i: LongInt;

+ 51 - 1
lazpaintcontrols/lcvectorpolyshapes.pas

@@ -96,6 +96,7 @@ type
       AStrokeMatrix: TAffineMatrix): ArrayOfTPointF; override;
     function GetLoopStartIndex: integer;
     function GetLoopPointCount: integer;
+    function GetIsFollowingMouse: boolean; override;
   public
     constructor Create(AContainer: TVectorOriginal); override;
     procedure Clear;
@@ -790,6 +791,11 @@ begin
   result := PointCount-GetLoopStartIndex;
 end;
 
+function TCustomPolypointShape.GetIsFollowingMouse: boolean;
+begin
+  Result:= Usermode = vsuCreate;
+end;
+
 constructor TCustomPolypointShape.Create(AContainer: TVectorOriginal);
 begin
   inherited Create(AContainer);
@@ -1179,8 +1185,52 @@ begin
 end;
 
 function TPolylineShape.GetIsSlow(const AMatrix: TAffineMatrix): boolean;
+var pts: ArrayOfTPointF;
+  i: Integer;
+  ptsBounds: TRectF;
+  backSurface: Single;
+  penLength, zoomFactor, penSurface, totalSurface: single;
 begin
-  Result:= PointCount > 40;
+  if not PenVisible and not BackVisible or (PointCount = 0) then exit(false);
+
+  setlength(pts, PointCount);
+  for i := 0 to high(pts) do
+    pts[i] := AMatrix * Points[i];
+
+  if PenVisible then
+  begin
+    penLength := 0;
+    zoomFactor := max(VectLen(AMatrix[1,1],AMatrix[2,1]), VectLen(AMatrix[1,2],AMatrix[2,2]));
+    for i := 0 to high(pts) do
+      if (i > 0) then
+      begin
+        if pts[i-1].IsEmpty then
+        begin
+          if not pts[i].IsEmpty and (LineCap <> pecFlat) then penLength += penWidth/2*zoomFactor;
+        end else
+        if pts[i].IsEmpty then
+        begin
+          if not pts[i-1].IsEmpty and (LineCap <> pecFlat) then penLength += penWidth/2*zoomFactor;
+        end else
+          penLength += VectLen(pts[i]-pts[i-1]);
+      end;
+    penSurface := penLength*PenWidth*zoomFactor;
+  end else penSurface := 0;
+
+  if BackVisible then
+  begin
+    ptsBounds := GetPointsBoundsF(pts);
+    backSurface := ptsBounds.Width*ptsBounds.Height;
+  end else
+    backSurface := 0;
+
+  if PenVisible and BackVisible then totalSurface := backSurface+penSurface/2
+  else totalSurface := backSurface+penSurface;
+
+  Result:= (PointCount > 40) or
+           ((penSurface > 320*240) and PenFill.IsSlow(AMatrix)) or
+           ((backSurface > 320*240) and BackFill.IsSlow(AMatrix)) or
+           (totalSurface > 640*480);
 end;
 
 class function TPolylineShape.StorageClassName: RawByteString;

+ 6 - 2
lazpaintcontrols/lcvectorrectshapes.pas

@@ -934,7 +934,9 @@ begin
         totalSurface := penSurface;
     end else
       totalSurface := backSurface;
-    result := (totalSurface > 800*600) or ((totalSurface > 320*240) and (BackFill.IsSlow(AMatrix) or (BackFill.FillType = vftGradient)));
+    result := (totalSurface > 800*600) or
+              ((backSurface > 320*240) and BackVisible and BackFill.IsSlow(AMatrix)) or
+              ((penSurface > 320*240) and PenVisible and PenFill.IsSlow(AMatrix));
   end;
 end;
 
@@ -1374,7 +1376,9 @@ begin
         totalSurface := penSurface;
     end else
       totalSurface := backSurface;
-    result := (totalSurface > 640*480) or ((totalSurface > 320*240) and BackFill.IsSlow(AMatrix));
+    result := (totalSurface > 640*480) or
+              ((backSurface > 320*240) and BackVisible and BackFill.IsSlow(AMatrix)) or
+              ((penSurface > 320*240) and PenVisible and PenFill.IsSlow(AMatrix));
   end;
 end;