Browse Source

started changes

johann 5 năm trước cách đây
mục cha
commit
9e5cb1c7c0

+ 22 - 3
lazpaint/dialog/filter/uphongfilter.pas

@@ -53,6 +53,7 @@ type
     FCenter: TPointF;
     FHeightMap: TBGRABitmap;
     FWorkspaceColor: TColor;
+    FTexture: TBGRACustomBitmap;
     function GetCurrentLightPos: TPointF;
     procedure InitParams;
     procedure PreviewNeeded;
@@ -120,6 +121,7 @@ end;
 procedure TFPhongFilter.FormDestroy(Sender: TObject);
 begin
   FreeAndNil(FHeightMap);
+  if Assigned(FTexture) then FTexture.Free;
 end;
 
 
@@ -213,10 +215,27 @@ begin
 end;
 
 procedure TFPhongFilter.InitParams;
+var
+  texOpacity: Byte;
 begin
   FInitializing:= true;
-  Radio_UseTexture.Enabled := (FilterConnector.LazPaintInstance.ToolManager.GetTexture <> nil);
-  if Radio_UseTexture.Enabled then Radio_UseTexture.Checked := true
+  Radio_UseTexture.Enabled := (FilterConnector.LazPaintInstance.ToolManager.BackFill.Texture <> nil);
+  if FTexture <> nil then
+  begin
+    FTexture.FreeReference;
+    FTexture := nil;
+  end;
+  if Radio_UseTexture.Enabled then
+  begin
+    Radio_UseTexture.Checked := true;
+    texOpacity := FilterConnector.LazPaintInstance.ToolManager.BackFill.TextureOpacity;
+    if texOpacity <> 255 then
+    begin
+      FTexture := FilterConnector.LazPaintInstance.ToolManager.BackFill.Texture.Duplicate;
+      FTexture.ApplyGlobalOpacity(texOpacity);
+    end else
+      FTexture := FilterConnector.LazPaintInstance.ToolManager.BackFill.Texture.NewReference;
+  end
   else Radio_UsePenColor.Checked := true;
   SpinEdit_Altitude.Value := FilterConnector.LazPaintInstance.Config.DefaultPhongFilterAltitude;
   with FilterConnector.LazPaintInstance.ToolManager.LightPosition do
@@ -377,7 +396,7 @@ begin
   if FHeightMap <> nil then
   begin
     if Radio_UseTexture.Checked then
-      shader.DrawScan(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.GetTextureAfterAlpha)
+      shader.DrawScan(result, FHeightMap, SpinEdit_Altitude.Value, 0, 0, FTexture)
     else if Radio_UsePenColor.Checked then
       shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.ForeColor)
     else if Radio_UseKeep.Checked then

+ 11 - 18
lazpaint/lazpaintinstance.pas

@@ -46,7 +46,7 @@ type
     function ScriptImageRepeat(AVars: TVariableSet): TScriptResult;
     function ScriptImageResample(AParams: TVariableSet): TScriptResult;
     procedure SelectionInstanceOnRun(AInstance: TLazPaintCustomInstance);
-    procedure ToolColorChanged(Sender: TObject);
+    procedure ToolFillChanged(Sender: TObject);
     procedure PythonScriptCommand({%H-}ASender: TObject; ACommand, AParam: UTF8String; out
       AResult: UTF8String);
     procedure PythonBusy({%H-}Sender: TObject);
@@ -152,7 +152,7 @@ type
     procedure AssignBitmap(bmp: TBGRABitmap); override;
     procedure EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil; ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil; AOnExit: TLazPaintInstanceEvent = nil; ABlackAndWhite: boolean = false); override;
     procedure EditSelection; override;
-    procedure EditTexture; override;
+    function EditTexture(ASource: TBGRABitmap): TBGRABitmap; override;
     function ProcessCommandLine: boolean; override;
     function ProcessCommands(commands: TStringList): boolean; override;
     procedure ChangeIconSize(size: integer); override;
@@ -323,7 +323,7 @@ begin
   FToolManager := TToolManager.Create(FImage, self, nil, BlackAndWhite, FScriptContext);
   UseConfig(TIniFile.Create(''));
   FToolManager.OnPopup := @OnToolPopup;
-  FToolManager.OnColorChanged:=@ToolColorChanged;
+  FToolManager.OnFillChanged:= @ToolFillChanged;
   FSelectionEditConfig := nil;
   FTextureEditConfig := nil;
 
@@ -916,19 +916,18 @@ begin
   imageActions.Free;
 end;
 
-procedure TLazPaintInstance.EditTexture;
-var tex: TBGRABitmap;
+function TLazPaintInstance.EditTexture(ASource: TBGRABitmap): TBGRABitmap;
 begin
   try
     if FTextureEditConfig = nil then
       FTextureEditConfig := TStringStream.Create('[General]'+LineEnding+
         'DefaultImageWidth=256'+LineEnding+
         'DefaultImageHeight=256'+LineEnding);
-    tex := ToolManager.BorrowTexture;
+    result := ASource.Duplicate as TBGRABitmap;
     try
-      EditBitmap(tex,FTextureEditConfig,rsEditTexture,nil,nil,BlackAndWhite);
+      EditBitmap(result,FTextureEditConfig,rsEditTexture,nil,nil,BlackAndWhite);
     finally
-      ToolManager.SetTexture(tex);
+      if result.Equals(ASource) then FreeAndNil(result);
     end;
   except
     on ex: Exception do
@@ -942,10 +941,10 @@ begin
   AInstance.Config.SetDefaultImageHeight(Image.Height);
 end;
 
-procedure TLazPaintInstance.ToolColorChanged(Sender: TObject);
+procedure TLazPaintInstance.ToolFillChanged(Sender: TObject);
 begin
   ColorToFChooseColor;
-  if Assigned(FMain) then FMain.UpdateColorToolbar(false);
+  if Assigned(FMain) then FMain.UpdateFillToolbar(false);
 end;
 
 function TLazPaintInstance.GetIcons(ASize: integer): TImageList;
@@ -1403,20 +1402,14 @@ begin
   FormsNeeded;
   if InColorFromFChooseColor then exit;
   InColorFromFChooseColor := True;
-  if FChooseColor.colorTarget = ctForeColor then
-    ToolManager.ForeColor := FChooseColor.GetCurrentColor else
-  if FChooseColor.colorTarget = ctBackColor then
-    ToolManager.BackColor := FChooseColor.GetCurrentColor;
+  SetColor(FChooseColor.colorTarget, FChooseColor.GetCurrentColor);
   InColorFromFChooseColor := false;
 end;
 
 procedure TLazPaintInstance.ColorToFChooseColor;
 begin
   if not Assigned(FChooseColor) or InColorFromFChooseColor then exit;
