2
0
Эх сурвалжийг харах

use fill style and fit geometry

johann 5 жил өмнө
parent
commit
eb972921a2

+ 4 - 0
lazpaint/lazpaintmainform.pas

@@ -2899,6 +2899,10 @@ begin
       if self.Visible then
       begin
         case Tool of
+          ptGradient:
+            begin
+              VectorialFill_Back.FillType:= vftGradient;
+            end;
           ptTextureMapping:
           begin
             useSelection:= false;

+ 33 - 2
lazpaint/tools/utool.pas

@@ -144,10 +144,10 @@ type
 
   TToolClass = class of TGenericTool;
 
-  TToolPopupMessage= (tpmNone,tpmHoldKeyForSquare, tpmHoldKeySnapToPixel,
+  TToolPopupMessage= (tpmNone, tpmHoldKeyForSquare, tpmHoldKeySnapToPixel,
     tpmReturnValides, tpmBackspaceRemoveLastPoint, tpmHoldKeyRestrictRotation,
     tpmHoldKeysScaleMode, tpmCurveModeHint, tpmBlendOpBackground,
-    tpmRightClickForSource);
+    tpmRightClickForSource, tpmNothingToBeDeformed);
 
   TOnToolChangedHandler = procedure(sender: TToolManager; ANewToolType: TPaintToolType) of object;
   TOnPopupToolHandler = procedure(sender: TToolManager; APopupMessage: TToolPopupMessage; AKey: Word) of object;
@@ -437,6 +437,8 @@ type
     function SuggestGradientBox: TAffineBox;
 
     procedure SwapToolColors;
+    procedure NeedBackGradient;
+    procedure NeedForeGradient;
     procedure AddBrush(brush: TLazPaintBrush);
     procedure RemoveBrushAt(index: integer);
     procedure SetTextFont(AName: string; ASize: single; AStyle: TFontStyles);
@@ -603,6 +605,7 @@ begin
   tpmCurveModeHint: result := rsCurveModeHint;
   tpmBlendOpBackground: result := rsBlendOpNotUsedForBackground;
   tpmRightClickForSource: result := rsRightClickForSource;
+  tpmNothingToBeDeformed: result := rsNothingToBeDeformed;
   else
     result := '';
   end;
@@ -2820,6 +2823,34 @@ begin
   if Assigned(FOnFillChanged) then FOnFillChanged(self);
 end;
 
+procedure TToolManager.NeedBackGradient;
+var
+  tempFill: TVectorialFill;
+begin
+  if BackFill.FillType <> vftGradient then
+  begin
+    tempFill := TVectorialFill.Create;
+    tempFill.SetGradient(FBackLastGradient, False);
+    tempFill.FitGeometry(SuggestGradientBox);
+    BackFill.Assign(tempFill);
+    tempFill.Free;
+  end;
+end;
+
+procedure TToolManager.NeedForeGradient;
+var
+  tempFill: TVectorialFill;
+begin
+  if ForeFill.FillType <> vftGradient then
+  begin
+    tempFill := TVectorialFill.Create;
+    tempFill.SetGradient(FForeLastGradient, False);
+    tempFill.FitGeometry(SuggestGradientBox);
+    ForeFill.Assign(tempFill);
+    tempFill.Free;
+  end;
+end;
+
 procedure TToolManager.AddBrush(brush: TLazPaintBrush);
 begin
   FBrushIndex := FBrushInfoList.Add(brush);

+ 21 - 12
lazpaint/tools/utooldeformationgrid.pas

@@ -236,6 +236,8 @@ begin
     ValidateAction;
     quadDefined := false;
     quad := nil;
+    FLastTexture.FreeReference;
+    FLastTexture := nil;
   end;
 end;
 
@@ -376,12 +378,17 @@ begin
   begin
     if not definingQuad then
     begin
-      definingQuad := true;
-      setlength(quad,4);
-      quad[0] := ptF;
-      quad[1] := ptF;
-      quad[2] := ptF;
-      quad[3] := ptF;
+      if GetTexture = nil then
+        Manager.ToolPopup(tpmNothingToBeDeformed)
+      else
+        begin
+          definingQuad := true;
+          setlength(quad,4);
+          quad[0] := ptF;
+          quad[1] := ptF;
+          quad[2] := ptF;
+          quad[3] := ptF;
+        end;
     end;
     exit;
   end;
@@ -433,9 +440,9 @@ begin
   begin
     if ShiftKey then
     begin
-      if (Manager.BackFill.Texture <> nil) and (Manager.BackFill.Texture.Height <> 0)
-        and (Manager.BackFill.Texture.Width <> 0) then
-        ratio := Manager.BackFill.Texture.Width/Manager.BackFill.Texture.Height;
+      if (GetTexture <> nil) and (GetTexture.Height <> 0)
+        and (GetTexture.Width <> 0) then
+        ratio := GetTexture.Width/GetTexture.Height;
 
       newSize := ptF - quad[0];
       avgSize := (abs(newSize.x)+abs(newSize.y))/2;
@@ -541,12 +548,12 @@ end;
 
 function TToolTextureMapping.GetTexture: TBGRABitmap;
 begin
-  if Manager.BackFill.Texture = FLastTexture then
+  if (Manager.BackFill.Texture = nil) or (Manager.BackFill.Texture = FLastTexture) then
   begin
     if FTextureAfterAlpha <> nil then
       result := FTextureAfterAlpha
     else
-      result := Manager.BackFill.Texture;
+      result := FLastTexture;
   end
   else
   begin
@@ -560,7 +567,8 @@ begin
       result := Manager.BackFill.Texture;
       FreeAndNil(FTextureAfterAlpha);
     end;
-    FLastTexture := Manager.BackFill.Texture;
+    FLastTexture.FreeReference;
+    FLastTexture := Manager.BackFill.Texture.NewReference as TBGRABitmap;
   end;
 end;
 
@@ -827,6 +835,7 @@ end;
 destructor TToolTextureMapping.Destroy;
 begin
   ValidateAction;
+  FLastTexture.FreeReference;
   FreeAndNil(FTextureAfterAlpha);
   FreeAndNil(FAdaptedTexture);
   inherited Destroy;

+ 3 - 2
lazpaint/tools/utoolfloodfill.pas

@@ -27,7 +27,7 @@ type
   protected
     function CreateShape: TVectorShape; override;
     procedure DrawCustomShape(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); override;
-    procedure AssignShapeStyle({%H-}AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle({%H-}AMatrix: TAffineMatrix; {%H-}AAlwaysFit: boolean); override;
     procedure QuickDefineShape(AStart,AEnd: TPointF); override;
     function SlowShape: boolean; override;
     function GetStatusText: string; override;
@@ -57,8 +57,9 @@ begin
   FShape.BackFill.Gradient.Render(ADest,AMatrix,ADraft,dmDrawWithTransparency);
 end;
 
-procedure TToolGradient.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolGradient.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
+  Manager.NeedBackGradient;
   if Manager.BackFill.FillType = vftGradient then
     FShape.BackFill.AssignExceptGeometry(Manager.BackFill);
 end;

+ 3 - 3
lazpaint/tools/utoolphong.pas

@@ -15,7 +15,7 @@ type
   protected
     FMatrix: TAffineMatrix;
     procedure ShapeChange({%H-}ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff); override;
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     function CreateShape: TVectorShape; override;
     function SlowShape: boolean; override;
   public
@@ -49,9 +49,9 @@ begin
   inherited ShapeChange(ASender, ABounds, ADiff);
 end;
 
-procedure TToolPhong.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolPhong.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
-  inherited AssignShapeStyle(AMatrix);
+  inherited AssignShapeStyle(AMatrix, AAlwaysFit);
   FMatrix := AMatrix;
   with (FShape as TPhongShape) do
   begin

+ 6 - 6
lazpaint/tools/utoolpolygon.pas

@@ -36,7 +36,7 @@ type
   protected
     initiallyClosed : boolean;
     function CreateShape: TVectorShape; override;
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     procedure UpdateUserMode; virtual;
     procedure ShapeValidated; override;
   public
@@ -57,7 +57,7 @@ type
     procedure SetCurrentMode(AValue: TToolSplineMode);
   protected
     function CreateShape: TVectorShape; override;
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     procedure UpdateUserMode; override;
   public
     constructor Create(AManager: TToolManager); override;
@@ -144,9 +144,9 @@ begin
   end;
 end;
 
-procedure TToolSpline.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolSpline.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
-  inherited AssignShapeStyle(AMatrix);
+  inherited AssignShapeStyle(AMatrix, AAlwaysFit);
   TCurveShape(FShape).SplineStyle:= Manager.SplineStyle;
 end;
 
@@ -183,9 +183,9 @@ begin
   initiallyClosed := toCloseShape in Manager.ShapeOptions;
 end;
 
-procedure TToolPolygon.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolPolygon.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
-  inherited AssignShapeStyle(AMatrix);
+  inherited AssignShapeStyle(AMatrix, AAlwaysFit);
   TCustomPolypointShape(FShape).Closed := toCloseShape in Manager.ShapeOptions;
   TCustomPolypointShape(FShape).ArrowStartKind := Manager.ArrowStart;
   TCustomPolypointShape(FShape).ArrowEndKind := Manager.ArrowEnd;

+ 8 - 8
lazpaint/tools/utoolselect.pas

@@ -15,7 +15,7 @@ type
   TVectorialSelectTool = class(TVectorialTool)
   protected
     function GetIsSelectingTool: boolean; override;
-    procedure AssignShapeStyle({%H-}AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle({%H-}AMatrix: TAffineMatrix; {%H-}AAlwaysFit: boolean); override;
     function RoundCoordinate(ptF: TPointF): TPointF; override;
     function UpdateShape(toolDest: TBGRABitmap): TRect; override;
     procedure QuickDefineEnd; override;
@@ -48,7 +48,7 @@ type
 
   TToolSelectPoly = class(TToolPolygon)
   protected
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     function GetIsSelectingTool: boolean; override;
   public
     function GetContextualToolbars: TContextualToolbars; override;
@@ -58,7 +58,7 @@ type
 
   TToolSelectSpline = class(TToolSpline)
   protected
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     function GetIsSelectingTool: boolean; override;
   public
     function GetContextualToolbars: TContextualToolbars; override;
@@ -163,10 +163,10 @@ end;
 
 { TToolSelectSpline }
 
-procedure TToolSelectSpline.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolSelectSpline.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
   FShape.BeginUpdate;
-  inherited AssignShapeStyle(AMatrix);
+  inherited AssignShapeStyle(AMatrix, AAlwaysFit);
   AssignSelectShapeStyle(FShape, FSwapColor);
   FShape.EndUpdate;
 end;
@@ -183,10 +183,10 @@ end;
 
 { TToolSelectPoly }
 
-procedure TToolSelectPoly.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolSelectPoly.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
   FShape.BeginUpdate;
-  inherited AssignShapeStyle(AMatrix);
+  inherited AssignShapeStyle(AMatrix, AAlwaysFit);
   AssignSelectShapeStyle(FShape, FSwapColor);
   FShape.EndUpdate;
 end;
@@ -208,7 +208,7 @@ begin
   Result:= true;
 end;
 
-procedure TVectorialSelectTool.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TVectorialSelectTool.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 begin
   AssignSelectShapeStyle(FShape, FSwapColor);
   if FShape is TCustomRectShape then

+ 8 - 6
lazpaint/tools/utooltext.pas

@@ -25,7 +25,7 @@ type
     procedure DrawCustomShape(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); override;
     procedure ShapeChange(ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff); override;
     procedure ShapeEditingChange(ASender: TObject); override;
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); override;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); override;
     function SlowShape: boolean; override;
     procedure QuickDefineEnd; override;
     function RoundCoordinate(ptF: TPointF): TPointF; override;
@@ -142,11 +142,12 @@ begin
   inherited ShapeEditingChange(ASender);
 end;
 
-procedure TToolText.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TToolText.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 var
   r: TRect;
   toolDest: TBGRABitmap;
   zoom: Single;
+  gradBox: TAffineBox;
 begin
   FMatrix := AMatrix;
   with TTextShape(FShape) do
@@ -155,19 +156,20 @@ begin
     FontEmHeight:= zoom*Manager.TextFontSize*Manager.Image.DPI/72;
     FontName:= Manager.TextFontName;
     FontStyle:= Manager.TextFontStyle;
+    gradBox := self.SuggestGradientBox;
 
     if FSwapColor then
-      FShape.PenFill.AssignExceptGeometry(Manager.BackFill)
+      AssignFill(FShape.PenFill, Manager.BackFill, gradBox, AAlwaysFit)
     else
-      FShape.PenFill.AssignExceptGeometry(Manager.ForeFill);
+      AssignFill(FShape.PenFill, Manager.ForeFill, gradBox, AAlwaysFit);
 
     if Manager.TextOutline and (Manager.TextOutlineWidth>0) and
        (Manager.BackColor.alpha > 0) then
     begin
       if FSwapColor then
-        FShape.OutlineFill.AssignExceptGeometry(Manager.ForeFill)
+        AssignFill(FShape.OutlineFill, Manager.ForeFill, gradBox, AAlwaysFit)
       else
-        FShape.OutlineFill.AssignExceptGeometry(Manager.BackFill);
+        AssignFill(FShape.OutlineFill, Manager.BackFill, gradBox, AAlwaysFit);
       OutlineWidth := Manager.TextOutlineWidth;
     end
     else

+ 18 - 16
lazpaint/tools/utoolvectorial.pas

@@ -6,7 +6,7 @@ interface
 
 uses
   Classes, SysUtils, LCLType, BGRABitmap, BGRABitmapTypes,
-  BGRALayerOriginal, BGRAGraphics, LCVectorOriginal,
+  BGRALayerOriginal, BGRAGraphics, LCVectorOriginal, LCVectorialFill,
   UTool, UImageType, ULayerAction, LCVectorRectShapes,
   BGRAGradientOriginal, UStateType;
 
@@ -41,7 +41,7 @@ type
     function UseOriginal: boolean; virtual;
     function GetCustomShapeBounds(ADestBounds: TRect; AMatrix: TAffineMatrix; {%H-}ADraft: boolean): TRect; virtual;
     procedure DrawCustomShape(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); virtual;
-    procedure AssignShapeStyle(AMatrix: TAffineMatrix); virtual;
+    procedure AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean); virtual;
     procedure QuickDefineShape(AStart,AEnd: TPointF); virtual;
     function RoundCoordinate(ptF: TPointF): TPointF; virtual;
     function GetIsSelectingTool: boolean; override;
@@ -140,9 +140,11 @@ type
     property CurrentSplineMode: TToolSplineMode read GetCurrentSplineMode write SetCurrentSplineMode;
   end;
 
+procedure AssignFill(ATarget, ASource: TVectorialFill; const ABox: TAffineBox; AAlwaysFit: boolean);
+
 implementation
 
-uses LazPaintType, LCVectorPolyShapes, LCVectorTextShapes, LCVectorialFill, BGRASVGOriginal,
+uses LazPaintType, LCVectorPolyShapes, LCVectorTextShapes, BGRASVGOriginal,
   ULoading, BGRATransform, math, UImageDiff, Controls, BGRAPen, UResourceStrings, ugraph,
   LCScaleDPI, LCVectorClipboard, BGRAGradientScanner, UClipboard;
 
@@ -201,12 +203,12 @@ begin
   end;
 end;
 
-procedure AssignFill(ATarget, ASource: TVectorialFill; const ABox: TAffineBox);
+procedure AssignFill(ATarget, ASource: TVectorialFill; const ABox: TAffineBox; AAlwaysFit: boolean);
 var
   temp: TVectorialFill;
 begin
   if ASource.IsFullyTransparent then ATarget.Clear
-  else if ATarget.FillType <> ASource.FillType then
+  else if (ATarget.FillType <> ASource.FillType) or AAlwaysFit then
   begin
     temp := ATarget.Duplicate;
     temp.AssignExceptGeometry(ASource);
@@ -511,10 +513,10 @@ begin
         doDraw := vsfPenFill in SelectedShape.Fields;
         doFill := vsfBackFill in SelectedShape.Fields;
       end;
-      if doFill then AssignFill(SelectedShape.BackFill, Manager.BackFill, gradBox)
+      if doFill then AssignFill(SelectedShape.BackFill, Manager.BackFill, gradBox, false)
       else if vsfBackFill in SelectedShape.Fields then
           SelectedShape.BackFill.Clear;
-      if doDraw then AssignFill(SelectedShape.PenFill, Manager.ForeFill, gradBox);
+      if doDraw then AssignFill(SelectedShape.PenFill, Manager.ForeFill, gradBox, false);
 
       if SelectedShape is TTextShape then
       with TTextShape(SelectedShape) do
@@ -529,7 +531,7 @@ begin
         if Manager.TextOutline then
         begin
           OutlineWidth := Manager.TextOutlineWidth;
-          AssignFill(OutLineFill, Manager.BackFill, gradBox);
+          AssignFill(OutLineFill, Manager.BackFill, gradBox, false);
         end else
           OutlineFill.Clear;
       end;
@@ -1551,7 +1553,7 @@ begin
   FShape.Render(ADest,AMatrix,ADraft);
 end;
 
-procedure TVectorialTool.AssignShapeStyle(AMatrix: TAffineMatrix);
+procedure TVectorialTool.AssignShapeStyle(AMatrix: TAffineMatrix; AAlwaysFit: boolean);
 var
   f: TVectorShapeFields;
   zoom: Single;
@@ -1565,9 +1567,9 @@ begin
     if Manager.ShapeOptionDraw then
     begin
       if FSwapColor then
-        AssignFill(FShape.PenFill, Manager.BackFill, gradBox)
+        AssignFill(FShape.PenFill, Manager.BackFill, gradBox, AAlwaysFit)
       else
-        AssignFill(FShape.PenFill, Manager.ForeFill, gradBox);
+        AssignFill(FShape.PenFill, Manager.ForeFill, gradBox, AAlwaysFit);
     end else
       FShape.PenFill.Clear;
   end;
@@ -1579,9 +1581,9 @@ begin
     if Manager.ShapeOptionFill then
     begin
       if FSwapColor then
-        AssignFill(FShape.BackFill, Manager.ForeFill, gradBox)
+        AssignFill(FShape.BackFill, Manager.ForeFill, gradBox, AAlwaysFit)
       else
-        AssignFill(FShape.BackFill, Manager.BackFill, gradBox);
+        AssignFill(FShape.BackFill, Manager.BackFill, gradBox, AAlwaysFit);
     end else
       FShape.BackFill.Clear;
   end;
@@ -1704,7 +1706,7 @@ begin
         shapePt := AffineMatrixInverse(VectorTransform(true))*FLastPos;
         handled := false;
         FShape.MouseMove(FShiftState, shapePt.X,shapePt.Y, cur, handled);
-        AssignShapeStyle(FLastShapeTransform);
+        AssignShapeStyle(FLastShapeTransform, true);
       FShape.EndUpdate;
       FShape.OnChange:= @ShapeChange;
       FShape.OnEditingChange:=@ShapeEditingChange;
@@ -1741,7 +1743,7 @@ begin
       QuickDefineShape(FQuickDefineStartPoint, FQuickDefineEndPoint);
       FLastShapeTransform := AffineMatrixInverse(VectorTransform(false));
       FShape.Transform(FLastShapeTransform);
-      AssignShapeStyle(FLastShapeTransform);
+      AssignShapeStyle(FLastShapeTransform, true);
     FShape.EndUpdate;
     result := OnlyRenderChange;
   end else
@@ -1764,7 +1766,7 @@ begin
   if Assigned(FShape) then
   begin
     FShape.BeginUpdate;
-    AssignShapeStyle(FLastShapeTransform);
+    AssignShapeStyle(FLastShapeTransform, false);
     FShape.EndUpdate;
   end;
   result := EmptyRect;