-  if FChooseColor.colorTarget = ctForeColor then
-    FChooseColor.SetCurrentColor(ToolManager.ForeColor) else
-  if FChooseColor.colorTarget = ctBackColor then
-    FChooseColor.SetCurrentColor(ToolManager.BackColor);
+  FChooseColor.SetCurrentColor(GetColor(FChooseColor.colorTarget));
 end;
 
 function TLazPaintInstance.ShowSaveOptionDlg(AParameters: TVariableSet;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 251 - 650
lazpaint/lazpaintmainform.lfm


+ 42 - 104
lazpaint/lazpaintmainform.pas

@@ -16,8 +16,9 @@ uses
   BGRABitmap, BGRABitmapTypes, BGRALayers, BGRASVGOriginal, BGRAGradientScanner,
 
   LazPaintType, UMainFormLayout, UTool, UImage, UImageAction, UZoom, UImageView,
-  UImageObservation, UConfig, LCScaleDPI, UResourceStrings,
-  UMenu, uscripting, ubrowseimages, UToolPolygon, UToolVectorial, LCVectorRectShapes,
+  UImageObservation, UConfig, LCScaleDPI, UResourceStrings, UMenu, uscripting,
+  ubrowseimages, UToolPolygon, UToolVectorial, LCVectorRectShapes,
+  LCVectorialFillControl, LCVectorialFill,
 
   laztablet, udarktheme, UScriptType;
 
@@ -38,8 +39,16 @@ type
     EditMoveDown: TAction;
     EditMoveToFront: TAction;
     EditMoveUp: TAction;
+    Image_SwapColors: TImage;
+    Label_Pen: TLabel;
+    Label_Back: TLabel;
     Label_ShadowOffset: TLabel;
     Label_TextBlur: TLabel;
+    VectorialFill_Pen: TLCVectorialFillControl;
+    VectorialFill_Back: TLCVectorialFillControl;
+    Panel_BackFill: TPanel;
+    Panel_SwapColor: TPanel;
+    Panel_PenFill: TPanel;
     Panel_TextShadow: TPanel;
     Panel_CloseShape: TPanel;
     SpinEdit_TextBlur: TBCTrackbarUpdown;
@@ -52,10 +61,7 @@ type
     ComboBox_ArrowEnd: TBCComboBox;
     ComboBox_BrushSelect: TBCComboBox;
     Combo_SplineStyle: TBCComboBox;
-    Combo_GradientColorspace: TBCComboBox;
-    SpinEdit_PenOpacity: TBCTrackbarUpdown;
     FilterWaveDisplacement: TAction;
-    SpinEdit_BackOpacity: TBCTrackbarUpdown;
     SpinEdit_Eraser: TBCTrackbarUpdown;
     SpinEdit_GridNbX: TBCTrackbarUpdown;
     SpinEdit_GridNbY: TBCTrackbarUpdown;
@@ -68,7 +74,6 @@ type
     SpinEdit_TextOutlineWidth: TBCTrackbarUpdown;
     SpinEdit_PhongBorderSize: TBCTrackbarUpdown;
     SpinEdit_TextSize: TBCTrackbarUpdown;
-    SpinEdit_TextureOpacity: TBCTrackbarUpdown;
     Tool_CloseShape: TToolButton;
     Tool_TextShadow: TToolButton;
     ViewDarkTheme: TAction;
@@ -213,8 +218,6 @@ type
     RenderCyclicPerlinNoise: TAction;
     RenderWood: TAction;
     RenderPlastik: TAction;
-    ToolNoTexture: TAction;
-    ToolLoadTexture: TAction;
     RenderPerlinNoise: TAction;
     FilterBlurFast: TAction;
     FilterPlane: TAction;
@@ -342,39 +345,29 @@ type
     ToolButton20: TToolButton;
     ToolButton3: TToolButton;
     Tool_GridMoveWithoutDeformation: TToolButton;
-    Image_CurrentTexture: TImage;
-    Panel_Texture: TPanel;
     Panel_PenStyle: TPanel;
     Panel_LineCap: TPanel;
     Panel_JoinStyle: TPanel;
     ToolBar11: TToolBar;
-    ToolBar4: TToolBar;
-    ToolButton1: TToolButton;
-    ToolButton2: TToolButton;
     Tool_JoinBevel: TToolButton;
     Tool_JoinRound: TToolButton;
     Tool_CapSquare: TToolButton;
     Tool_CapFlat: TToolButton;
     Tool_CapRound: TToolButton;
     ToolBar10: TToolBar;
-    Tool_SinGradient: TToolButton;
     Tool_JoinMiter: TToolButton;
     Label_Coordinates: TLabel;
     Panel_Coordinates: TPanel;
-    Image_SwapColors: TImage;
     Label_Eraser: TLabel;
     Image_CurrentTool: TImage;
-    Label_Pen: TLabel;
-    Label_Back: TLabel;
     Label_CurrentZoom: TLabel;
     Panel_Undo: TPanel;
     Panel_CopyPaste: TPanel;
     Panel_ToolbarBackground: TPanel;
     Panel_File: TPanel;
-    Panel_GradientType: TPanel;
     Panel_Tool: TPanel;
     Panel_Zoom: TPanel;
-    Panel_Color: TPanel;
+    Panel_ColorDiff: TPanel;
     Panel_PenWidth: TPanel;
     Panel_Eraser: TPanel;
     Panel_Tolerance: TPanel;
@@ -382,14 +375,11 @@ type
     Label_PenWidth: TLabel;
     Tool_DrawShapeBorder: TToolButton;
     Tool_FillShape: TToolButton;
-    Shape_BackColor: TShape;
-    Shape_PenColor: TShape;
     Label_Tolerance: TLabel;
     ToolBar2: TToolBar;
     ToolBar3: TToolBar;
     ToolBar5: TToolBar;
     ToolBar6: TToolBar;
-    ToolBar7: TToolBar;
     ToolBar8: TToolBar;
     ToolBar9: TToolBar;
     ToolButton14: TToolButton;
@@ -403,11 +393,7 @@ type
     ToolButton30: TToolButton;
     ToolButton5: TToolButton;
     ToolButton6: TToolButton;
-    Tool_DiamondGradient: TToolButton;
-    Tool_LinearGradient: TToolButton;
     Tool_ProgressiveFloodfill: TToolButton;
-    Tool_RadialGradient: TToolButton;
-    Tool_ReflectedGradient: TToolButton;
     ToolButton_ZoomOriginal: TToolButton;
     ColorDialog1: TColorDialog;
     ActionList1: TActionList;
@@ -535,10 +521,9 @@ type
     procedure SpinEdit_ShapeAltitudeChange(Sender: TObject; AByUser: boolean);
     procedure SpinEdit_BrushSpacingChange(Sender: TObject; AByUser: boolean);
     procedure SpinEdit_TextSizeChange(Sender: TObject; AByUser: boolean);
-    procedure SpinEdit_TextureOpacityChange(Sender: TObject; AByUser: boolean);
     procedure SpinEdit_TextBlurChange(Sender: TObject; AByUser: boolean);
     procedure GridNb_SpinEditChange(Sender: TObject; AByUser: boolean);
-    procedure Image_CurrentTextureClick(Sender: TObject);
+    procedure VectorialFill_TextureClick(Sender: TObject);
     procedure PaintBox_PenPreviewPaint(Sender: TObject);
     procedure PaintBox_PictureMouseDown(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
@@ -595,11 +580,6 @@ type
     procedure Tool_PhongShapeRectangleClick(Sender: TObject);
     procedure Tool_PhongShapeRoundRectClick(Sender: TObject);
     procedure Tool_PhongShapeSphereClick(Sender: TObject);
-    procedure Tool_SinGradientClick(Sender: TObject);
-    procedure Combo_GradientColorspaceChange(Sender: TObject);
-    procedure ToolLoadTextureExecute(Sender: TObject);
-    procedure ToolNoTextureExecute(Sender: TObject);
-    procedure ToolNoTextureUpdate(Sender: TObject);
     procedure Tool_CapFlatClick(Sender: TObject);
     procedure Tool_CapRoundClick(Sender: TObject);
     procedure Tool_CapSquareClick(Sender: TObject);
@@ -644,19 +624,13 @@ type
       {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
     procedure SpinEdit_PenWidthChange(Sender: TObject; AByUser: boolean);
     procedure Tool_CloseShapeClick(Sender: TObject);
-    procedure Shape_BackColorMouseDown(Sender: TObject; Button: TMouseButton;
-      {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
-    procedure Shape_PenColorMouseDown(Sender: TObject; Button: TMouseButton;
-      {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
-    procedure SpinEdit_BackOpacityChange(Sender: TObject; AByUser: boolean);
-    procedure SpinEdit_PenOpacityChange(Sender: TObject; AByUser: boolean);
+    procedure VectorialFill_BackChooseColor({%H-}ASender: TObject; AButton: TMouseButton;
+              AColorIndex: integer; var {%H-}AColorValue: TBGRAPixel; out AHandled: boolean);
+    procedure VectorialFill_PenChooseColor({%H-}ASender: TObject; AButton: TMouseButton;
+              AColorIndex: integer; var {%H-}AColorValue: TBGRAPixel; out AHandled: boolean);
     procedure SpinEdit_ArrowSizeChange(Sender: TObject; AByUser: boolean);
     procedure SpinEdit_ToleranceChange(Sender: TObject; AByUser: boolean);
-    procedure Tool_DiamondGradientClick(Sender: TObject);
-    procedure Tool_LinearGradientClick(Sender: TObject);
     procedure Tool_ProgressiveFloodfillClick(Sender: TObject);
-    procedure Tool_RadialGradientClick(Sender: TObject);
-    procedure Tool_ReflectedGradientClick(Sender: TObject);
     procedure Tool_AliasingClick(Sender: TObject);
     procedure Tool_DrawShapeBorderClick(Sender: TObject);
     procedure Tool_FillShapeClick(Sender: TObject);
@@ -679,7 +653,6 @@ type
     procedure ManagerDeformationGridSizeChanged(Sender: TObject);
     procedure ManagerEraserChanged(Sender: TObject);
     procedure ManagerFloodFillOptionChanged(Sender: TObject);
-    procedure ManagerGradientChanged(Sender: TObject);
     procedure ManagerJoinStyleChanged(Sender: TObject);
     procedure ManagerLineCapChanged(Sender: TObject);
     procedure ManagerPerspectiveOptionChanged(Sender: TObject);
@@ -693,15 +666,15 @@ type
     procedure ManagerTextOutlineChanged(Sender: TObject);
     procedure ManagerTextPhongChanged(Sender: TObject);
     procedure ManagerTextShadowChanged(Sender: TObject);
-    procedure ManagerTextureChanged(Sender: TObject);
     procedure ManagerShapeOptionChanged(Sender: TObject);
     procedure ManagerToleranceChanged(Sender: TObject);
     procedure ManagerToolbarChanged(Sender: TObject);
+    procedure VectorialFill_BackChange(Sender: TObject);
+    procedure VectorialFill_PenChange(Sender: TObject);
   private
     { private declarations }
     FLayout: TMainFormLayout;
 
-    FActiveSpinEdit: TBCTrackbarUpdown;
     FLastWidth,FLastHeight,FLastBPP,FLastFrameIndex: integer;
     {$IFDEF LINUX}
     FTopMostHiddenMinimised: TTopMostInfo;
@@ -717,7 +690,7 @@ type
 
     FLoadInitialDir, FSaveInitialDir: string;
     FSaveSelectionInitialFilename: string;
-    FInPenWidthChange, FInBrush, FInShapeRatio, FInEraserOption,
+    FInFillChange, FInPenWidthChange, FInBrush, FInShapeRatio, FInEraserOption,
     FInSplineStyleChange, FInFloodfillOption, FInTolerance,
     FInTextFont, FInTextAlign, FInTextShadow,
     FInPerspective, FInGridNb: Boolean;
@@ -756,7 +729,6 @@ type
     procedure UpdateStatusText;
     procedure CreateToolbarElements;
     function GetCurrentToolAction: TAction;
-    procedure NoTextureIcon;
     procedure RegisterToolbarElements;
     procedure InitToolbarElements;
     procedure UpdateToolOptions;
@@ -771,7 +743,6 @@ type
     procedure UpdateTextShadowToolbar;
     procedure UpdateLineCapToolbar;
     procedure UpdateSplineStyleToolbar;
-    procedure UpdateGradientToolbar;
     procedure UpdatePenWidthToolbar;
     procedure UpdatePhongToolbar;
     procedure UpdateToleranceToolbar;
@@ -803,19 +774,17 @@ type
     procedure ToggleImageListVisible;
     procedure ToggleColorsVisible;
     procedure ToggleLayersVisible;
-    procedure ShowColorDialogForPen;
-    procedure ShowColorDialogForBack;
+    procedure ShowColorDialogFor(ATarget: TColorTarget);
     procedure ShowPenPreview(ShouldRepaint: boolean= False);
     procedure HidePenPreview(TimeMs: Integer = 300);
     procedure OnPaintHandler;
     procedure OnImageChangedHandler({%H-}AEvent: TLazPaintImageObservationEvent);
-    procedure UpdateTextureIcon;
     procedure LabelAutosize(ALabel: TLabel);
     procedure AskMergeSelection(ACaption: string);
     procedure ReleaseMouseButtons(Shift: TShiftState);
     procedure UpdateSpecialKeys({%H-}Shift: TShiftState);
     procedure UpdateCurveModeToolbar;
-    function ShowOpenTextureDialog: boolean;
+    function ShowOpenTextureDialog(ATargetFill: TVectorialFill): boolean;
     procedure ShowNoPicture;
     procedure SetCurveMode(AMode: TToolSplineMode);
     procedure IncreasePenSize;
@@ -868,7 +837,7 @@ type
       AAllowDuplicate: boolean = false; AEntryToLoad: integer = -1): Boolean;
     function PictureCanvasOfs: TPoint;
     procedure UpdateLineCapBar;
-    procedure UpdateColorToolbar(AUpdateColorDiff: boolean);
+    procedure UpdateFillToolbar(AUpdateColorDiff: boolean);
     procedure UpdateToolbar;
     function ChooseTool(Tool : TPaintToolType): boolean;
     procedure PictureSelectedLayerIndexChanged({%H-}sender: TLazPaintImage);
@@ -974,10 +943,10 @@ begin
   m.PredefinedMainMenus([MenuFile,MenuEdit,MenuSelect,MenuView, MenuImage,MenuRemoveTransparency,
     MenuColors,MenuTool, MenuFilter,MenuRadialBlur, MenuRender,MenuHelp]);
   m.Toolbars([Panel_Embedded,Panel_File,Panel_Zoom,Panel_Undo,Panel_CopyPaste,Panel_Coordinates,
-    Panel_Tool,Panel_Color,Panel_Texture,Panel_Grid,
+    Panel_Tool,Panel_ColorDiff,Panel_Grid,
     Panel_ShapeOption,Panel_PenWidth,Panel_PenStyle,Panel_JoinStyle,
     Panel_CloseShape,Panel_LineCap,Panel_Aliasing,
-    Panel_SplineStyle,Panel_Eraser,Panel_Tolerance,Panel_GradientType,Panel_Text,Panel_TextShadow,Panel_TextOutline,
+    Panel_SplineStyle,Panel_Eraser,Panel_Tolerance,Panel_Text,Panel_TextShadow,Panel_TextOutline,
     Panel_PhongShape,Panel_Altitude,Panel_PerspectiveOption,Panel_Brush,Panel_Ratio],Panel_ToolbarBackground);
   m.ImageList := LazPaintInstance.Icons[ScaleY(16, 96)];
   m.Apply;
@@ -1007,7 +976,6 @@ begin
   begin
     if ToolManager.OnToolChanged = @ManagerToolChanged then ToolManager.OnToolChanged := nil;
     if ToolManager.OnToolbarChanged = @ManagerToolbarChanged then ToolManager.OnToolbarChanged := nil;
-    if ToolManager.OnTextureChanged = @ManagerTextureChanged then ToolManager.OnTextureChanged := nil;
     if ToolManager.OnEraserChanged = @ManagerEraserChanged then ToolManager.OnEraserChanged := nil;
     if ToolManager.OnPenWidthChanged = @ManagerPenWidthChanged then ToolManager.OnPenWidthChanged := nil;
     if ToolManager.OnBrushChanged = @ManagerBrushChanged then ToolManager.OnBrushChanged := nil;
@@ -1023,7 +991,6 @@ begin
     if ToolManager.OnTextShadowChanged = @ManagerTextShadowChanged then ToolManager.OnTextShadowChanged := nil;
     if ToolManager.OnLineCapChanged = @ManagerLineCapChanged then ToolManager.OnLineCapChanged := nil;
     if ToolManager.OnSplineStyleChanged = @ManagerSplineStyleChanged then ToolManager.OnSplineStyleChanged := nil;
-    if ToolManager.OnGradientChanged = @ManagerGradientChanged then ToolManager.OnGradientChanged := nil;
     if ToolManager.OnPhongShapeChanged = @ManagerPhongShapeChanged then ToolManager.OnPhongShapeChanged := nil;
     if ToolManager.OnToleranceChanged = @ManagerToleranceChanged then ToolManager.OnToleranceChanged := nil;
     if ToolManager.OnDeformationGridChanged = @ManagerDeformationGridSizeChanged then ToolManager.OnDeformationGridChanged := nil;
@@ -1089,7 +1056,6 @@ begin
   ToolManager.SetCurrentToolType(ptHand);
   ToolManager.OnToolChanged  :=  @ManagerToolChanged;
   ToolManager.OnToolbarChanged:=@ManagerToolbarChanged;
-  ToolManager.OnTextureChanged := @ManagerTextureChanged;
   ToolManager.OnEraserChanged:=@ManagerEraserChanged;
   ToolManager.OnPenWidthChanged:= @ManagerPenWidthChanged;
   ToolManager.OnBrushChanged:=@ManagerBrushChanged;
@@ -1105,7 +1071,6 @@ begin
   ToolManager.OnTextShadowChanged:=@ManagerTextShadowChanged;
   ToolManager.OnLineCapChanged := @ManagerLineCapChanged;
   ToolManager.OnSplineStyleChanged:=@ManagerSplineStyleChanged;
-  ToolManager.OnGradientChanged:=@ManagerGradientChanged;
   ToolManager.OnPhongShapeChanged:=@ManagerPhongShapeChanged;
   ToolManager.OnToleranceChanged:=@ManagerToleranceChanged;
   ToolManager.OnDeformationGridChanged:=@ManagerDeformationGridSizeChanged;
@@ -1244,7 +1209,7 @@ begin
     else
       exit;
   end;
-  if (CurrentTool in[ptText,ptEditShape]) and TextSpinEditFocused then SpinEdit_PenOpacity.SetFocus;
+  if (CurrentTool in[ptText,ptEditShape]) and TextSpinEditFocused then VectorialFill_Pen.SetFocus;
   Image.CurrentState.LayeredBitmap.EditorFocused := true;
 
   FormMouseMovePos := Point(X,Y);
@@ -2721,27 +2686,6 @@ begin
   ToolLayerMapping.Enabled := Image.CurrentLayerVisible and Image.SelectionMaskEmpty;
 end;
 
-procedure TFMain.ToolLoadTextureExecute(Sender: TObject);
-begin
-  ShowOpenTextureDialog;
-end;
-
-procedure TFMain.ToolNoTextureExecute(Sender: TObject);
-begin
-  try
-    ToolManager.SetTexture(nil);
-  except
-    on ex:Exception do
-      LazPaintInstance.ShowError(RemoveTrail(ToolNoTexture.Hint),ex.Message);
-  end;
-end;
-
-procedure TFMain.ToolNoTextureUpdate(Sender: TObject);
-begin
-  ToolNoTexture.Enabled := (ToolManager.GetTexture <> nil)
-    and (CurrentTool <> ptTextureMapping);
-end;
-
 procedure TFMain.ViewColorsExecute(Sender: TObject);
 begin
   ToggleColorsVisible;
@@ -2991,27 +2935,30 @@ begin
                       FImageActions.RemoveSelection;
                       texMapBounds := newTexture.GetImageBounds;
                       BGRAReplace(newTexture, newTexture.GetPart(texMapBounds));
-                      ToolManager.SetTexture(newTexture);
+                      ToolManager.BackFill.SetTexture(newTexture, AffineMatrixIdentity,
+                        ToolManager.BackFill.TextureOpacity, ToolManager.BackFill.TextureRepetition);
                       newTexture.FreeReference;
                     end;
                   end;
                 end;
               end;
             end;
-            if (ToolManager.GetTexture = nil) or ToolManager.GetTexture.Empty then
+            if (ToolManager.BackFill.Texture = nil) or
+               ToolManager.BackFill.Texture.Empty then
             begin
               if useSelection then
               begin
                 Tool := ptHand;
                 result := srException;
               end else
-              if not ShowOpenTextureDialog then
+              if not ShowOpenTextureDialog(ToolManager.BackFill) then
               begin
                 Tool := ptHand;
                 result := srCancelledByUser;
               end
               else
-              if (ToolManager.GetTexture = nil) or ToolManager.GetTexture.Empty then
+              if (ToolManager.BackFill.Texture = nil) or
+                ToolManager.BackFill.Texture.Empty then
               begin
                 Tool := ptHand;
                 result := srException;
@@ -3822,7 +3769,7 @@ begin
   {$ENDIF}
 end;
 
-function TFMain.ShowOpenTextureDialog: boolean;
+function TFMain.ShowOpenTextureDialog(ATargetFill: TVectorialFill): boolean;
 var newTex: TBGRABitmap;
   texFilename: string;
   topMostInfo: TTopMostInfo;
@@ -3865,7 +3812,8 @@ begin
           newTex := LoadFlatImageUTF8(texFilename).bmp;
         if LazPaintInstance.BlackAndWhite then
           newTex.InplaceGrayscale;
-        ToolManager.SetTexture(newTex);
+        ATargetFill.SetTexture(newTex, AffineMatrixIdentity,
+          ATargetFill.TextureOpacity, ATargetFill.TextureRepetition);
         newTex.FreeReference;
         newTex := nil;
         result := true;
@@ -4153,6 +4101,8 @@ end;
 {****************************** Picture ************************}
 
 procedure TFMain.OnPaintHandler;
+var
+  ac: TWinControl;
 begin
   if FirstPaint then
   begin
@@ -4164,11 +4114,10 @@ begin
 
   if Assigned(FImageView) then FImageView.DoPaint(PictureCanvasOfs, FLayout.WorkArea, InShowNoPicture);
   DelayedPaintPicture:= false;
-  if FActiveSpinEdit <> nil then
-  begin
-    FActiveSpinEdit.DelayTimer;
-    FActiveSpinEdit := nil;
-  end;
+
+  ac := ActiveControl;
+  if ac is TBCTrackbarUpdown then
+    TBCTrackbarUpdown(ac).DelayTimer;
 
   InFormPaint := false;
   FLastPaintDate := Now;
@@ -4292,11 +4241,6 @@ begin
   UpdateFloodFillToolbar;
 end;
 
-procedure TFMain.ManagerGradientChanged(Sender: TObject);
-begin
-  UpdateGradientToolbar;
-end;
-
 procedure TFMain.ManagerJoinStyleChanged(Sender: TObject);
 begin
   UpdateJoinStyleToolbar;
@@ -4362,12 +4306,6 @@ begin
   UpdateTextShadowToolbar;
 end;
 
-procedure TFMain.ManagerTextureChanged(Sender: TObject);
-begin
-  UpdateTextureIcon;
-  SpinEdit_TextureOpacity.Value := ToolManager.TextureOpacity;
-end;
-
 procedure TFMain.ManagerShapeOptionChanged(Sender: TObject);
 begin
   UpdateToolOptions;

+ 47 - 5
lazpaint/lazpainttype.pas

@@ -5,8 +5,8 @@ unit LazPaintType;
 interface
 
 uses
-  Classes, SysUtils, Inifiles, BGRABitmap, BGRABitmapTypes, uconfig, uimage, utool, Forms, BGRALayers, Graphics, Menus,
-  uscripting, Dialogs, Controls
+  Classes, SysUtils, Inifiles, BGRABitmap, BGRABitmapTypes, UConfig, UImage, UTool, Forms, BGRALayers, Graphics, Menus,
+  UScripting, Dialogs, Controls
   {$IFDEF LINUX}, InterfaceBase{$ENDIF};
 
 const
@@ -107,7 +107,8 @@ function IsOnlyRenderChange(const ARect:TRect): boolean;
 
 type
     ArrayOfBGRABitmap = array of TBGRABitmap;
-    TColorTarget = (ctForeColor, ctBackColor);
+    TColorTarget = (ctForeColorSolid, ctForeColorStartGrad, ctForeColorEndGrad,
+                    ctBackColorSolid, ctBackColorStartGrad, ctBackColorEndGrad);
     TFlipOption = (foAuto, foWholePicture, foSelection, foCurrentLayer);
 
     PImageEntry = ^TImageEntry;
@@ -217,7 +218,7 @@ type
     procedure UseConfig(ini: TInifile); virtual; abstract;
     procedure AssignBitmap(bmp: TBGRABitmap); virtual; abstract;
     procedure EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil; ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil; AOnExit: TLazPaintInstanceEvent = nil; ABlackAndWhite : boolean = false); virtual; abstract;
-    procedure EditTexture; virtual; abstract;
+    function EditTexture(ASource: TBGRABitmap): TBGRABitmap; virtual; abstract;
     procedure EditSelection; virtual; abstract;
     function ProcessCommandLine: boolean; virtual; abstract;
     function ProcessCommands(commands: TStringList): boolean; virtual; abstract;
@@ -235,6 +236,8 @@ type
     function RunScript(AFilename: string): boolean; virtual; abstract;
     procedure ColorFromFChooseColor; virtual; abstract;
     procedure ColorToFChooseColor; virtual; abstract;
+    function GetColor(ATarget: TColorTarget): TBGRAPixel;
+    procedure SetColor(ATarget: TColorTarget; AColor: TBGRAPixel);
     function ShowSaveOptionDlg(AParameters: TVariableSet; AOutputFilenameUTF8: string; ASkipOptions: boolean): boolean; virtual; abstract;
     function ShowColorIntensityDlg(AParameters: TVariableSet): TScriptResult; virtual; abstract;
     function ShowColorLightnessDlg(AParameters: TVariableSet): TScriptResult; virtual; abstract;
@@ -346,7 +349,7 @@ function CSSToPascalCase(AIdentifier: string): string;
 
 implementation
 
-uses LCLType, BGRAUTF8, LCLIntf, FileUtil, UResourceStrings;
+uses LCLType, BGRAUTF8, LCLIntf, FileUtil, UResourceStrings, LCVectorialFill;
 
 function LazPaintVersionStr: string;
 var numbers: TStringList;
@@ -632,6 +635,45 @@ begin
   result := 1;
 end;
 
+function TLazPaintCustomInstance.GetColor(ATarget: TColorTarget): TBGRAPixel;
+begin
+  case ATarget of
+    ctForeColorSolid: result := ToolManager.ForeColor;
+    ctForeColorStartGrad: if ToolManager.ForeFill.FillType = vftGradient then
+                            result := ToolManager.ForeFill.Gradient.StartColor
+                          else result := ToolManager.ForeColor;
+    ctForeColorEndGrad: if ToolManager.ForeFill.FillType = vftGradient then
+                          result := ToolManager.ForeFill.Gradient.EndColor
+                        else result := ToolManager.ForeColor;
+    ctBackColorSolid: result := ToolManager.BackColor;
+    ctBackColorStartGrad: if ToolManager.BackFill.FillType = vftGradient then
+                            result := ToolManager.BackFill.Gradient.StartColor
+                          else result := ToolManager.BackColor;
+    ctBackColorEndGrad: if ToolManager.BackFill.FillType = vftGradient then
+                          result := ToolManager.BackFill.Gradient.EndColor
+                        else result := ToolManager.BackColor;
+  else
+    result := BGRAPixelTransparent;
+  end;
+end;
+
+procedure TLazPaintCustomInstance.SetColor(ATarget: TColorTarget;
+  AColor: TBGRAPixel);
+begin
+  case ATarget of
+    ctForeColorSolid: ToolManager.ForeColor := AColor;
+    ctForeColorStartGrad: if ToolManager.ForeFill.FillType = vftGradient then
+                            ToolManager.ForeFill.Gradient.StartColor := AColor;
+    ctForeColorEndGrad: if ToolManager.ForeFill.FillType = vftGradient then
+                          ToolManager.ForeFill.Gradient.EndColor := AColor;
+    ctBackColorSolid: ToolManager.BackColor := AColor;
+    ctBackColorStartGrad: if ToolManager.BackFill.FillType = vftGradient then
+                            ToolManager.BackFill.Gradient.StartColor := AColor;
+    ctBackColorEndGrad: if ToolManager.BackFill.FillType = vftGradient then
+                          ToolManager.BackFill.Gradient.EndColor := AColor;
+  end;
+end;
+
 procedure TLazPaintCustomInstance.SetBlackAndWhite(AValue: boolean);
 begin
   if FBlackAndWhite=AValue then Exit;

+ 107 - 204
lazpaint/maintoolbar.inc

@@ -1,5 +1,5 @@
 procedure TFMain.CreateToolbarElements;
-var ci: TBGRAColorInterpolation;
+var
   ps: TPenStyle;
 begin
   if FToolbarElementsInitDone then exit;
@@ -8,10 +8,13 @@ begin
   Panel_ToolbarBackground.PopupMenu := PopupToolbar;
   Perspective_Repeat.OnClick := @Perspective_RepeatClick;
   Perspective_TwoPlanes.OnClick := @Perspective_TwoPlanesClick;
-  Shape_PenColor.OnMouseDown := @Shape_PenColorMouseDown;
-  Shape_BackColor.OnMouseDown := @Shape_BackColorMouseDown;
+  VectorialFill_Pen.OnChooseColor := @VectorialFill_PenChooseColor;
+  VectorialFill_Back.OnChooseColor := @VectorialFill_BackChooseColor;
+  VectorialFill_Pen.OnTextureClick := @VectorialFill_TextureClick;
+  VectorialFill_Back.OnTextureClick := @VectorialFill_TextureClick;
+  VectorialFill_Pen.OnFillChange:=@VectorialFill_PenChange;
+  VectorialFill_Back.OnFillChange:=@VectorialFill_BackChange;
   Image_SwapColors.OnMouseDown := @Image_SwapColorsMouseDown;
-  Image_CurrentTexture.OnClick := @Image_CurrentTextureClick;
   Tool_DrawShapeBorder.OnClick := @Tool_DrawShapeBorderClick;
   Tool_Aliasing.OnClick := @Tool_AliasingClick;
   Tool_FillShape.OnClick := @Tool_FillShapeClick;
@@ -54,14 +57,6 @@ begin
   PaintBox_PenPreview.OnMouseMove := @Panel_PenWidthMouseMove;
   PaintBox_PenPreview.OnMouseDown := @PaintBox_PenPreviewMouseDown;
   PaintBox_PenPreview.OnPaint := @PaintBox_PenPreviewPaint;
-  Tool_LinearGradient.OnClick := @Tool_LinearGradientClick;
-  Tool_ReflectedGradient.OnClick := @Tool_ReflectedGradientClick;
-  Tool_DiamondGradient.OnClick := @Tool_DiamondGradientClick;
-  Tool_RadialGradient.OnClick := @Tool_RadialGradientClick;
-  Tool_SinGradient.OnClick := @Tool_SinGradientClick;
-  for ci := low(TBGRAColorInterpolation) to high(TBGRAColorInterpolation) do
-    Combo_GradientColorspace.Items.Add(GradientColorSpaceToDisplay(ci));
-  Combo_GradientColorspace.OnChange := @Combo_GradientColorspaceChange;
   Tool_PhongShapeRectangle.OnClick := @Tool_PhongShapeRectangleClick;
   Tool_PhongShapeRoundRect.OnClick := @Tool_PhongShapeRoundRectClick;
   Tool_PhongShapeSphere.OnClick := @Tool_PhongShapeSphereClick;
@@ -84,14 +79,6 @@ begin
   Combo_Ratio.OnChange := @Combo_RatioChange;
 
   Panel_LineCap_FullSize := Panel_LineCap.Width;
-  SpinEdit_PenOpacity.Increment := 15;
-  SpinEdit_PenOpacity.OnChange := @SpinEdit_PenOpacityChange;
-
-  SpinEdit_BackOpacity.Increment := 15;
-  SpinEdit_BackOpacity.OnChange := @SpinEdit_BackOpacityChange;
-
-  SpinEdit_TextureOpacity.Increment := 15;
-  SpinEdit_TextureOpacity.OnChange := @SpinEdit_TextureOpacityChange;
 
   SpinEdit_Eraser.Increment := 15;
   SpinEdit_Eraser.OnChange := @SpinEdit_EraserChange;
@@ -207,7 +194,6 @@ begin
   LabelAutosize(Label_Brush);
   LabelAutosize(Label_Spacing);
   Image_SwapColors.Hint := Image_SwapColors.Hint + ' (X)';
-  NoTextureIcon;
 
   Tool_CurveModeAuto.Hint := Tool_CurveModeAuto.Hint + ' (A)';
   Tool_CurveModeAngle.Hint := Tool_CurveModeAngle.Hint + ' (X)';
@@ -275,7 +261,6 @@ begin
   ToolManager.LineCapControls.Add(Panel_LineCap);
   ToolManager.EraserControls.Add(Panel_Eraser);
   ToolManager.ToleranceControls.Add(Panel_Tolerance);
-  ToolManager.GradientControls.Add(Panel_GradientType);
   ToolManager.DeformationControls.Add(Panel_Grid);
   ToolManager.TextControls.Add(Panel_Text);
   ToolManager.TextShadowControls.Add(Panel_TextShadow);
@@ -283,8 +268,7 @@ begin
   ToolManager.PhongControls.Add(Panel_PhongShape);
   ToolManager.AltitudeControls.Add(Panel_Altitude);
   ToolManager.PerspectiveControls.Add(Panel_PerspectiveOption);
-  ToolManager.PenColorControls.Add(Panel_Color);
-  ToolManager.TextureControls.Add(Panel_Texture);
+  ToolManager.FillControls.Add(Panel_ColorDiff);
   ToolManager.BrushControls.Add(Panel_Brush);
   ToolManager.RatioControls.Add(Panel_Ratio);
 end;
@@ -315,18 +299,6 @@ begin
   ComboBox_PenStyle.ItemIndex := ord(ToolManager.PenStyle);
 end;
 
-procedure TFMain.UpdateGradientToolbar;
-begin
-  case ToolManager.GradientType of
-  gtLinear: Tool_LinearGradient.Down := true;
-  gtReflected: Tool_ReflectedGradient.Down := true;
-  gtDiamond: Tool_DiamondGradient.Down := true;
-  gtRadial: Tool_RadialGradient.Down := true;
-  end;
-  Tool_SinGradient.Down := ToolManager.GradientSine;
-  Combo_GradientColorspace.ItemIndex := Combo_GradientColorspace.Items.IndexOf(GradientColorSpaceToDisplay(ToolManager.GradientColorspace));
-end;
-
 procedure TFMain.UpdatePenWidthToolbar;
 begin
   if FInPenWidthChange then exit;
@@ -470,7 +442,7 @@ begin
   Panel_File.Visible := not LazPaintInstance.Embedded;
 
   UpdateToolImage;
-  UpdateColorToolbar(true);
+  UpdateFillToolbar(true);
   UpdatePenWidthToolbar;
   UpdatePenStyleToolbar;
   UpdateJoinStyleToolbar;
@@ -485,7 +457,6 @@ begin
   UpdateToleranceToolbar;
   UpdateFloodfillToolbar;
   UpdatePerspectiveToolbar;
-  UpdateGradientToolbar;
   UpdateDeformationGridToolbar;
   UpdateSplineStyleToolbar;
   UpdateCurveModeToolbar;
@@ -493,7 +464,6 @@ begin
   UpdateTextPhongToolbar;
   UpdateTextFontToolbar;
   UpdateTextShadowToolbar;
-  SpinEdit_TextureOpacity.Value := ToolManager.TextureOpacity;
   UpdatePhongToolbar;
   ComboBox_BrushSelect.Clear;
   for i := 0 to ToolManager.BrushCount-1 do
@@ -502,32 +472,19 @@ begin
     ComboBox_BrushSelect.ItemIndex := 0;
 end;
 
-procedure TFMain.UpdateColorToolbar(AUpdateColorDiff: boolean);
+procedure TFMain.UpdateFillToolbar(AUpdateColorDiff: boolean);
 var
   colorChange: boolean;
+  prevPenColor, prevBackColor, newPenColor, newBackColor: TBGRAPixel;
 begin
-  colorChange:= false;
-  if Shape_PenColor.Brush.Color <> BGRAToColor(ToolManager.ForeColor) then
-  begin
-    Shape_PenColor.Brush.Color := BGRAToColor(ToolManager.ForeColor);
-    colorChange:= true;
-  end;
-  if SpinEdit_PenOpacity.Value <> ToolManager.ForeColor.alpha then
-  begin
-    SpinEdit_PenOpacity.Value := ToolManager.ForeColor.alpha;
-    colorChange:= true;
-  end;
+  prevPenColor := VectorialFill_Pen.AverageColor;
+  prevBackColor := VectorialFill_Back.AverageColor;
+  VectorialFill_Pen.AssignFill(ToolManager.ForeFill);
+  VectorialFill_Back.AssignFill(ToolManager.BackFill);
+  newPenColor := VectorialFill_Pen.AverageColor;
+  newBackColor := VectorialFill_Back.AverageColor;
 
-  if Shape_BackColor.Brush.Color <> BGRAToColor(ToolManager.BackColor) then
-  begin
-    Shape_BackColor.Brush.Color := BGRAToColor(ToolManager.BackColor);
-    colorChange:= true;
-  end;
-  if SpinEdit_BackOpacity.Value <> ToolManager.BackColor.alpha then
-  begin
-    SpinEdit_BackOpacity.Value := ToolManager.BackColor.alpha;
-    colorChange:= true;
-  end;
+  colorChange := (newPenColor <> prevPenColor) or (newBackColor <> prevBackColor);
 
   if colorChange or AUpdateColorDiff then
   begin
@@ -605,33 +562,6 @@ begin
   end;
 end;
 
-procedure TFMain.NoTextureIcon;
-var lIcon: TBitmap;
-begin
-  Image_CurrentTexture.Picture.Clear;
-  lIcon := TBitmap.Create;
-  ImageList16.GetBitmap(56,lIcon);
-  Image_CurrentTexture.Picture.Assign(lIcon);
-  lIcon.Free;
-end;
-
-procedure TFMain.UpdateTextureIcon;
-var
-  IconBGRA: TBGRABitmap;
-  IconBmp: TBitmap;
-begin
-  if ToolManager.GetTexture = nil then
-  begin
-    NoTextureIcon;
-    exit;
-  end;
-  IconBGRA := ToolManager.GetTexture.Resample(Image_CurrentTexture.Width,Image_CurrentTexture.Height) as TBGRABitmap;
-  IconBmp := IconBGRA.MakeBitmapCopy(ColorToRGB(clBtnFace));
-  FreeAndNil(IconBGRA);
-  Image_CurrentTexture.Picture.Assign(IconBmp);
-  IconBmp.Free;
-end;
-
 function TFMain.TextSpinEditFocused: boolean;
 begin
   result := SpinEdit_TextSize.Focused or SpinEdit_TextBlur.Focused or SpinEdit_TextShadowX.Focused or
@@ -694,18 +624,6 @@ begin
       SpinEdit_TextSize.Value, ToolManager.TextFontStyle);
     UpdateTextSizeIncrement;
     FInTextFont:= false;
-    FActiveSpinEdit := SpinEdit_TextSize;
-  end;
-end;
-
-procedure TFMain.SpinEdit_TextureOpacityChange(Sender: TObject; AByUser: boolean);
-begin
-  if AByUser and initialized then
-  begin
-    if ToolManager.TextureOpacity = SpinEdit_TextureOpacity.Value then exit;
-    ToolManager.TextureOpacity := SpinEdit_TextureOpacity.Value;
-    UpdateEditPicture(True);
-    FActiveSpinEdit := SpinEdit_TextureOpacity;
   end;
 end;
 
@@ -718,7 +636,6 @@ begin
     ToolManager.TextShadowBlurRadius := SpinEdit_TextBlur.Value/PenWidthFactor;
     FInTextShadow := false;
     UpdateEditPicture(True);
-    FActiveSpinEdit := SpinEdit_TextBlur;
   end;
 end;
 
@@ -761,7 +678,6 @@ begin
     ToolManager.TextShadowOffset := Point(SpinEdit_TextShadowX.Value, ToolManager.TextShadowOffset.Y);
     FInTextShadow := false;
     UpdateEditPicture(True);
-    FActiveSpinEdit := SpinEdit_TextShadowX;
   end;
 end;
 
@@ -774,7 +690,6 @@ begin
     ToolManager.TextShadowOffset := Point(ToolManager.TextShadowOffset.X, SpinEdit_TextShadowY.Value);
     FInTextShadow := false;
     UpdateEditPicture(True);
-    FActiveSpinEdit := SpinEdit_TextShadowY;
   end;
 end;
 
@@ -812,62 +727,87 @@ begin
   UpdateEditPicture;
 end;
 
-procedure TFMain.Shape_PenColorMouseDown(Sender: TObject; Button: TMouseButton;
-  Shift: TShiftState; X, Y: Integer);
-begin
-  if LazPaintInstance.ChooseColorVisible and (Button = mbLeft) then
-    LazPaintInstance.ChooseColorTarget := ctForeColor
-  else
-    ShowColorDialogForPen;
+procedure TFMain.VectorialFill_BackChange(Sender: TObject);
+begin
+  if FInFillChange then exit;
+  FInFillChange:= true;
+  ToolManager.BackFill.Assign(VectorialFill_Back);
+  if (VectorialFill_Back.FillType = vftSolid) and
+     (LazPaintInstance.ChooseColorTarget in [ctBackColorStartGrad,ctBackColorEndGrad]) then
+    LazPaintInstance.ChooseColorTarget := ctBackColorSolid else
+  if (VectorialFill_Back.FillType = vftGradient) and
+     (LazPaintInstance.ChooseColorTarget = ctBackColorSolid) then
+    LazPaintInstance.ChooseColorTarget := ctBackColorStartGrad else
+  if (VectorialFill_Back.FillType in [vftSolid,vftGradient]) and
+     (LazPaintInstance.ChooseColorTarget in
+     [ctBackColorSolid,ctBackColorStartGrad,ctBackColorEndGrad]) then
+      LazPaintInstance.ColorToFChooseColor;
+  UpdateEditPicture;
+  FInFillChange:= false;
+end;
+
+procedure TFMain.VectorialFill_PenChange(Sender: TObject);
+begin
+  if FInFillChange then exit;
+  FInFillChange:= true;
+  ToolManager.ForeFill.Assign(VectorialFill_Pen);
+  if (VectorialFill_Pen.FillType = vftSolid) and
+     (LazPaintInstance.ChooseColorTarget in [ctForeColorStartGrad,ctForeColorEndGrad]) then
+    LazPaintInstance.ChooseColorTarget := ctForeColorSolid else
+  if (VectorialFill_Pen.FillType = vftGradient) and
+     (LazPaintInstance.ChooseColorTarget = ctForeColorSolid) then
+    LazPaintInstance.ChooseColorTarget := ctForeColorStartGrad else
+  if (VectorialFill_Pen.FillType in [vftSolid,vftGradient]) and
+     (LazPaintInstance.ChooseColorTarget in
+     [ctForeColorSolid,ctForeColorStartGrad,ctForeColorEndGrad]) then
+      LazPaintInstance.ColorToFChooseColor;
+  UpdateEditPicture;
+  FInFillChange:= false;
 end;
 
-procedure TFMain.ShowColorDialogForPen;
+procedure TFMain.VectorialFill_PenChooseColor(ASender: TObject; AButton: TMouseButton;
+  AColorIndex: integer; var AColorValue: TBGRAPixel; out AHandled: boolean);
+var
+  target: TColorTarget;
 begin
-  ColorDialog1.Color := BGRAToColor(ToolManager.ForeColor);
-  if ColorDialog1.Execute then
-  begin
-    ToolManager.ForeColor := ColorToBGRA(ColorDialog1.Color,ToolManager.ForeColor.alpha);
-    LazPaintInstance.ColorToFChooseColor;
-    UpdateEditPicture;
+  AHandled := true;
+  case AColorIndex of
+    -1: target := ctForeColorSolid;
+    0: target := ctForeColorStartGrad;
+    1: target := ctForeColorEndGrad;
+    else exit;
   end;
+  if LazPaintInstance.ChooseColorVisible and (AButton = mbLeft) then
+    LazPaintInstance.ChooseColorTarget := target
+  else
+    ShowColorDialogFor(target);
 end;
 
-procedure TFMain.SpinEdit_PenOpacityChange(Sender: TObject; AByUser: boolean);
+procedure TFMain.VectorialFill_BackChooseColor(ASender: TObject; AButton: TMouseButton;
+  AColorIndex: integer; var AColorValue: TBGRAPixel; out AHandled: boolean);
+var
+  target: TColorTarget;
 begin
-  if AByUser and initialized then
-  begin
-    if ToolManager.ForeColor.alpha = SpinEdit_PenOpacity.value then exit;
-    with ToolManager.ForeColor do
-      ToolManager.ForeColor := BGRA(red,green,blue,SpinEdit_PenOpacity.value);
-    LazPaintInstance.ColorToFChooseColor;
-    UpdateEditPicture;
+  AHandled := true;
+  case AColorIndex of
+    -1: target := ctBackColorSolid;
+    0: target := ctBackColorStartGrad;
+    1: target := ctBackColorEndGrad;
+    else exit;
   end;
-end;
-
-procedure TFMain.Shape_BackColorMouseDown(Sender: TObject;
-  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-begin
-  if LazPaintInstance.ChooseColorVisible and (Button = mbLeft) then
-    LazPaintInstance.ChooseColorTarget := ctBackColor
+  if LazPaintInstance.ChooseColorVisible and (AButton = mbLeft) then
+    LazPaintInstance.ChooseColorTarget := target
   else
-    ShowColorDialogForBack;
+    ShowColorDialogFor(target);
 end;
 
-procedure TFMain.ShowColorDialogForBack;
+procedure TFMain.ShowColorDialogFor(ATarget: TColorTarget);
+var sourceColor: TBGRAPixel;
 begin
-  ColorDialog1.Color := BGRAToColor(ToolManager.BackColor);
+  sourceColor := LazPaintInstance.GetColor(ATarget);
+  ColorDialog1.Color := sourceColor.ToColor;
   if ColorDialog1.Execute then
-    ToolManager.BackColor := ColorToBGRA(ColorDialog1.Color,ToolManager.BackColor.alpha);
-end;
-
-procedure TFMain.SpinEdit_BackOpacityChange(Sender: TObject; AByUser: boolean);
-begin
-  if AByUser and initialized then
-  begin
-    if ToolManager.BackColor.alpha = SpinEdit_BackOpacity.value then exit;
-    with ToolManager.BackColor do
-      ToolManager.BackColor := BGRA(red,green,blue,SpinEdit_BackOpacity.value);
-  end;
+    LazPaintInstance.SetColor(ATarget, ColorToBGRA(ColorDialog1.Color,sourceColor.alpha));
 end;
 
 procedure TFMain.Image_SwapColorsMouseDown(Sender: TObject; Button: TMouseButton;
@@ -887,10 +827,27 @@ begin
   end;
 end;
 
-procedure TFMain.Image_CurrentTextureClick(Sender: TObject);
-begin
-  LazPaintInstance.EditTexture;
-  UpdateEditPicture;
+procedure TFMain.VectorialFill_TextureClick(Sender: TObject);
+var
+  vfc: TLCVectorialFillControl;
+  newTex: TBGRABitmap;
+  target: TVectorialFill;
+begin
+  vfc := Sender as TLCVectorialFillControl;
+  newTex := LazPaintInstance.EditTexture(vfc.Texture);
+  if Assigned(newTex) then
+  begin
+    FInFillChange:= true;
+    vfc.Texture := newTex;
+    FInFillChange:= false;
+    if vfc = VectorialFill_Back then target := ToolManager.BackFill
+    else if vfc = VectorialFill_Pen then target := ToolManager.ForeFill
+    else target := nil;
+    if Assigned(target) then
+      target.SetTexture(newTex, AffineMatrixIdentity, target.TextureOpacity, target.TextureRepetition);
+    newTex.FreeReference;
+    UpdateEditPicture;
+  end;
 end;
 
 procedure TFMain.Tool_AliasingClick(Sender: TObject);
@@ -1450,60 +1407,6 @@ begin
   ToolHotSpot.Visible := Image.IsCursor;
 end;
 
-procedure TFMain.Tool_LinearGradientClick(Sender: TObject);
-begin
-  if Tool_LinearGradient.Down then
-  begin
-    ToolManager.GradientType := gtLinear;
-    UpdateEditPicture;
-  end;
-end;
-
-procedure TFMain.Tool_ReflectedGradientClick(Sender: TObject);
-begin
-  if Tool_ReflectedGradient.Down then
-  begin
-    ToolManager.GradientType := gtReflected;
-    UpdateEditPicture;
-  end;
-end;
-
-procedure TFMain.Tool_DiamondGradientClick(Sender: TObject);
-begin
-  if Tool_DiamondGradient.Down then
-  begin
-    ToolManager.GradientType := gtDiamond;
-    UpdateEditPicture;
-  end;
-end;
-
-procedure TFMain.Tool_RadialGradientClick(Sender: TObject);
-begin
-  if Tool_RadialGradient.Down then
-  begin
-    ToolManager.GradientType := gtRadial;
-    UpdateEditPicture;
-  end;
-end;
-
-procedure TFMain.Tool_SinGradientClick(Sender: TObject);
-begin
-  if initialized then
-  begin
-    ToolManager.GradientSine := Tool_SinGradient.Down;
-    UpdateEditPicture;
-  end;
-end;
-
-procedure TFMain.Combo_GradientColorspaceChange(Sender: TObject);
-begin
-  if initialized then
-  begin
-    ToolManager.GradientColorspace := DisplayToGradientColorSpace(Combo_GradientColorspace.Text);
-    UpdateEditPicture(True);
-  end;
-end;
-
 procedure TFMain.SpinEdit_PhongBorderSizeChange(Sender: TObject; AByUser: boolean);
 begin
   if AByUser and initialized then

+ 259 - 197
lazpaint/tools/utool.pas

@@ -7,7 +7,8 @@ interface
 uses
   Classes, Types, SysUtils, Graphics, BGRABitmap, BGRABitmapTypes, uimage, UImageType,
   ULayerAction, LCLType, Controls, UBrushType, UConfig, LCVectorPolyShapes,
-  BGRAGradientScanner, BGRALayerOriginal, LCVectorRectShapes, UScripting;
+  BGRAGradientScanner, BGRALayerOriginal, LCVectorRectShapes, UScripting,
+  LCVectorialFill, BGRAGradientOriginal;
 
 const
   VK_SNAP = {$IFDEF DARWIN}VK_LWIN{$ELSE}VK_CONTROL{$ENDIF};
@@ -34,9 +35,9 @@ const
 function StrToPaintToolType(const s: ansistring): TPaintToolType;
 
 type
-  TContextualToolbar = (ctColor, ctPenWidth, ctPenStyle, ctAliasing, ctShape, ctEraserOption, ctTolerance,
-    ctGradient, ctDeformation, ctCloseShape, ctLineCap, ctJoinStyle, ctSplineStyle, ctText, ctTextShadow,
-    ctPhong, ctAltitude, ctPerspective, ctBrush, ctTexture, ctRatio);
+  TContextualToolbar = (ctFill, ctPenWidth, ctPenStyle, ctAliasing, ctShape, ctEraserOption, ctTolerance,
+    ctDeformation, ctCloseShape, ctLineCap, ctJoinStyle, ctSplineStyle, ctText, ctTextShadow,
+    ctPhong, ctAltitude, ctPerspective, ctBrush, ctRatio);
   TContextualToolbars = set of TContextualToolbar;
 
 type
@@ -109,6 +110,7 @@ type
     function ToolUp: TRect; virtual;
     function ToolCommand({%H-}ACommand: TToolCommand): boolean; virtual;
     function ToolProvideCommand({%H-}ACommand: TToolCommand): boolean; virtual;
+    function SuggestGradientBox: TAffineBox; virtual;
     function GetContextualToolbars: TContextualToolbars; virtual;
     function GetToolDrawingLayer: TBGRABitmap;
     procedure RestoreBackupDrawingLayer;
@@ -162,7 +164,7 @@ type
     FBlackAndWhite: boolean;
     FScriptContext: TScriptContext;
     FToolPressure: single;
-    FInTool: boolean;
+    FInTool, FInToolUpdate: boolean;
     FCurrentTool : TGenericTool;
     FCurrentToolType : TPaintToolType;
     FToolCurrentCursorPos: TPointF;
@@ -173,12 +175,10 @@ type
     FOnToolbarChanged: TNotifyEvent;
     FOnPopupToolHandler: TOnPopupToolHandler;
 
-    FForeColor, FBackColor: TBGRAPixel;
+    FForeFill, FBackFill: TVectorialFill;
+    FForeLastGradient, FBackLastGradient: TBGRALayerGradientOriginal;
     FEraserMode: TEraserMode;
     FEraserAlpha: byte;
-    FTexture: TBGRABitmap;
-    FTextureAfterAlpha: TBGRABitmap;
-    FTextureOpactiy: byte;
     FBrushInfoList: TList;
     FBrushInfoListChanged: boolean;
     FBrushIndex: integer;
@@ -203,9 +203,6 @@ type
     FArrowStart,FArrowEnd: TArrowKind;
     FArrowSize: TPointF;
     FSplineStyle: TSplineStyle;
-    FGradientType: TGradientType;
-    FGradientSine: boolean;
-    FGradientColorspace: TBGRAColorInterpolation;
     FPhongShapeAltitude: integer;
     FPhongShapeBorderSize: integer;
     FPhongShapeKind: TPhongShapeKind;
@@ -216,9 +213,8 @@ type
     FPerspectiveOptions: TPerspectiveOptions;
     FShapeRatio: Single;
 
-    FOnColorChanged: TNotifyEvent;
+    FOnFillChanged: TNotifyEvent;
     FOnEraserChanged: TNotifyEvent;
-    FOnGradientChanged: TNotifyEvent;
     FOnJoinStyleChanged: TNotifyEvent;
     FOnLineCapChanged: TNotifyEvent;
     FOnPenStyleChanged: TNotifyEvent;
@@ -230,13 +226,14 @@ type
     FOnTextOutlineChanged: TNotifyEvent;
     FOnTextPhongChanged, FOnLightChanged: TNotifyEvent;
     FOnTextShadowChanged: TNotifyEvent;
-    FOnTextureChanged: TNotifyEvent;
     FOnShapeOptionChanged, FOnShapeRatioChanged: TNotifyEvent;
     FOnDeformationGridChanged: TNotifyEvent;
     FOnToleranceChanged: TNotifyEvent;
     FOnFloodFillOptionChanged: TNotifyEvent;
     FOnPerspectiveOptionChanged: TNotifyEvent;
 
+    procedure BackFillChange(ASender: TObject;
+      var ADiff: TCustomVectorialFillDiff);
     function GetCursor: TCursor;
     function GetBackColor: TBGRAPixel;
     function GetBrushAt(AIndex: integer): TLazPaintBrush;
@@ -253,6 +250,8 @@ type
     function GetTextFontSize: single;
     function GetTextFontStyle: TFontStyles;
     function GetTextureOpacity: byte;
+    procedure ForeFillChange({%H-}ASender: TObject;
+      var ADiff: TCustomVectorialFillDiff);
     function ScriptGetAliasing(AVars: TVariableSet): TScriptResult;
     function ScriptGetArrowEnd(AVars: TVariableSet): TScriptResult;
     function ScriptGetArrowSize(AVars: TVariableSet): TScriptResult;
@@ -269,13 +268,19 @@ type
     function ScriptGetFontName(AVars: TVariableSet): TScriptResult;
     function ScriptGetFontSize(AVars: TVariableSet): TScriptResult;
     function ScriptGetFontStyle(AVars: TVariableSet): TScriptResult;
-    function ScriptGetGradientColorspace(AVars: TVariableSet): TScriptResult;
-    function ScriptGetGradientSine(AVars: TVariableSet): TScriptResult;
-    function ScriptGetGradientType(AVars: TVariableSet): TScriptResult;
+    function ScriptGetGradientColorspace(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptGetGradientRepetition(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptGetGradientType(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptGetBackGradientColorspace(AVars: TVariableSet): TScriptResult;
+    function ScriptGetBackGradientRepetition(AVars: TVariableSet): TScriptResult;
+    function ScriptGetBackGradientType(AVars: TVariableSet): TScriptResult;
+    function ScriptGetForeGradientColorspace(AVars: TVariableSet): TScriptResult;
+    function ScriptGetForeGradientRepetition(AVars: TVariableSet): TScriptResult;
+    function ScriptGetForeGradientType(AVars: TVariableSet): TScriptResult;
     function ScriptGetJoinStyle(AVars: TVariableSet): TScriptResult;
     function ScriptGetLightPosition(AVars: TVariableSet): TScriptResult;
     function ScriptGetLineCap(AVars: TVariableSet): TScriptResult;
-    function ScriptGetPenColor(AVars: TVariableSet): TScriptResult;
+    function ScriptGetForeColor(AVars: TVariableSet): TScriptResult;
     function ScriptGetPenStyle(AVars: TVariableSet): TScriptResult;
     function ScriptGetPenWidth(AVars: TVariableSet): TScriptResult;
     function ScriptGetPerspectiveOptions(AVars: TVariableSet): TScriptResult;
@@ -304,13 +309,19 @@ type
     function ScriptSetFontName(AVars: TVariableSet): TScriptResult;
     function ScriptSetFontSize(AVars: TVariableSet): TScriptResult;
     function ScriptSetFontStyle(AVars: TVariableSet): TScriptResult;
-    function ScriptSetGradientColorspace(AVars: TVariableSet): TScriptResult;
-    function ScriptSetGradientSine(AVars: TVariableSet): TScriptResult;
-    function ScriptSetGradientType(AVars: TVariableSet): TScriptResult;
+    function ScriptSetGradientColorspace(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptSetGradientRepetition(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptSetGradientType(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+    function ScriptSetBackGradientColorspace(AVars: TVariableSet): TScriptResult;
+    function ScriptSetBackGradientRepetition(AVars: TVariableSet): TScriptResult;
+    function ScriptSetBackGradientType(AVars: TVariableSet): TScriptResult;
+    function ScriptSetForeGradientColorspace(AVars: TVariableSet): TScriptResult;
+    function ScriptSetForeGradientRepetition(AVars: TVariableSet): TScriptResult;
+    function ScriptSetForeGradientType(AVars: TVariableSet): TScriptResult;
     function ScriptSetJoinStyle(AVars: TVariableSet): TScriptResult;
     function ScriptSetLightPosition(AVars: TVariableSet): TScriptResult;
     function ScriptSetLineCap(AVars: TVariableSet): TScriptResult;
-    function ScriptSetPenColor(AVars: TVariableSet): TScriptResult;
+    function ScriptSetForeColor(AVars: TVariableSet): TScriptResult;
     function ScriptSetPenStyle(AVars: TVariableSet): TScriptResult;
     function ScriptSetPenWidth(AVars: TVariableSet): TScriptResult;
     function ScriptSetPerspectiveOptions(AVars: TVariableSet): TScriptResult;
@@ -336,9 +347,6 @@ type
     procedure SetEraserMode(AValue: TEraserMode);
     procedure SetFloodFillOptions(AValue: TFloodFillOptions);
     procedure SetForeColor(AValue: TBGRAPixel);
-    procedure SetGradientColorspace(AValue: TBGRAColorInterpolation);
-    procedure SetGradientSine(AValue: boolean);
-    procedure SetGradientType(AValue: TGradientType);
     procedure SetJoinStyle(AValue: TPenJoinStyle);
     procedure SetLightAltitude(AValue: integer);
     procedure SetLightPosition(AValue: TPointF);
@@ -357,7 +365,6 @@ type
     procedure SetTextShadow(AValue: boolean);
     procedure SetTextShadowBlurRadius(AValue: single);
     procedure SetTextShadowOffset(AValue: TPoint);
-    procedure SetTextureOpacity(AValue: byte);
     procedure SetTolerance(AValue: byte);
     procedure ToolCloseAndReopenImmediatly;
   protected
@@ -371,9 +378,9 @@ type
     BitmapToVirtualScreen: TBitmapToVirtualScreenFunction;
     PenWidthControls, AliasingControls, EraserControls, ToleranceControls,
     ShapeControls, PenStyleControls, JoinStyleControls, SplineStyleControls,
-    CloseShapeControls, LineCapControls, GradientControls, DeformationControls,
+    CloseShapeControls, LineCapControls, DeformationControls,
     TextControls, TextShadowControls, PhongControls, AltitudeControls,
-    PerspectiveControls,PenColorControls,TextureControls,
+    PerspectiveControls,FillControls,
     BrushControls, RatioControls: TList;
 
     constructor Create(AImage: TLazPaintImage; AConfigProvider: IConfigProvider;
@@ -419,13 +426,9 @@ type
 
     procedure RenderTool(formBitmap: TBGRABitmap);
     function GetRenderBounds(VirtualScreenWidth, VirtualScreenHeight: integer): TRect;
+    function SuggestGradientBox: TAffineBox;
 
     procedure SwapToolColors;
-    procedure SetTexture(ATexture: TBGRABitmap); overload;
-    procedure SetTexture(ATexture: TBGRABitmap; AOpacity: byte); overload;
-    function GetTextureAfterAlpha: TBGRABitmap;
-    function GetTexture: TBGRABitmap;
-    function BorrowTexture: TBGRABitmap;
     procedure AddBrush(brush: TLazPaintBrush);
     procedure RemoveBrushAt(index: integer);
     procedure SetTextFont(AName: string; ASize: single; AStyle: TFontStyles);
@@ -441,13 +444,12 @@ type
     property ToolSleeping: boolean read GetToolSleeping;
     property Cursor: TCursor read GetCursor;
 
+    property ForeFill: TVectorialFill read FForeFill;
+    property BackFill: TVectorialFill read FBackFill;
     property ForeColor: TBGRAPixel read GetForeColor write SetForeColor;
     property BackColor: TBGRAPixel read GetBackColor write SetBackColor;
     property EraserMode: TEraserMode read FEraserMode write SetEraserMode;
     property EraserAlpha: byte read FEraserAlpha write SetEraserAlpha;
-    property Texture: TBGRABitmap read GetTexture write SetTexture;
-    property TextureAfterAlpha: TBGRABitmap read GetTextureAfterAlpha;
-    property TextureOpacity: byte read GetTextureOpacity write SetTextureOpacity;
     property PenWidth: single read GetPenWidth write SetPenWidth;
     property PenStyle: TPenStyle read FPenStyle write SetPenStyle;
     property JoinStyle: TPenJoinStyle read FJoinStyle write SetJoinStyle;
@@ -478,9 +480,6 @@ type
     property ArrowEnd: TArrowKind read FArrowEnd write SetArrowEnd;
     property ArrowSize: TPointF read FArrowSize write SetArrowSize;
     property SplineStyle: TSplineStyle read FSplineStyle write SetSplineStyle;
-    property GradientType: TGradientType read FGradientType write SetGradientType;
-    property GradientSine: boolean read FGradientSine write SetGradientSine;
-    property GradientColorspace: TBGRAColorInterpolation read FGradientColorspace write SetGradientColorspace;
     property PhongShapeAltitude: integer read FPhongShapeAltitude write SetPhongShapeAltitude;
     property PhongShapeBorderSize: integer read FPhongShapeBorderSize write SetPhongShapeBorderSize;
     property PhongShapeKind: TPhongShapeKind read FPhongShapeKind write SetPhongShapeKind;
@@ -497,8 +496,7 @@ type
     property OnToolbarChanged: TNotifyEvent read FOnToolbarChanged write FOnToolbarChanged;
     property OnPopup: TOnPopupToolHandler read FOnPopupToolHandler write FOnPopupToolHandler;
     property OnEraserChanged: TNotifyEvent read FOnEraserChanged write FOnEraserChanged;
-    property OnTextureChanged: TNotifyEvent read FOnTextureChanged write FOnTextureChanged;
-    property OnColorChanged: TNotifyEvent read FOnColorChanged write FOnColorChanged;
+    property OnFillChanged: TNotifyEvent read FOnFillChanged write FOnFillChanged;
     property OnPenWidthChanged: TNotifyEvent read FOnPenWidthChanged write FOnPenWidthChanged;
     property OnBrushChanged: TNotifyEvent read FOnBrushChanged write FOnBrushChanged;
     property OnBrushListChanged: TNotifyEvent read FOnBrushListChanged write FOnBrushListChanged;
@@ -514,7 +512,6 @@ type
     property OnTextShadowChanged: TNotifyEvent read FOnTextShadowChanged write FOnTextShadowChanged;
     property OnLineCapChanged: TNotifyEvent read FOnLineCapChanged write FOnLineCapChanged;
     property OnSplineStyleChanged: TNotifyEvent read FOnSplineStyleChanged write FOnSplineStyleChanged;
-    property OnGradientChanged: TNotifyEvent read FOnGradientChanged write FOnGradientChanged;
     property OnPhongShapeChanged: TNotifyEvent read FOnPhongShapeChanged write FOnPhongShapeChanged;
     property OnDeformationGridChanged: TNotifyEvent read FOnDeformationGridChanged write FOnDeformationGridChanged;
     property OnToleranceChanged: TNotifyEvent read FOnToleranceChanged write FOnToleranceChanged;
@@ -528,7 +525,7 @@ function ToolPopupMessageToStr(AMessage :TToolPopupMessage; AKey: Word = 0): str
 implementation
 
 uses UGraph, LCScaleDPI, LazPaintType, UCursors, BGRATextFX, ULoading, UResourceStrings,
-  BGRATransform, LCVectorOriginal, BGRAGradientOriginal, BGRASVGOriginal, math;
+  BGRATransform, LCVectorOriginal, BGRASVGOriginal, math;
 
 function StrToPaintToolType(const s: ansistring): TPaintToolType;
 var pt: TPaintToolType;
@@ -915,9 +912,21 @@ begin
   result := false;
 end;
 
+function TGenericTool.SuggestGradientBox: TAffineBox;
+var
+  m: TAffineMatrix;
+begin
+  result := TAffineBox.AffineBox(RectF(PointF(0,0),PointF(Manager.Image.Width,Manager.Image.Height)));
+  if not IsSelectingTool and Manager.Image.SelectionMaskEmpty then
+  begin
+    m := Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex];
+    result := AffineMatrixInverse(m)*result;
+  end;
+end;
+
 function TGenericTool.GetContextualToolbars: TContextualToolbars;
 begin
-  result := [ctColor,ctTexture];
+  result := [ctFill];
 end;
 
 function TGenericTool.GetToolDrawingLayer: TBGRABitmap;
@@ -1027,13 +1036,7 @@ end;
 
 procedure TToolManager.SetBackColor(AValue: TBGRAPixel);
 begin
-  if (AValue.red = FBackColor.red) and
-     (AValue.green = FBackColor.green) and
-     (AValue.blue = FBackColor.blue) and
-     (AValue.alpha = FBackColor.alpha) then exit;
-  FBackColor := AValue;
-  ToolUpdate;
-  if Assigned(FOnColorChanged) then FOnColorChanged(self);
+  FBackFill.SolidColor := AValue;
 end;
 
 procedure TToolManager.SetDeformationGridMode(AValue: TDeformationGridMode);
@@ -1070,37 +1073,7 @@ end;
 
 procedure TToolManager.SetForeColor(AValue: TBGRAPixel);
 begin
-  if (AValue.red = FForeColor.red) and
-     (AValue.green = FForeColor.green) and
-     (AValue.blue = FForeColor.blue) and
-     (AValue.alpha = FForeColor.alpha) then exit;
-  FForeColor := AValue;
-  ToolUpdate;
-  if Assigned(FOnColorChanged) then FOnColorChanged(self);
-end;
-
-procedure TToolManager.SetGradientColorspace(AValue: TBGRAColorInterpolation);
-begin
-  if FGradientColorspace=AValue then Exit;
-  FGradientColorspace:=AValue;
-  ToolUpdate;
-  if Assigned(FOnGradientChanged) then FOnGradientChanged(self);
-end;
-
-procedure TToolManager.SetGradientSine(AValue: boolean);
-begin
-  if FGradientSine=AValue then Exit;
-  FGradientSine:=AValue;
-  ToolUpdate;
-  if Assigned(FOnGradientChanged) then FOnGradientChanged(self);
-end;
-
-procedure TToolManager.SetGradientType(AValue: TGradientType);
-begin
-  if FGradientType=AValue then Exit;
-  FGradientType:=AValue;
-  ToolUpdate;
-  if Assigned(FOnGradientChanged) then FOnGradientChanged(self);
+  FForeFill.SolidColor := AValue;
 end;
 
 procedure TToolManager.SetJoinStyle(AValue: TPenJoinStyle);
@@ -1266,15 +1239,6 @@ begin
   if Assigned(FOnTextShadowChanged) then FOnTextShadowChanged(self);
 end;
 
-procedure TToolManager.SetTextureOpacity(AValue: byte);
-begin
-  if AValue = FTextureOpactiy then exit;
-  FreeAndNil(FTextureAfterAlpha);
-  FTextureOpactiy := AValue;
-  ToolUpdate;
-  if Assigned(FOnTextureChanged) then FOnTextureChanged(self);
-end;
-
 procedure TToolManager.SetTolerance(AValue: byte);
 begin
   if FTolerance=AValue then Exit;
@@ -1323,9 +1287,9 @@ end;
 function TToolManager.GetBackColor: TBGRAPixel;
 begin
   if BlackAndWhite then
-    result := BGRAToGrayscale(FBackColor)
+    result := BGRAToGrayscale(FBackFill.AverageColor)
   else
-    result := FBackColor;
+    result := FBackFill.AverageColor;
 end;
 
 function TToolManager.GetBrushAt(AIndex: integer): TLazPaintBrush;
@@ -1376,12 +1340,25 @@ begin
   if toolCursor <> crDefault then result := toolCursor;
 end;
 
+procedure TToolManager.BackFillChange(ASender: TObject;
+  var ADiff: TCustomVectorialFillDiff);
+begin
+  if FInToolUpdate then exit;
+  ToolUpdate;
+  if Assigned(FOnFillChanged) then FOnFillChanged(self);
+  if FBackFill.FillType = vftGradient then
+  begin
+    FBackLastGradient.Free;
+    FBackLastGradient := FBackFill.Gradient.Duplicate as TBGRALayerGradientOriginal;
+  end;
+end;
+
 function TToolManager.GetForeColor: TBGRAPixel;
 begin
   if BlackAndWhite then
-    result := BGRAToGrayscale(FForeColor)
+    result := BGRAToGrayscale(FForeFill.AverageColor)
   else
-    result := FForeColor;
+    result := FForeFill.AverageColor;
 end;
 
 function TToolManager.GetMaxDeformationGridSize: TSize;
@@ -1433,7 +1410,20 @@ end;
 
 function TToolManager.GetTextureOpacity: byte;
 begin
-  result := FTextureOpactiy;
+
+end;
+
+procedure TToolManager.ForeFillChange(ASender: TObject;
+  var ADiff: TCustomVectorialFillDiff);
+begin
+  if FInToolUpdate then exit;
+  ToolUpdate;
+  if Assigned(FOnFillChanged) then FOnFillChanged(self);
+  if FForeFill.FillType = vftGradient then
+  begin
+    FForeLastGradient.Free;
+    FForeLastGradient := FForeFill.Gradient.Duplicate as TBGRALayerGradientOriginal;
+  end;
 end;
 
 function TToolManager.ScriptGetAliasing(AVars: TVariableSet): TScriptResult;
@@ -1561,10 +1551,11 @@ begin
   result := srOk;
 end;
 
-function TToolManager.ScriptGetGradientColorspace(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptGetGradientColorspace(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
 begin
   result := srOk;
-  case GradientColorspace of
+  if AFill.FillType <> vftGradient then result := srException else
+  case AFill.Gradient.ColorInterpolation of
   ciStdRGB: AVars.Strings['Result'] := 'StdRGB';
   ciLinearRGB: AVars.Strings['Result'] := 'LinearRGB';
   ciLinearHSLPositive: AVars.Strings['Result'] := 'LinearHSLPositive';
@@ -1575,16 +1566,24 @@ begin
   end;
 end;
 
-function TToolManager.ScriptGetGradientSine(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptGetGradientRepetition(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
 begin
   result := srOk;
-  AVars.Booleans['Result'] := GradientSine;
+  if AFill.FillType <> vftGradient then result := srException else
+  case AFill.Gradient.Repetition of
+  grPad: AVars.Strings['Result'] := 'Pad';
+  grRepeat: AVars.Strings['Result'] := 'Repeat';
+  grReflect: AVars.Strings['Result'] := 'Reflect';
+  grSine: AVars.Strings['Result'] := 'Sine';
+  else result := srException;
+  end;
 end;
 
-function TToolManager.ScriptGetGradientType(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptGetGradientType(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
 begin
   result := srOk;
-  case GradientType of
+  if AFill.FillType <> vftGradient then result := srException else
+  case AFill.Gradient.GradientType of
   gtLinear: AVars.Strings['Result'] := 'Linear';
   gtReflected: AVars.Strings['Result'] := 'Reflected';
   gtDiamond: AVars.Strings['Result'] := 'Diamond';
@@ -1594,6 +1593,36 @@ begin
   end;
 end;
 
+function TToolManager.ScriptGetBackGradientColorspace(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientColorspace(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptGetBackGradientRepetition(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientRepetition(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptGetBackGradientType(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientType(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptGetForeGradientColorspace(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientColorspace(AVars, FForeFill);
+end;
+
+function TToolManager.ScriptGetForeGradientRepetition(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientRepetition(AVars, FForeFill);
+end;
+
+function TToolManager.ScriptGetForeGradientType(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptGetGradientType(AVars, FForeFill);
+end;
+
 function TToolManager.ScriptGetJoinStyle(AVars: TVariableSet): TScriptResult;
 begin
   result := srOk;
@@ -1622,7 +1651,7 @@ begin
   result := srOk;
 end;
 
-function TToolManager.ScriptGetPenColor(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptGetForeColor(AVars: TVariableSet): TScriptResult;
 begin
   AVars.Pixels['Result'] := ForeColor;
   result := srOk;
@@ -1926,37 +1955,93 @@ begin
   result := srOk;
 end;
 
-function TToolManager.ScriptSetGradientColorspace(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptSetGradientColorspace(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
 begin
+  if AFill.FillType <> vftGradient then exit(srException);
   result := srOk;
   case AVars.Strings['Colorspace'] of
-  'StdRGB': GradientColorspace := ciStdRGB;
-  'LinearRGB': GradientColorspace := ciLinearRGB;
-  'LinearHSLPositive': GradientColorspace := ciLinearHSLPositive;
-  'LinearHSLNegative': GradientColorspace := ciLinearHSLNegative;
-  'GSBPositive': GradientColorspace := ciGSBPositive;
-  'GSBNegative': GradientColorspace := ciGSBNegative;
+  'StdRGB': AFill.Gradient.ColorInterpolation:= ciStdRGB;
+  'LinearRGB': AFill.Gradient.ColorInterpolation:= ciLinearRGB;
+  'LinearHSLPositive': AFill.Gradient.ColorInterpolation:= ciLinearHSLPositive;
+  'LinearHSLNegative': AFill.Gradient.ColorInterpolation:= ciLinearHSLNegative;
+  'GSBPositive': AFill.Gradient.ColorInterpolation:= ciGSBPositive;
+  'GSBNegative': AFill.Gradient.ColorInterpolation:= ciGSBNegative;
   else result := srInvalidParameters;
   end;
 end;
 
-function TToolManager.ScriptSetGradientSine(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptSetGradientRepetition(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
 begin
+  if AFill.FillType <> vftGradient then exit(srException);
   result := srOk;
-  GradientSine:= AVars.Booleans['Enabled'];
+  case AVars.Strings['Repetition'] of
+    'Pad': AFill.Gradient.Repetition:= grPad;
+    'Repeat': AFill.Gradient.Repetition:= grRepeat;
+    'Reflect': AFill.Gradient.Repetition:= grReflect;
+    'Sine': AFill.Gradient.Repetition:= grSine;
+    else result := srInvalidParameters;
+  end;
 end;
 
-function TToolManager.ScriptSetGradientType(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptSetGradientType(AVars: TVariableSet; AFill: TVectorialFill): TScriptResult;
+var
+  gt: TGradientType;
+  b: TAffineBox;
 begin
   result := srOk;
   case AVars.Strings['GradientType'] of
-  'Linear': GradientType:= gtLinear;
-  'Reflected': GradientType := gtReflected;
-  'Diamond': GradientType := gtDiamond;
-  'Radial': GradientType := gtRadial;
-  'Angular': GradientType := gtAngular;
+  'Linear': gt := gtLinear;
+  'Reflected': gt := gtReflected;
+  'Diamond': gt := gtDiamond;
+  'Radial': gt := gtRadial;
+  'Angular': gt := gtAngular;
   else result := srInvalidParameters;
   end;
+  if AFill.FillType = vftGradient then
+    AFill.Gradient.GradientType:= gt
+  else
+  begin
+    FBackLastGradient.GradientType:= gt;
+    b := SuggestGradientBox;
+    if gt = gtLinear then FBackLastGradient.Origin := b.TopLeft else
+      FBackLastGradient.Origin := (b.TopLeft+b.BottomRight)*0.5;
+    FBackLastGradient.XAxis := b.BottomRight;
+    FBackLastGradient.YAxis := EmptyPointF;
+    FBackLastGradient.FocalPoint := EmptyPointF;
+    FBackLastGradient.Radius := 1;
+    FBackLastGradient.FocalRadius := 0;
+    AFill.SetGradient(FBackLastGradient, False);
+  end;
+end;
+
+function TToolManager.ScriptSetBackGradientColorspace(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientColorspace(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptSetBackGradientRepetition(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientRepetition(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptSetBackGradientType(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientType(AVars, FBackFill);
+end;
+
+function TToolManager.ScriptSetForeGradientColorspace(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientColorspace(AVars, FForeFill);
+end;
+
+function TToolManager.ScriptSetForeGradientRepetition(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientRepetition(AVars, FForeFill);
+end;
+
+function TToolManager.ScriptSetForeGradientType(AVars: TVariableSet): TScriptResult;
+begin
+  result := ScriptSetGradientType(AVars, FForeFill);
 end;
 
 function TToolManager.ScriptSetJoinStyle(AVars: TVariableSet): TScriptResult;
@@ -1994,7 +2079,7 @@ begin
   result := srOk;
 end;
 
-function TToolManager.ScriptSetPenColor(AVars: TVariableSet): TScriptResult;
+function TToolManager.ScriptSetForeColor(AVars: TVariableSet): TScriptResult;
 begin
   ForeColor := AVars.Pixels['Color'];
   ToolUpdate;
@@ -2196,11 +2281,16 @@ begin
   FScriptContext := AScriptContext;
   RegisterScriptFunctions(True);
 
-  FForeColor := BGRABlack;
-  FBackColor := BGRA(0,0,255);
-  FTexture := nil;
-  FTextureOpactiy:= 255;
-  FTextureAfterAlpha := nil;
+  FForeFill := TVectorialFill.Create;
+  FForeFill.SolidColor := BGRABlack;
+  FForeFill.OnChange:=@ForeFillChange;
+  FBackFill := TVectorialFill.Create;
+  FBackFill.SolidColor := CSSSkyBlue;
+  FBackFill.OnChange:=@BackFillChange;
+  FForeLastGradient:= TBGRALayerGradientOriginal.Create;
+  FForeLastGradient.ColorInterpolation:= ciLinearRGB;
+  FBackLastGradient:= TBGRALayerGradientOriginal.Create;
+  FBackLastGradient.ColorInterpolation:= ciLinearRGB;
   FNormalPenWidth := 5;
   FEraserWidth := 10;
   FEraserAlpha := 255;
@@ -2217,9 +2307,6 @@ begin
   FSplineStyle := ssEasyBezier;
   FFloodFillOptions := [ffProgressive];
   FTolerance := 64;
-  FGradientType := gtLinear;
-  FGradientSine := false;
-  FGradientColorspace := ciLinearRGB;
   FTextOutline := False;
   FTextOutlineWidth := 2;
   FTextShadow := false;
@@ -2250,15 +2337,13 @@ begin
   SplineStyleControls := TList.Create;
   EraserControls := TList.Create;
   ToleranceControls := TList.Create;
-  GradientControls := TList.Create;
   DeformationControls := TList.Create;
   TextControls := TList.Create;
   TextShadowControls := TList.Create;
   PhongControls := TList.Create;
   AltitudeControls := TList.Create;
   PerspectiveControls := TList.Create;
-  PenColorControls := TList.Create;
-  TextureControls := TList.Create;
+  FillControls := TList.Create;
   BrushControls := TList.Create;
   RatioControls := TList.Create;
 
@@ -2283,15 +2368,13 @@ begin
   SplineStyleControls.Free;
   EraserControls.Free;
   ToleranceControls.Free;
-  GradientControls.Free;
   DeformationControls.Free;
   TextControls.Free;
   TextShadowControls.Free;
   PhongControls.Free;
   AltitudeControls.Free;
   PerspectiveControls.Free;
-  PenColorControls.Free;
-  TextureControls.Free;
+  FillControls.Free;
   BrushControls.Free;
   RatioControls.Free;
 
@@ -2299,9 +2382,8 @@ begin
     BrushAt[i].Free;
   FBrushInfoList.Free;
 
-  FTexture.FreeReference;
-  FTexture := nil;
-  FTextureAfterAlpha.Free;
+  FForeFill.Free;
+  FBackFill.Free;
 
   RegisterScriptFunctions(False);
   inherited Destroy;
@@ -2496,10 +2578,9 @@ begin
   if Assigned(FCurrentTool) then
     contextualToolbars := FCurrentTool.GetContextualToolbars
   else
-    contextualToolbars := [ctColor,ctTexture];
+    contextualToolbars := [ctFill];
 
-  OrResult(SetControlsVisible(PenColorControls, ctColor in contextualToolbars));
-  OrResult(SetControlsVisible(TextureControls, ctTexture in contextualToolbars));
+  OrResult(SetControlsVisible(FillControls, ctFill in contextualToolbars));
   OrResult(SetControlsVisible(BrushControls, ctBrush in contextualToolbars));
   OrResult(SetControlsVisible(ShapeControls, ctShape in contextualToolbars));
   OrResult(SetControlsVisible(PenWidthControls, (ctPenWidth in contextualToolbars) and (toDrawShape in ShapeOptions)));
@@ -2511,7 +2592,6 @@ begin
   OrResult(SetControlsVisible(SplineStyleControls, ctSplineStyle in contextualToolbars));
   OrResult(SetControlsVisible(EraserControls, ctEraserOption in contextualToolbars));
   OrResult(SetControlsVisible(ToleranceControls, ctTolerance in contextualToolbars));
-  OrResult(SetControlsVisible(GradientControls, ctGradient in contextualToolbars));
   OrResult(SetControlsVisible(DeformationControls, ctDeformation in contextualToolbars));
   OrResult(SetControlsVisible(TextControls, ctText in contextualToolbars));
   OrResult(SetControlsVisible(TextShadowControls, ctTextShadow in contextualToolbars));
@@ -2547,8 +2627,8 @@ end;
 procedure TToolManager.RegisterScriptFunctions(ARegister: boolean);
 begin
   if not Assigned(FScriptContext) then exit;
-  FScriptContext.RegisterScriptFunction('ToolSetPenColor', @ScriptSetPenColor, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolGetPenColor', @ScriptGetPenColor, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetForeColor', @ScriptSetForeColor, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetForeColor', @ScriptGetForeColor, ARegister);
   FScriptContext.RegisterScriptFunction('ToolSetBackColor', @ScriptSetBackColor, ARegister);
   FScriptContext.RegisterScriptFunction('ToolGetBackColor', @ScriptGetBackColor, ARegister);
   FScriptContext.RegisterScriptFunction('ToolSetEraserMode', @ScriptSetEraserMode, ARegister);
@@ -2598,12 +2678,18 @@ begin
   FScriptContext.RegisterScriptFunction('ToolGetArrowSize', @ScriptGetArrowSize, ARegister);
   FScriptContext.RegisterScriptFunction('ToolSetSplineStyle', @ScriptSetSplineStyle, ARegister);
   FScriptContext.RegisterScriptFunction('ToolGetSplineStyle', @ScriptGetSplineStyle, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolSetGradientType', @ScriptSetGradientType, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolGetGradientType', @ScriptGetGradientType, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolSetGradientSine', @ScriptSetGradientSine, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolGetGradientSine', @ScriptGetGradientSine, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolSetGradientColorspace', @ScriptSetGradientColorspace, ARegister);
-  FScriptContext.RegisterScriptFunction('ToolGetGradientColorspace', @ScriptGetGradientColorspace, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetForeGradientType', @ScriptSetForeGradientType, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetForeGradientType', @ScriptGetForeGradientType, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetForeGradientRepetition', @ScriptSetForeGradientRepetition, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetForeGradientRepetition', @ScriptGetForeGradientRepetition, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetForeGradientColorspace', @ScriptSetForeGradientColorspace, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetForeGradientColorspace', @ScriptGetForeGradientColorspace, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetBackGradientType', @ScriptSetBackGradientType, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetBackGradientType', @ScriptGetBackGradientType, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetBackGradientRepetition', @ScriptSetBackGradientRepetition, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetBackGradientRepetition', @ScriptGetBackGradientRepetition, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolSetBackGradientColorspace', @ScriptSetBackGradientColorspace, ARegister);
+  FScriptContext.RegisterScriptFunction('ToolGetBackGradientColorspace', @ScriptGetBackGradientColorspace, ARegister);
   FScriptContext.RegisterScriptFunction('ToolSetPhongShapeAltitude', @ScriptSetPhongShapeAltitude, ARegister);
   FScriptContext.RegisterScriptFunction('ToolGetPhongShapeAltitude', @ScriptGetPhongShapeAltitude, ARegister);
   FScriptContext.RegisterScriptFunction('ToolSetPhongShapeBorderSize', @ScriptSetPhongShapeBorderSize, ARegister);
@@ -2662,58 +2748,24 @@ end;
 
 procedure TToolManager.SwapToolColors;
 var
-  tmp: TBGRAPixel;
-begin
-  if (FForeColor.red = FBackColor.red) and
-     (FForeColor.green = FBackColor.green) and
-     (FForeColor.blue = FBackColor.blue) and
-     (FForeColor.alpha = FBackColor.alpha) then exit;
-  tmp := FForeColor;
-  FForeColor := FBackColor;
-  FBackColor := tmp;
-  if Assigned(FOnColorChanged) then FOnColorChanged(self);
-end;
-
-procedure TToolManager.SetTexture(ATexture: TBGRABitmap);
-begin
-  SetTexture(ATexture, TextureOpacity);
-end;
-
-procedure TToolManager.SetTexture(ATexture: TBGRABitmap; AOpacity: byte);
-begin
-  if (ATexture = FTexture) and (AOpacity = FTextureOpactiy) then exit;
-  if ATexture<>FTexture then
+  tmpFill: TVectorialFill;
+begin
+  if FForeFill.Equals(FBackFill) then exit;
+  tmpFill := FForeFill.Duplicate;
+  FForeFill.Assign(FBackFill);
+  FBackFill.Assign(tmpFill);
+  tmpFill.Free;
+  if FForeFill.FillType = vftGradient then
   begin
-    FTexture.FreeReference;
-    FTexture := ATexture.NewReference as TBGRABitmap;
+    FForeLastGradient.Free;
+    FForeLastGradient := FForeFill.Gradient.Duplicate as TBGRALayerGradientOriginal;
   end;
-  FTextureOpactiy:= AOpacity;
-  FreeAndNil(FTextureAfterAlpha);
-  ToolUpdate;
-  if Assigned(FOnTextureChanged) then FOnTextureChanged(self);
-end;
-
-function TToolManager.GetTextureAfterAlpha: TBGRABitmap;
-begin
-  if (FTextureAfterAlpha = nil) and (FTexture <> nil) then
+  if FBackFill.FillType = vftGradient then
   begin
-    FTextureAfterAlpha := FTexture.Duplicate as TBGRABitmap;
-    FTextureAfterAlpha.ApplyGlobalOpacity(FTextureOpactiy);
+    FBackLastGradient.Free;
+    FBackLastGradient := FBackFill.Gradient.Duplicate as TBGRALayerGradientOriginal;
   end;
-  result := FTextureAfterAlpha;
-end;
-
-function TToolManager.GetTexture: TBGRABitmap;
-begin
-  result := FTexture;
-end;
-
-function TToolManager.BorrowTexture: TBGRABitmap;
-begin
-  result := FTexture;
-  FTexture := nil;
-  FreeAndNil(FTextureAfterAlpha);
-  if Assigned(FOnTextureChanged) then FOnTextureChanged(self);
+  if Assigned(FOnFillChanged) then FOnFillChanged(self);
 end;
 
 procedure TToolManager.AddBrush(brush: TLazPaintBrush);
@@ -2966,6 +3018,7 @@ var changed: TRect;
 begin
   if FInTool then exit(false);
   FInTool := true;
+  FInToolUpdate := true;
   try
     if ToolCanBeUsed then
       changed := currentTool.ToolUpdate
@@ -2978,6 +3031,7 @@ begin
     if result then NotifyImageOrSelectionChanged(CurrentTool.LastToolDrawingLayer, changed);
   finally
     FInTool := false;
+    FInToolUpdate := false;
   end;
 end;
 
@@ -3036,6 +3090,14 @@ begin
     result := EmptyRect;
 end;
 
+function TToolManager.SuggestGradientBox: TAffineBox;
+begin
+  if Assigned(CurrentTool) then
+    result := CurrentTool.SuggestGradientBox
+  else
+    result := TAffineBox.AffineBox(RectF(PointF(0,0),PointF(Image.Width,Image.Height)));
+end;
+
 function TToolManager.GetDeformationGridSize: TSize;
 begin
   result := Size(DeformationGridNbX, DeformationGridNbY);

+ 2 - 2
lazpaint/tools/utoolbasic.pas

@@ -361,7 +361,7 @@ end;
 
 function TToolPen.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctPenWidth,ctAliasing];
+  Result:= [ctFill,ctTexture,ctPenWidth,ctAliasing];
 end;
 
 destructor TToolPen.Destroy;
@@ -406,7 +406,7 @@ end;
 
 function TToolColorPicker.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor];
+  Result:= [ctFill];
 end;
 
 { TToolHand }

+ 1 - 1
lazpaint/tools/utoolbrush.pas

@@ -216,7 +216,7 @@ end;
 
 function TToolBrush.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctPenWidth,ctBrush];
+  Result:= [ctFill,ctPenWidth,ctBrush];
 end;
 
 { TToolGenericBrush }

+ 29 - 5
lazpaint/tools/utooldeformationgrid.pas

@@ -47,6 +47,8 @@ type
   private
     class var FHintShowed: boolean;
     FCurrentBounds: TRect;
+    FLastTexture: TBGRABitmap;
+    FTextureAfterAlpha: TBGRABitmap;
     FAdaptedTexture: TBGRABitmap;
     FCanReadaptTexture: boolean;
     FHighQuality: boolean;
@@ -431,9 +433,9 @@ begin
   begin
     if ShiftKey then
     begin
-      if (Manager.GetTexture <> nil) and (Manager.GetTexture.Height <> 0)
-        and (Manager.GetTexture.Width <> 0) then
-        ratio := Manager.GetTexture.Width/Manager.GetTexture.Height;
+      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;
 
       newSize := ptF - quad[0];
       avgSize := (abs(newSize.x)+abs(newSize.y))/2;
@@ -539,7 +541,27 @@ end;
 
 function TToolTextureMapping.GetTexture: TBGRABitmap;
 begin
-  result := Manager.GetTextureAfterAlpha;
+  if Manager.BackFill.Texture = FLastTexture then
+  begin
+    if FTextureAfterAlpha <> nil then
+      result := FTextureAfterAlpha
+    else
+      result := Manager.BackFill.Texture;
+  end
+  else
+  begin
+    if (Manager.BackFill.Texture <> nil) and (Manager.BackFill.TextureOpacity <> 255) then
+    begin
+      FTextureAfterAlpha := Manager.BackFill.Texture.Duplicate as TBGRABitmap;
+      FTextureAfterAlpha.ApplyGlobalOpacity(Manager.BackFill.TextureOpacity);
+      result := FTextureAfterAlpha;
+    end else
+    begin
+      result := Manager.BackFill.Texture;
+      FreeAndNil(FTextureAfterAlpha);
+    end;
+    FLastTexture := Manager.BackFill.Texture;
+  end;
 end;
 
 procedure TToolTextureMapping.OnTryStop(sender: TCustomLayerAction);
@@ -609,6 +631,7 @@ begin
   inherited Create(AManager);
   FCurrentBounds := EmptyRect;
   FHighQuality:= False;
+  FLastTexture := nil;
   quadDefined:= false;
   definingQuad:= false;
 end;
@@ -745,7 +768,7 @@ end;
 
 function TToolTextureMapping.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctTexture,ctPerspective];
+  Result:= [ctFill,ctPerspective];
 end;
 
 function TToolTextureMapping.Render(VirtualScreen: TBGRABitmap;
@@ -804,6 +827,7 @@ end;
 destructor TToolTextureMapping.Destroy;
 begin
   ValidateAction;
+  FreeAndNil(FTextureAfterAlpha);
   FreeAndNil(FAdaptedTexture);
   inherited Destroy;
 end;

+ 2 - 2
lazpaint/tools/utoolfloodfill.pas

@@ -109,7 +109,7 @@ end;
 
 function TToolGradient.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor, ctGradient];
+  Result:= [ctFill, ctGradient];
 end;
 
 function TToolGradient.SlowShape: boolean;
@@ -150,7 +150,7 @@ end;
 
 function TToolFloodFill.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctTolerance];
+  Result:= [ctFill,ctTexture,ctTolerance];
 end;
 
 initialization

+ 1 - 1
lazpaint/tools/utoolphong.pas

@@ -37,7 +37,7 @@ end;
 
 function TToolPhong.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctPhong,ctAltitude];
+  Result:= [ctFill,ctTexture,ctPhong,ctAltitude];
 end;
 
 procedure TToolPhong.ShapeChange(ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff);

+ 4 - 4
lazpaint/tools/utoolpolygon.pas

@@ -79,7 +79,7 @@ end;
 
 function TToolEllipse.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle];
+  Result:= [ctFill,ctShape,ctPenWidth,ctPenStyle];
 end;
 
 { TToolRectangle }
@@ -91,7 +91,7 @@ end;
 
 function TToolRectangle.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle];
+  Result:= [ctFill,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle];
 end;
 
 { TToolSpline }
@@ -172,7 +172,7 @@ end;
 
 function TToolSpline.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctLineCap,ctSplineStyle];
+  Result:= [ctFill,ctShape,ctPenWidth,ctPenStyle,ctLineCap,ctSplineStyle];
 end;
 
 { TToolPolygon }
@@ -254,7 +254,7 @@ end;
 
 function TToolPolygon.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap];
+  Result:= [ctFill,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap];
 end;
 
 initialization

+ 1 - 1
lazpaint/tools/utooltext.pas

@@ -216,7 +216,7 @@ end;
 
 function TToolText.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctText,ctTextShadow];
+  Result:= [ctFill,ctTexture,ctText,ctTextShadow];
   if Manager.TextPhong then include(result, ctAltitude);
 end;
 

+ 160 - 231
lazpaint/tools/utoolvectorial.pas

@@ -72,6 +72,7 @@ type
     function ToolKeyUp(var key: Word): TRect; override;
     function ToolCommand(ACommand: TToolCommand): boolean; override;
     function ToolProvideCommand(ACommand: TToolCommand): boolean; override;
+    function SuggestGradientBox: TAffineBox; override;
     function Render(VirtualScreen: TBGRABitmap; {%H-}VirtualScreenWidth, {%H-}VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction):TRect; override;
     property IsIdle: boolean read GetIsIdle;
     property IsHandDrawing: boolean read GetIsHandDrawing;
@@ -121,7 +122,6 @@ type
     function FixLayerOffset: boolean; override;
     function GetCurrentSplineMode: TToolSplineMode;
     procedure SetCurrentSplineMode(AMode: TToolSplineMode);
-    function IsGradientShape(AShape: TVectorShape): boolean;
     function ConvertToSpline: boolean;
     function GetEditMode: TEditShapeMode;
     function InvalidEditMode: boolean;
@@ -136,6 +136,7 @@ type
     function ToolUp: TRect; override;
     function ToolCommand(ACommand: TToolCommand): boolean; override;
     function ToolProvideCommand(ACommand: TToolCommand): boolean; override;
+    function SuggestGradientBox: TAffineBox; override;
     property CurrentSplineMode: TToolSplineMode read GetCurrentSplineMode write SetCurrentSplineMode;
   end;
 
@@ -200,6 +201,22 @@ begin
   end;
 end;
 
+procedure AssignFill(ATarget, ASource: TVectorialFill; const ABox: TAffineBox);
+var
+  temp: TVectorialFill;
+begin
+  if ASource.IsFullyTransparent then ATarget.Clear
+  else if ATarget.FillType <> ASource.FillType then
+  begin
+    temp := ATarget.Duplicate;
+    temp.AssignExceptGeometry(ASource);
+    temp.FitGeometry(ABox);
+    ATarget.Assign(temp);
+    temp.Free;
+  end else
+    ATarget.AssignExceptGeometry(ASource);
+end;
+
 { TEditShapeTool }
 
 procedure TEditShapeTool.SelectShape(ASender: TObject; AShape: TVectorShape;
@@ -241,93 +258,75 @@ var
 begin
   m := Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex];
   zoom := (VectLen(m[1,1],m[2,1])+VectLen(m[1,2],m[2,2]))/2;
-  if IsGradientShape(AShape) then
+  if AShape.Usermode in [vsuEditBackFill, vsuEditPenFill] then
+    AShape.Usermode := vsuEdit;
+  opt := Manager.ShapeOptions;
+  if AShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
   begin
-    Manager.ForeColor := AShape.BackFill.Gradient.StartColor;
-    Manager.BackColor := AShape.BackFill.Gradient.EndColor;
-    Manager.GradientType:= AShape.BackFill.Gradient.GradientType;
-    Manager.GradientColorspace:= AShape.BackFill.Gradient.ColorInterpolation;
-    Manager.GradientSine:= AShape.BackFill.Gradient.Repetition = grSine;
-    Manager.SetTexture(nil);
-    AShape.Usermode := vsuEditBackFill;
-  end else
-  begin
-    if AShape.Usermode in [vsuEditBackFill, vsuEditPenFill] then
-      AShape.Usermode := vsuEdit;
-    opt := Manager.ShapeOptions;
-    if AShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
-    begin
-      if AShape.BackFill.FillType = vftNone then
-      begin;
-        exclude(opt,toFillShape);
-        doFill := false;
-      end
-      else
-      begin
-        include(opt,toFillShape);
-        doFill := true;
-      end;
-      ps := BGRAToPenStyle(AShape.PenStyle);
-      if (ps = psClear) or (AShape.PenFill.FillType = vftNone) then
-      begin
-        exclude(opt,toDrawShape);
-        doDraw := false;
-      end
-      else
-      begin
-        include(opt,toDrawShape);
-        Manager.PenStyle := ps;
-        doDraw := true;
-      end;
-    end else
+    if AShape.BackFill.FillType = vftNone then
+    begin;
+      exclude(opt,toFillShape);
+      doFill := false;
+    end
+    else
     begin
-      doDraw := vsfPenFill in AShape.Fields;
-      doFill := vsfBackFill in AShape.Fields;
+      include(opt,toFillShape);
+      doFill := true;
     end;
-
-    if doDraw then
+    ps := BGRAToPenStyle(AShape.PenStyle);
+    if (ps = psClear) or (AShape.PenFill.FillType = vftNone) then
     begin
-      case AShape.PenFill.FillType of
-        vftSolid: Manager.ForeColor := AShape.PenFill.SolidColor;
-        vftNone: Manager.ForeColor := BGRA(Manager.ForeColor.red,
-          Manager.ForeColor.green,Manager.ForeColor.blue,0);
-      end;
-    end;
-    if doFill then
+      exclude(opt,toDrawShape);
+      doDraw := false;
+    end
+    else
     begin
-      case AShape.BackFill.FillType of
-        vftSolid: Manager.BackColor := AShape.BackFill.SolidColor;
-        vftNone: Manager.BackColor := BGRA(Manager.BackColor.red,
-          Manager.BackColor.green,Manager.BackColor.blue,0);
-      end;
+      include(opt,toDrawShape);
+      Manager.PenStyle := ps;
+      doDraw := true;
     end;
-    if doFill and (AShape.BackFill.FillType = vftTexture) then
-      Manager.SetTexture(AShape.BackFill.Texture,AShape.BackFill.TextureOpacity)
-    else if doDraw and (AShape.PenFill.FillType = vftTexture) then
-      Manager.SetTexture(AShape.PenFill.Texture,AShape.PenFill.TextureOpacity)
+  end else
+  begin
+    doDraw := vsfPenFill in AShape.Fields;
+    doFill := vsfBackFill in AShape.Fields;
+  end;
+
+  if doDraw then
+  begin
+    if AShape.PenFill.FillType = vftNone then
+      Manager.ForeColor := BGRA(Manager.ForeColor.red,
+        Manager.ForeColor.green,Manager.ForeColor.blue,0)
     else
-      Manager.SetTexture(nil);
+      Manager.ForeFill.Assign(AShape.PenFill);
+  end;
+  if doFill then
+  begin
+    if AShape.BackFill.FillType = vftNone then
+      Manager.BackColor := BGRA(Manager.BackColor.red,
+        Manager.BackColor.green,Manager.BackColor.blue,0)
+    else
+      Manager.BackFill.Assign(AShape.BackFill);
+  end;
 
-    if toDrawShape in opt then
+  if toDrawShape in opt then
+  begin
+    if vsfPenWidth in AShape.Fields then Manager.PenWidth := AShape.PenWidth*zoom;
+    if vsfJoinStyle in AShape.Fields then Manager.JoinStyle:= AShape.JoinStyle;
+    if AShape is TCustomPolypointShape then
     begin
-      if vsfPenWidth in AShape.Fields then Manager.PenWidth := AShape.PenWidth*zoom;
-      if vsfJoinStyle in AShape.Fields then Manager.JoinStyle:= AShape.JoinStyle;
-      if AShape is TCustomPolypointShape then
-      begin
-        if TCustomPolypointShape(AShape).Closed then
-          include(opt, toCloseShape)
-        else
-          exclude(opt, toCloseShape);
-        Manager.LineCap := TCustomPolypointShape(AShape).LineCap;
-        Manager.ArrowSize := TCustomPolypointShape(AShape).ArrowSize;
-        Manager.ArrowStart := TCustomPolypointShape(AShape).ArrowStartKind;
-        Manager.ArrowEnd := TCustomPolypointShape(AShape).ArrowEndKind;
-      end;
-      if AShape is TCurveShape then
-        Manager.SplineStyle := TCurveShape(AShape).SplineStyle;
+      if TCustomPolypointShape(AShape).Closed then
+        include(opt, toCloseShape)
+      else
+        exclude(opt, toCloseShape);
+      Manager.LineCap := TCustomPolypointShape(AShape).LineCap;
+      Manager.ArrowSize := TCustomPolypointShape(AShape).ArrowSize;
+      Manager.ArrowStart := TCustomPolypointShape(AShape).ArrowStartKind;
+      Manager.ArrowEnd := TCustomPolypointShape(AShape).ArrowEndKind;
     end;
-    Manager.ShapeOptions := opt;
+    if AShape is TCurveShape then
+      Manager.SplineStyle := TCurveShape(AShape).SplineStyle;
   end;
+  Manager.ShapeOptions := opt;
 
   if AShape is TTextShape then
   with TTextShape(AShape) do
@@ -342,8 +341,7 @@ begin
       Manager.SetTextOutline(false, Manager.TextOutlineWidth) else
     begin
       Manager.SetTextOutline(true, OutlineWidth);
-      if OutlineFill.FillType = vftSolid then
-        Manager.BackColor := OutlineFill.SolidColor;
+      Manager.BackFill.Assign(OutlineFill);
     end;
   end;
 
@@ -473,126 +471,75 @@ var
   doDraw, doFill: Boolean;
   m: TAffineMatrix;
   zoom: Single;
+  gradBox: TAffineBox;
 begin
   case GetEditMode of
   esmShape:
     with GetVectorOriginal do
     try
       BindOriginalEvent(true);
+      gradBox := SelectedShape.SuggestGradientBox(AffineMatrixIdentity);
       m := AffineMatrixInverse(Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex]);
       zoom := (VectLen(m[1,1],m[2,1])+VectLen(m[1,2],m[2,2]))/2;
-      if IsGradientShape(SelectedShape) then
-      begin
-        SelectedShape.BackFill.Gradient.StartColor := Manager.ForeColor;
-        SelectedShape.BackFill.Gradient.EndColor := Manager.BackColor;
-        SelectedShape.BackFill.Gradient.GradientType := Manager.GradientType;
-        SelectedShape.BackFill.Gradient.ColorInterpolation := Manager.GradientColorspace;
-        if (SelectedShape.BackFill.Gradient.Repetition in[grSine,grPad]) or
-          Manager.GradientSine then
-        begin
-          if Manager.GradientSine then
-            SelectedShape.BackFill.Gradient.Repetition := grSine
-          else
-            SelectedShape.BackFill.Gradient.Repetition := grPad;
-        end;
-      end else
+      if SelectedShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
       begin
-        if SelectedShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
-        begin
-          doDraw := toDrawShape in Manager.ShapeOptions;
-          doFill := toFillShape in Manager.ShapeOptions;
-
-          if doDraw then
-            SelectedShape.PenStyle := PenStyleToBGRA(Manager.PenStyle)
-          else
-            SelectedShape.PenStyle := ClearPenStyle;
+        doDraw := toDrawShape in Manager.ShapeOptions;
+        doFill := toFillShape in Manager.ShapeOptions;
 
-          if vsfPenWidth in SelectedShape.Fields then SelectedShape.PenWidth := Manager.PenWidth*zoom;
-          if vsfJoinStyle in SelectedShape.Fields then SelectedShape.JoinStyle := Manager.JoinStyle;
-          if SelectedShape is TCustomPolypointShape then
-          begin
-            TCustomPolypointShape(SelectedShape).Closed := toCloseShape in Manager.ShapeOptions;
-            if not TCustomPolypointShape(SelectedShape).Closed then
-            begin
-              TCustomPolypointShape(SelectedShape).LineCap:= Manager.LineCap;
-              TCustomPolypointShape(SelectedShape).ArrowSize:= Manager.ArrowSize;
-              TCustomPolypointShape(SelectedShape).ArrowStartKind:= Manager.ArrowStart;
-              TCustomPolypointShape(SelectedShape).ArrowEndKind:= Manager.ArrowEnd;
-            end;
-          end;
-          if SelectedShape is TCurveShape then
-            TCurveShape(SelectedShape).SplineStyle:= Manager.SplineStyle;
-        end else
-        begin
-          doDraw := vsfPenFill in SelectedShape.Fields;
-          doFill := vsfBackFill in SelectedShape.Fields;
-        end;
-        if doFill then
-        begin
-          if Assigned(Manager.GetTexture) then
-          begin
-            if SelectedShape.BackFill.FillType = vftTexture then
-            begin
-              SelectedShape.BackFill.SetTexture(Manager.GetTexture,
-                SelectedShape.BackFill.TextureMatrix,Manager.TextureOpacity,
-                SelectedShape.BackFill.TextureRepetition);
-            end else
-            if SelectedShape.BackFill.FillType <> vftGradient then
-              SelectedShape.BackFill.SetTexture(Manager.GetTexture, AffineMatrixIdentity,
-                    Manager.TextureOpacity);
-          end else
-          begin
-            if SelectedShape.BackFill.FillType <> vftGradient then
-              SelectedShape.BackFill.SetSolid(Manager.BackColor);
-          end;
-        end else
-          if vsfBackFill in SelectedShape.Fields then
-            SelectedShape.BackFill.Clear;
         if doDraw then
+          SelectedShape.PenStyle := PenStyleToBGRA(Manager.PenStyle)
+        else
+          SelectedShape.PenStyle := ClearPenStyle;
+
+        if vsfPenWidth in SelectedShape.Fields then SelectedShape.PenWidth := Manager.PenWidth*zoom;
+        if vsfJoinStyle in SelectedShape.Fields then SelectedShape.JoinStyle := Manager.JoinStyle;
+        if SelectedShape is TCustomPolypointShape then
         begin
-          if Assigned(Manager.GetTexture) and not doFill then
-          begin
-            if SelectedShape.PenFill.FillType = vftTexture then
-            begin
-              SelectedShape.PenFill.SetTexture(Manager.GetTexture,
-                SelectedShape.PenFill.TextureMatrix,Manager.TextureOpacity,
-                SelectedShape.PenFill.TextureRepetition);
-            end else
-            if SelectedShape.PenFill.FillType <> vftGradient then
-              SelectedShape.PenFill.SetTexture(Manager.GetTexture, AffineMatrixIdentity,
-                    Manager.TextureOpacity);
-          end else
+          TCustomPolypointShape(SelectedShape).Closed := toCloseShape in Manager.ShapeOptions;
+          if not TCustomPolypointShape(SelectedShape).Closed then
           begin
-            if SelectedShape.PenFill.FillType <> vftGradient then
-              SelectedShape.PenFill.SetSolid(Manager.ForeColor);
+            TCustomPolypointShape(SelectedShape).LineCap:= Manager.LineCap;
+            TCustomPolypointShape(SelectedShape).ArrowSize:= Manager.ArrowSize;
+            TCustomPolypointShape(SelectedShape).ArrowStartKind:= Manager.ArrowStart;
+            TCustomPolypointShape(SelectedShape).ArrowEndKind:= Manager.ArrowEnd;
           end;
         end;
-        if SelectedShape is TTextShape then
-        with TTextShape(SelectedShape) do
-        begin
-          PenPhong := Manager.TextPhong;
-          LightPosition := m*Manager.LightPosition;
-          AltitudePercent := Manager.PhongShapeAltitude;
-          ParagraphAlignment := Manager.TextAlign;
-          FontName:= Manager.TextFontName;
-          FontEmHeight:= Manager.TextFontSize*zoom*Manager.Image.DPI/72;
-          FontStyle := Manager.TextFontStyle;
-          if Manager.TextOutline then
-          begin
-            OutlineWidth := Manager.TextOutlineWidth;
-            if OutlineFill.FillType in[vftNone,vftSolid] then
-              OutlineFill.SetSolid(Manager.BackColor);
-          end else
-            OutlineFill.Clear;
-        end;
-        if SelectedShape is TPhongShape then
-        with TPhongShape(SelectedShape) do
+        if SelectedShape is TCurveShape then
+          TCurveShape(SelectedShape).SplineStyle:= Manager.SplineStyle;
+      end else
+      begin
+        doDraw := vsfPenFill in SelectedShape.Fields;
+        doFill := vsfBackFill in SelectedShape.Fields;
+      end;
+      if doFill then AssignFill(SelectedShape.BackFill, Manager.BackFill, gradBox)
+      else if vsfBackFill in SelectedShape.Fields then
+          SelectedShape.BackFill.Clear;
+      if doDraw then AssignFill(SelectedShape.PenFill, Manager.ForeFill, gradBox);
+
+      if SelectedShape is TTextShape then
+      with TTextShape(SelectedShape) do
+      begin
+        PenPhong := Manager.TextPhong;
+        LightPosition := m*Manager.LightPosition;
+        AltitudePercent := Manager.PhongShapeAltitude;
+        ParagraphAlignment := Manager.TextAlign;
+        FontName:= Manager.TextFontName;
+        FontEmHeight:= Manager.TextFontSize*zoom*Manager.Image.DPI/72;
+        FontStyle := Manager.TextFontStyle;
+        if Manager.TextOutline then
         begin
-          ShapeKind := Manager.PhongShapeKind;
-          LightPosition := Manager.LightPosition;
-          ShapeAltitudePercent := Manager.PhongShapeAltitude;
-          BorderSizePercent := Manager.PhongShapeBorderSize;
-        end;
+          OutlineWidth := Manager.TextOutlineWidth;
+          AssignFill(OutLineFill, Manager.BackFill, gradBox);
+        end else
+          OutlineFill.Clear;
+      end;
+      if SelectedShape is TPhongShape then
+      with TPhongShape(SelectedShape) do
+      begin
+        ShapeKind := Manager.PhongShapeKind;
+        LightPosition := Manager.LightPosition;
+        ShapeAltitudePercent := Manager.PhongShapeAltitude;
+        BorderSizePercent := Manager.PhongShapeBorderSize;
       end;
     finally
       BindOriginalEvent(false);
@@ -600,19 +547,9 @@ begin
   esmGradient:
     try
       BindOriginalEvent(true);
-      with GetGradientOriginal do
-      begin
-        StartColor := Manager.ForeColor;
-        EndColor := Manager.BackColor;
-        GradientType:= Manager.GradientType;
-        if (Repetition in [grSine,grPad]) or Manager.GradientSine then
-        begin
-          if Manager.GradientSine then
-            Repetition := grSine
-          else
-            Repetition := grPad;
-        end;
-        ColorInterpolation := Manager.GradientColorspace;
+      case Manager.BackFill.FillType of
+      vftGradient: GetGradientOriginal.AssignExceptGeometry(Manager.BackFill.Gradient);
+      vftSolid: GetGradientOriginal.SetColors(Manager.BackFill.SolidColor, Manager.BackFill.SolidColor);
       end;
     finally
       BindOriginalEvent(false);
@@ -802,7 +739,7 @@ function TEditShapeTool.GetContextualToolbars: TContextualToolbars;
 var
   shape: TVectorShape;
 begin
-  Result:= [ctColor,ctTexture];
+  Result:= [ctFill];
   case GetEditMode of
   esmShape:
     begin
@@ -817,10 +754,8 @@ begin
         result := result + [ctText];
         if TTextShape(shape).PenPhong then include(result, ctAltitude);
       end;
-      if IsGradientShape(shape) then
-        result := result - [ctShape,ctTexture,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap] + [ctGradient];
     end;
-  esmGradient: result := [ctColor,ctGradient];
+  esmGradient: result := [ctFill];
   end;
 end;
 
@@ -926,13 +861,6 @@ begin
   end;
 end;
 
-function TEditShapeTool.IsGradientShape(AShape: TVectorShape): boolean;
-begin
-  result := (vsfBackFill in AShape.Fields) and (AShape.BackFill.FillType = vftGradient) and
-        (not (vsfPenFill in AShape.Fields) or (AShape.PenFill.FillType = vftNone)) and
-        (not (vsfOutlineFill in AShape.Fields) or (AShape.OutlineFill.FillType = vftNone));
-end;
-
 function TEditShapeTool.ConvertToSpline: boolean;
 var
   shapeBefore: TVectorShape;
@@ -1239,14 +1167,7 @@ begin
       if not FIsEditingGradient then
       begin
         FIsEditingGradient:= true;
-        with GetGradientOriginal do
-        begin
-          Manager.ForeColor := StartColor;
-          Manager.BackColor := EndColor;
-          Manager.GradientType := GradientType;
-          Manager.GradientSine := (Repetition = grSine);
-          Manager.GradientColorspace := ColorInterpolation;
-        end;
+        Manager.BackFill.SetGradient(GetGradientOriginal, false);
         Manager.UpdateContextualToolbars;
         handled := true;
         result := OnlyRenderChange;
@@ -1410,6 +1331,14 @@ begin
   end;
 end;
 
+function TEditShapeTool.SuggestGradientBox: TAffineBox;
+begin
+  if GetEditMode = esmShape then
+    result := GetVectorOriginal.SelectedShape.SuggestGradientBox(AffineMatrixIdentity)
+  else
+    result:= inherited SuggestGradientBox;
+end;
+
 { TVectorialTool }
 
 procedure TVectorialTool.ShapeChange(ASender: TObject; ABounds: TRectF; ADiff: TVectorShapeDiff);
@@ -1626,22 +1555,19 @@ procedure TVectorialTool.AssignShapeStyle(AMatrix: TAffineMatrix);
 var
   f: TVectorShapeFields;
   zoom: Single;
+  gradBox: TAffineBox;
 begin
   zoom := (VectLen(AMatrix[1,1],AMatrix[2,1])+VectLen(AMatrix[1,2],AMatrix[2,2]))/2;
   f:= FShape.Fields;
+  gradBox := FShape.SuggestGradientBox(AffineMatrixIdentity);
   if vsfPenFill in f then
   begin
     if Manager.ShapeOptionDraw then
     begin
-      if (not (vsfBackFill in f) or not Manager.ShapeOptionFill) and (Manager.GetTexture <> nil) then
-        FShape.PenFill.SetTexture(Manager.GetTexture,AMatrix,Manager.TextureOpacity)
+      if FSwapColor then
+        AssignFill(FShape.PenFill, Manager.BackFill, gradBox)
       else
-      begin
-        if FSwapColor then
-          FShape.PenFill.SetSolid(Manager.BackColor)
-        else
-          FShape.PenFill.SetSolid(Manager.ForeColor);
-      end;
+        AssignFill(FShape.PenFill, Manager.ForeFill, gradBox);
     end else
       FShape.PenFill.Clear;
   end;
@@ -1652,15 +1578,10 @@ begin
   begin
     if Manager.ShapeOptionFill then
     begin
-      if Manager.GetTexture <> nil then
-        FShape.BackFill.SetTexture(Manager.GetTexture,AffineMatrixIdentity,Manager.TextureOpacity)
+      if FSwapColor then
+        AssignFill(FShape.BackFill, Manager.ForeFill, gradBox)
       else
-      begin
-        if FSwapColor then
-          FShape.BackFill.SetSolid(Manager.ForeColor)
-        else
-          FShape.BackFill.SetSolid(Manager.BackColor);
-      end;
+        AssignFill(FShape.BackFill, Manager.BackFill, gradBox);
     end else
       FShape.BackFill.Clear;
   end;
@@ -2036,6 +1957,14 @@ begin
   end;
 end;
 
+function TVectorialTool.SuggestGradientBox: TAffineBox;
+begin
+  if Assigned(FShape) then
+    result := FShape.SuggestGradientBox(AffineMatrixIdentity)
+  else
+    result:= inherited SuggestGradientBox;
+end;
+
 function TVectorialTool.Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth,
   VirtualScreenHeight: integer;
   BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;

+ 6 - 1
lazpaint/umenu.pas

@@ -52,7 +52,7 @@ implementation
 
 uses UResourceStrings, BGRAUTF8, LCScaleDPI, ComCtrls, Graphics,
   StdCtrls, BGRAText, math, udarktheme, BCTrackbarUpdown, BCTypes,
-  ugraph, BCComboBox, BGRABitmapTypes;
+  ugraph, BCComboBox, BGRABitmapTypes, LCVectorialFillControl;
 
 { TMainFormMenu }
 
@@ -414,6 +414,11 @@ begin
         if assigned(FImageList) then TToolbar(Controls[j]).Images := FImageList;
         TToolbar(Controls[j]).ButtonWidth := TToolbar(Controls[j]).Images.Width+ScaleX(6, 96);
         TToolbar(Controls[j]).ButtonHeight := TToolbar(Controls[j]).Images.Height+ScaleY(6, 96);
+      end else
+      if Controls[j] is TLCVectorialFillControl then
+      begin
+        if assigned(FImageList) then
+          TLCVectorialFillControl(Controls[j]).ToolIconSize:= FImageList.Height;
       end;
     end;
   end;

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác