Przeglądaj źródła

edit vector shapes, some refactoring, LineCap

Johann 6 lat temu
rodzic
commit
066bc7ca30

+ 7 - 7
lazpaint/dialog/filter/uphongfilter.pas

@@ -90,7 +90,7 @@ procedure TFPhongFilter.Button_OKClick(Sender: TObject);
 begin
 begin
   FilterConnector.ValidateAction;
   FilterConnector.ValidateAction;
   FilterConnector.LazPaintInstance.Config.SetDefaultPhongFilterAltitude(SpinEdit_Altitude.Value);
   FilterConnector.LazPaintInstance.Config.SetDefaultPhongFilterAltitude(SpinEdit_Altitude.Value);
-  FilterConnector.LazPaintInstance.ToolManager.ToolLightPosition := CurrentLightPos;
+  FilterConnector.LazPaintInstance.ToolManager.LightPosition := CurrentLightPos;
   ModalResult := mrOK;
   ModalResult := mrOK;
 end;
 end;
 
 
@@ -111,12 +111,12 @@ end;
 procedure TFPhongFilter.FormShow(Sender: TObject);
 procedure TFPhongFilter.FormShow(Sender: TObject);
 begin
 begin
   FInitializing:= true;
   FInitializing:= true;
-  Radio_UseTexture.Enabled := (FilterConnector.LazPaintInstance.ToolManager.GetToolTexture <> nil);
+  Radio_UseTexture.Enabled := (FilterConnector.LazPaintInstance.ToolManager.GetTexture <> nil);
   if Radio_UseTexture.Enabled then Radio_UseTexture.Checked := true
   if Radio_UseTexture.Enabled then Radio_UseTexture.Checked := true
   else Radio_UsePenColor.Checked := true;
   else Radio_UsePenColor.Checked := true;
   SpinEdit_Altitude.Value := FilterConnector.LazPaintInstance.Config.DefaultPhongFilterAltitude;
   SpinEdit_Altitude.Value := FilterConnector.LazPaintInstance.Config.DefaultPhongFilterAltitude;
   SpinEdit_AltitudeChange(nil);
   SpinEdit_AltitudeChange(nil);
-  with FilterConnector.LazPaintInstance.ToolManager.ToolLightPosition do
+  with FilterConnector.LazPaintInstance.ToolManager.LightPosition do
     FCenter := PointF(X/FilterConnector.LazPaintInstance.Image.Width,
     FCenter := PointF(X/FilterConnector.LazPaintInstance.Image.Width,
         Y/FilterConnector.LazPaintInstance.Image.Height);
         Y/FilterConnector.LazPaintInstance.Image.Height);
   FInitializing := false;
   FInitializing := false;
@@ -298,7 +298,7 @@ begin
   shader.AmbientFactor := 0.5;
   shader.AmbientFactor := 0.5;
   shader.NegativeDiffusionFactor := 0.15;
   shader.NegativeDiffusionFactor := 0.15;
   shader.LightPositionF := CurrentLightPos;
   shader.LightPositionF := CurrentLightPos;
-  shader.LightPositionZ := FilterConnector.LazPaintInstance.ToolManager.ToolLightAltitude;
+  shader.LightPositionZ := FilterConnector.LazPaintInstance.ToolManager.LightAltitude;
   if FHeightMap = nil then
   if FHeightMap = nil then
   begin
   begin
     if Radio_MapLightness.Checked then
     if Radio_MapLightness.Checked then
@@ -329,13 +329,13 @@ begin
   if FHeightMap <> nil then
   if FHeightMap <> nil then
   begin
   begin
     if Radio_UseTexture.Checked then
     if Radio_UseTexture.Checked then
-      shader.DrawScan(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.GetToolTextureAfterAlpha)
+      shader.DrawScan(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.GetTextureAfterAlpha)
     else if Radio_UsePenColor.Checked then
     else if Radio_UsePenColor.Checked then
-      shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.ToolForeColor)
+      shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.ForeColor)
     else if Radio_UseKeep.Checked then
     else if Radio_UseKeep.Checked then
       shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.BackupLayer)
       shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.BackupLayer)
     else
     else
-      shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.ToolBackColor);
+      shader.Draw(result, FHeightMap, SpinEdit_Altitude.Value,0,0,FilterConnector.LazPaintInstance.ToolManager.BackColor);
   end;
   end;
   shader.Free;
   shader.Free;
 end;
 end;

+ 8 - 1
lazpaint/image/uimage.pas

@@ -58,6 +58,7 @@ type
     FDraftOriginal: boolean;
     FDraftOriginal: boolean;
 
 
     procedure DiscardSelectionLayerAfterMask;
     procedure DiscardSelectionLayerAfterMask;
+    function GetDPI: integer;
     function GetIsCursor: boolean;
     function GetIsCursor: boolean;
     function GetIsIconCursor: boolean;
     function GetIsIconCursor: boolean;
     function GetIsTiff: boolean;
     function GetIsTiff: boolean;
@@ -265,6 +266,7 @@ type
     property IsCursor: boolean read GetIsCursor;
     property IsCursor: boolean read GetIsCursor;
     property IsTiff: boolean read GetIsTiff;
     property IsTiff: boolean read GetIsTiff;
     property IsGif: boolean read GetIsGif;
     property IsGif: boolean read GetIsGif;
+    property DPI: integer read GetDPI;
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
@@ -714,7 +716,7 @@ begin
     if FCurrentState.SelectedImageLayerIndex = -1 then
     if FCurrentState.SelectedImageLayerIndex = -1 then
       FCurrentState.SelectedImageLayerIndex := 0;
       FCurrentState.SelectedImageLayerIndex := 0;
 
 
-  if Assigned(FOnStackChanged) then FOnStackChanged(self,True);
+  if Assigned(FOnStackChanged)then FOnStackChanged(self,True);
   OnImageChanged.NotifyObservers;
   OnImageChanged.NotifyObservers;
   ImageMayChangeCompletely;
   ImageMayChangeCompletely;
 end;
 end;
@@ -1217,6 +1219,11 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TLazPaintImage.GetDPI: integer;
+begin
+  result := ScreenInfo.PixelsPerInchY;
+end;
+
 function TLazPaintImage.GetIsCursor: boolean;
 function TLazPaintImage.GetIsCursor: boolean;
 begin
 begin
   result := UTF8CompareText(ExtractFileExt(currentFilenameUTF8),'.cur')=0;
   result := UTF8CompareText(ExtractFileExt(currentFilenameUTF8),'.cur')=0;

+ 2 - 2
lazpaint/image/uimageaction.pas

@@ -203,7 +203,7 @@ begin
   if not Image.CheckNoAction then exit;
   if not Image.CheckNoAction then exit;
   LayerAction := nil;
   LayerAction := nil;
   try
   try
-    c := ToolManager.ToolBackColor;
+    c := ToolManager.BackColor;
     c.alpha := 255;
     c.alpha := 255;
     LayerAction := Image.CreateAction(true);
     LayerAction := Image.CreateAction(true);
     LayerAction.SelectedImageLayer.ReplaceColor(BGRAPixelTransparent,c);
     LayerAction.SelectedImageLayer.ReplaceColor(BGRAPixelTransparent,c);
@@ -232,7 +232,7 @@ begin
   if not Image.CheckNoAction then exit;
   if not Image.CheckNoAction then exit;
   LayerAction := nil;
   LayerAction := nil;
   try
   try
-    c := ToolManager.ToolBackColor;
+    c := ToolManager.BackColor;
     c.alpha := 255;
     c.alpha := 255;
     LayerAction := Image.CreateAction(True);
     LayerAction := Image.CreateAction(True);
     tempBmp := TBGRABitmap.Create(LayerAction.SelectedImageLayer.Width,1);
     tempBmp := TBGRABitmap.Create(LayerAction.SelectedImageLayer.Width,1);

+ 2 - 2
lazpaint/image/uimagediff.pas

@@ -472,7 +472,7 @@ type
 implementation
 implementation
 
 
 uses BGRAWriteLzp, BGRAReadLzp, UImageState, BGRAStreamLayers, BGRALzpCommon, ugraph, Types,
 uses BGRAWriteLzp, BGRAReadLzp, UImageState, BGRAStreamLayers, BGRALzpCommon, ugraph, Types,
-  BGRATransform, zstream, LCVectorRectShapes, BGRAPen;
+  BGRATransform, zstream, LCVectorRectShapes, BGRAPen, LCVectorialFill;
 
 
 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
 begin
 begin
@@ -872,7 +872,7 @@ begin
     shape.QuickDefine(PointF(0,0),PointF(FSourceBounds.Width,FSourceBounds.Height));
     shape.QuickDefine(PointF(0,0),PointF(FSourceBounds.Width,FSourceBounds.Height));
     shape.PenStyle := ClearPenStyle;
     shape.PenStyle := ClearPenStyle;
     temp := source.GetPart(FSourceBounds) as TBGRABitmap;
     temp := source.GetPart(FSourceBounds) as TBGRABitmap;
-    shape.BackFill.SetTexture(temp,AffineMatrixIdentity);
+    shape.BackFill.SetTexture(temp,AffineMatrixIdentity,255,trNone);
     temp.FreeReference;
     temp.FreeReference;
     orig.AddShape(shape);
     orig.AddShape(shape);
   end;
   end;

+ 9 - 51
lazpaint/lazpaintinstance.pas

@@ -350,28 +350,7 @@ procedure TLazPaintInstance.UseConfig(ini: TInifile);
 begin
 begin
   FreeAndNil(FConfig);
   FreeAndNil(FConfig);
   FConfig := TLazPaintConfig.Create(ini,LazPaintVersionStr);
   FConfig := TLazPaintConfig.Create(ini,LazPaintVersionStr);
-
-  ToolManager.ToolForeColor := Config.DefaultToolForeColor;
-  ToolManager.ToolBackColor := Config.DefaultToolBackColor;
-  ToolManager.ToolNormalPenWidth := Config.DefaultToolPenWidth;
-  ToolManager.ToolEraserWidth := Config.DefaultToolEraserWidth;
-  ToolManager.ToolOptionDrawShape := Config.DefaultToolOptionDrawShape;
-  ToolManager.ToolOptionFillShape := Config.DefaultToolOptionFillShape;
-  ToolManager.ToolOptionCloseShape := Config.DefaultToolOptionCloseShape;
-  ToolManager.ToolTolerance := Config.DefaultToolTolerance;
-  ToolManager.ToolTextShadow := Config.DefaultToolTextShadow;
-  ToolManager.ToolTextOutline := Config.DefaultToolTextOutline;
-  ToolManager.ToolTextOutlineWidth := Config.DefaultToolTextOutlineWidth;
-  ToolManager.ToolTextPhong := Config.DefaultToolTextPhong;
-  ToolManager.ToolTextFont.Assign(Config.DefaultToolTextFont);
-  ToolManager.ToolTextBlur := Config.DefaultToolTextBlur;
-  ToolManager.ToolTextShadowOffset := Config.DefaultToolTextShadowOffset;
-  ToolManager.ToolLightPosition := Config.DefaultToolLightPosition;
-  ToolManager.ToolLightAltitude := Config.DefaultToolLightAltitude;
-  ToolManager.ToolShapeAltitude := Config.DefaultToolShapeAltitude;
-  ToolManager.ToolShapeBorderSize := Config.DefaultToolShapeBorderSize;
-  ToolManager.ToolShapeType := Config.DefaultToolShapeType;
-  ToolManager.ReloadBrushes;
+  ToolManager.LoadFromConfig;
   FGridVisible := Config.DefaultGridVisible;
   FGridVisible := Config.DefaultGridVisible;
   FDockLayersAndColors:= Config.DefaultDockLayersAndColors;
   FDockLayersAndColors:= Config.DefaultDockLayersAndColors;
 end;
 end;
@@ -847,11 +826,11 @@ begin
       FTextureEditConfig := TStringStream.Create('[General]'+LineEnding+
       FTextureEditConfig := TStringStream.Create('[General]'+LineEnding+
         'DefaultImageWidth=256'+LineEnding+
         'DefaultImageWidth=256'+LineEnding+
         'DefaultImageHeight=256'+LineEnding);
         'DefaultImageHeight=256'+LineEnding);
-    tex := ToolManager.BorrowToolTexture;
+    tex := ToolManager.BorrowTexture;
     try
     try
       EditBitmap(tex,FTextureEditConfig,rsEditTexture,nil,nil,BlackAndWhite);
       EditBitmap(tex,FTextureEditConfig,rsEditTexture,nil,nil,BlackAndWhite);
     finally
     finally
-      ToolManager.SetToolTexture(tex);
+      ToolManager.SetTexture(tex);
     end;
     end;
   except
   except
     on ex: Exception do
     on ex: Exception do
@@ -868,7 +847,7 @@ end;
 procedure TLazPaintInstance.ToolColorChanged(Sender: TObject);
 procedure TLazPaintInstance.ToolColorChanged(Sender: TObject);
 begin
 begin
   ColorToFChooseColor;
   ColorToFChooseColor;
-  if Assigned(FMain) then FMain.UpdateToolbar;
+  if Assigned(FMain) then FMain.UpdateColorToolbar(false);
 end;
 end;
 
 
 function TLazPaintInstance.GetIcons(ASize: integer): TImageList;
 function TLazPaintInstance.GetIcons(ASize: integer): TImageList;
@@ -1084,28 +1063,7 @@ begin
     Config.SetDefaultToolboxWindowVisible(ToolboxVisible or (FTopMostInfo.toolboxHidden > 0));
     Config.SetDefaultToolboxWindowVisible(ToolboxVisible or (FTopMostInfo.toolboxHidden > 0));
     Config.SetDefaultToolboxWindowPosition(FToolBox.BoundsRect);
     Config.SetDefaultToolboxWindowPosition(FToolBox.BoundsRect);
   end;
   end;
-  Config.SetDefaultToolForeColor(ToolManager.ToolForeColor);
-  Config.SetDefaultToolBackColor(ToolManager.ToolBackColor);
-  Config.SetDefaultToolPenWidth(ToolManager.ToolNormalPenWidth);
-  Config.SetDefaultToolEraserWidth(ToolManager.ToolEraserWidth);
-  Config.SetDefaultToolOptionDrawShape(ToolManager.ToolOptionDrawShape);
-  Config.SetDefaultToolOptionFillShape(ToolManager.ToolOptionFillShape);
-  Config.SetDefaultToolOptionCloseShape(ToolManager.ToolOptionCloseShape);
-  Config.SetDefaultToolTolerance(ToolManager.ToolTolerance);
-
-  Config.SetDefaultToolTextFont(ToolManager.ToolTextFont);
-  Config.SetDefaultToolTextShadow(ToolManager.ToolTextShadow);
-  Config.SetDefaultToolTextOutline(ToolManager.ToolTextOutline);
-  Config.SetDefaultToolTextOutlineWidth(ToolManager.ToolTextOutlineWidth);
-  Config.SetDefaultToolTextBlur(ToolManager.ToolTextBlur);
-  Config.SetDefaultToolTextShadowOffset(ToolManager.ToolTextShadowOffset);
-  Config.SetDefaultToolTextPhong(ToolManager.ToolTextPhong);
-
-  Config.SetDefaultToolLightPosition(ToolManager.ToolLightPosition);
-  Config.SetDefaultToolLightAltitude(ToolManager.ToolLightAltitude);
-  Config.SetDefaultToolShapeBorderSize(ToolManager.ToolShapeBorderSize);
-  Config.SetDefaultToolShapeAltitude(ToolManager.ToolShapeAltitude);
-  Config.SetDefaultToolShapeType(ToolManager.ToolShapeType);
+  ToolManager.SaveToConfig;
 
 
   if FLoadingLayers <> nil then
   if FLoadingLayers <> nil then
   begin
   begin
@@ -1248,9 +1206,9 @@ begin
   if InColorFromFChooseColor then exit;
   if InColorFromFChooseColor then exit;
   InColorFromFChooseColor := True;
   InColorFromFChooseColor := True;
   if FChooseColor.colorTarget = ctForeColor then
   if FChooseColor.colorTarget = ctForeColor then
-    ToolManager.ToolForeColor := FChooseColor.GetCurrentColor else
+    ToolManager.ForeColor := FChooseColor.GetCurrentColor else
   if FChooseColor.colorTarget = ctBackColor then
   if FChooseColor.colorTarget = ctBackColor then
-    ToolManager.ToolBackColor := FChooseColor.GetCurrentColor;
+    ToolManager.BackColor := FChooseColor.GetCurrentColor;
   if Assigned(FMain) then FMain.UpdateEditPicture;
   if Assigned(FMain) then FMain.UpdateEditPicture;
   InColorFromFChooseColor := false;
   InColorFromFChooseColor := false;
 end;
 end;
@@ -1259,9 +1217,9 @@ procedure TLazPaintInstance.ColorToFChooseColor;
 begin
 begin
   if not Assigned(FChooseColor) or InColorFromFChooseColor then exit;
   if not Assigned(FChooseColor) or InColorFromFChooseColor then exit;
   if FChooseColor.colorTarget = ctForeColor then
   if FChooseColor.colorTarget = ctForeColor then
-    FChooseColor.SetCurrentColor(ToolManager.ToolForeColor) else
+    FChooseColor.SetCurrentColor(ToolManager.ForeColor) else
   if FChooseColor.colorTarget = ctBackColor then
   if FChooseColor.colorTarget = ctBackColor then
-    FChooseColor.SetCurrentColor(ToolManager.ToolBackColor);
+    FChooseColor.SetCurrentColor(ToolManager.BackColor);
 end;
 end;
 
 
 function TLazPaintInstance.ShowSaveOptionDlg(AParameters: TVariableSet;
 function TLazPaintInstance.ShowSaveOptionDlg(AParameters: TVariableSet;

+ 242 - 192
lazpaint/lazpaintmainform.lfm

@@ -940,12 +940,12 @@ object FMain: TFMain
     end
     end
   end
   end
   object Panel_LineCap: TPanel
   object Panel_LineCap: TPanel
-    Left = 90
+    Left = 144
     Height = 45
     Height = 45
     Top = 130
     Top = 130
-    Width = 348
+    Width = 318
     ClientHeight = 45
     ClientHeight = 45
-    ClientWidth = 348
+    ClientWidth = 318
     Font.Height = -15
     Font.Height = -15
     ParentColor = False
     ParentColor = False
     ParentFont = False
     ParentFont = False
@@ -954,7 +954,7 @@ object FMain: TFMain
       Left = 221
       Left = 221
       Height = 28
       Height = 28
       Top = 1
       Top = 1
-      Width = 117
+      Width = 88
       Align = alNone
       Align = alNone
       AutoSize = True
       AutoSize = True
       EdgeBorders = []
       EdgeBorders = []
@@ -963,7 +963,7 @@ object FMain: TFMain
       ParentFont = False
       ParentFont = False
       TabOrder = 0
       TabOrder = 0
       object Tool_CapFlat: TToolButton
       object Tool_CapFlat: TToolButton
-        Left = 30
+        Left = 1
         Hint = 'Flat cap'
         Hint = 'Flat cap'
         Top = 0
         Top = 0
         Grouped = True
         Grouped = True
@@ -971,7 +971,7 @@ object FMain: TFMain
         Style = tbsCheck
         Style = tbsCheck
       end
       end
       object Tool_CapRound: TToolButton
       object Tool_CapRound: TToolButton
-        Left = 59
+        Left = 30
         Hint = 'Round cap'
         Hint = 'Round cap'
         Top = 0
         Top = 0
         Down = True
         Down = True
@@ -980,20 +980,13 @@ object FMain: TFMain
         Style = tbsCheck
         Style = tbsCheck
       end
       end
       object Tool_CapSquare: TToolButton
       object Tool_CapSquare: TToolButton
-        Left = 88
+        Left = 59
         Hint = 'Square cap'
         Hint = 'Square cap'
         Top = 0
         Top = 0
         Grouped = True
         Grouped = True
         ImageIndex = 47
         ImageIndex = 47
         Style = tbsCheck
         Style = tbsCheck
       end
       end
-      object Tool_CloseShape: TToolButton
-        Left = 1
-        Hint = 'Close shape'
-        Top = 0
-        ImageIndex = 10
-        Style = tbsCheck
-      end
     end
     end
     object SpinEdit_ArrowSizeX: TBCTrackbarUpdown
     object SpinEdit_ArrowSizeX: TBCTrackbarUpdown
       Left = 116
       Left = 116
@@ -1229,7 +1222,7 @@ object FMain: TFMain
     end
     end
   end
   end
   object Panel_JoinStyle: TPanel
   object Panel_JoinStyle: TPanel
-    Left = 460
+    Left = 480
     Height = 45
     Height = 45
     Top = 130
     Top = 130
     Width = 94
     Width = 94
@@ -1279,7 +1272,7 @@ object FMain: TFMain
     end
     end
   end
   end
   object Panel_PenStyle: TPanel
   object Panel_PenStyle: TPanel
-    Left = 576
+    Left = 584
     Height = 45
     Height = 45
     Top = 130
     Top = 130
     Width = 150
     Width = 150
@@ -1785,9 +1778,9 @@ object FMain: TFMain
     Left = 10
     Left = 10
     Height = 45
     Height = 45
     Top = 250
     Top = 250
-    Width = 556
+    Width = 262
     ClientHeight = 45
     ClientHeight = 45
-    ClientWidth = 556
+    ClientWidth = 262
     Font.Height = -15
     Font.Height = -15
     ParentColor = False
     ParentColor = False
     ParentFont = False
     ParentFont = False
@@ -1808,7 +1801,7 @@ object FMain: TFMain
       Left = 106
       Left = 106
       Height = 28
       Height = 28
       Top = 1
       Top = 1
-      Width = 175
+      Width = 146
       Align = alNone
       Align = alNone
       AutoSize = True
       AutoSize = True
       EdgeBorders = []
       EdgeBorders = []
@@ -1822,13 +1815,6 @@ object FMain: TFMain
         Top = 0
         Top = 0
         ImageIndex = 61
         ImageIndex = 61
       end
       end
-      object Tool_TextShadow: TToolButton
-        Left = 146
-        Hint = 'Text shadow'
-        Top = 0
-        ImageIndex = 62
-        Style = tbsCheck
-      end
       object Tool_TextPhong: TToolButton
       object Tool_TextPhong: TToolButton
         Left = 117
         Left = 117
         Hint = 'Text phong shading'
         Hint = 'Text phong shading'
@@ -1859,30 +1845,6 @@ object FMain: TFMain
         Style = tbsCheck
         Style = tbsCheck
       end
       end
     end
     end
-    object Label_TextBlur: TLabel
-      Left = 291
-      Height = 28
-      Top = 2
-      Width = 40
-      AutoSize = False
-      Caption = 'Blur'
-      Font.Height = -15
-      Layout = tlCenter
-      ParentColor = False
-      ParentFont = False
-    end
-    object Label_ShadowOffset: TLabel
-      Left = 394
-      Height = 28
-      Top = 1
-      Width = 54
-      AutoSize = False
-      Caption = 'Offset'
-      Font.Height = -15
-      Layout = tlCenter
-      ParentColor = False
-      ParentFont = False
-    end
     object SpinEdit_TextSize: TBCTrackbarUpdown
     object SpinEdit_TextSize: TBCTrackbarUpdown
       Left = 46
       Left = 46
       Height = 25
       Height = 25
@@ -1930,147 +1892,6 @@ object FMain: TFMain
       TabStop = True
       TabStop = True
       UseDockManager = False
       UseDockManager = False
     end
     end
-    object SpinEdit_TextBlur: TBCTrackbarUpdown
-      Left = 331
-      Height = 25
-      Hint = 'Shadow blur'
-      Top = 2
-      Width = 51
-      AllowNegativeValues = False
-      BarExponent = 1
-      Increment = 1
-      LongTimeInterval = 400
-      MinValue = 0
-      MaxValue = 200
-      Value = 5
-      ShortTimeInterval = 100
-      Background.Color = clWindow
-      Background.Gradient1.StartColor = clWhite
-      Background.Gradient1.EndColor = clBlack
-      Background.Gradient2.StartColor = clWhite
-      Background.Gradient2.EndColor = clBlack
-      Background.Style = bbsColor
-      ButtonBackground.Gradient1.StartColor = clBtnShadow
-      ButtonBackground.Gradient1.EndColor = clBtnFace
-      ButtonBackground.Gradient1.Point1YPercent = -50
-      ButtonBackground.Gradient1.Point2YPercent = 50
-      ButtonBackground.Gradient2.StartColor = clBtnFace
-      ButtonBackground.Gradient2.EndColor = clBtnShadow
-      ButtonBackground.Gradient2.Point1YPercent = 50
-      ButtonBackground.Gradient2.Point2YPercent = 150
-      ButtonBackground.Gradient1EndPercent = 50
-      ButtonBackground.Style = bbsGradient
-      ButtonDownBackground.Color = clBtnShadow
-      ButtonDownBackground.Gradient1.StartColor = clWhite
-      ButtonDownBackground.Gradient1.EndColor = clBlack
-      ButtonDownBackground.Gradient2.StartColor = clWhite
-      ButtonDownBackground.Gradient2.EndColor = clBlack
-      ButtonDownBackground.Style = bbsColor
-      Border.Color = clWindowText
-      Rounding.RoundX = 1
-      Rounding.RoundY = 1
-      Font.Color = clWindowText
-      Font.Name = 'Arial'
-      HasTrackBar = True
-      ArrowColor = clBtnText
-      TabOrder = 2
-      TabStop = True
-      UseDockManager = False
-    end
-    object SpinEdit_TextShadowX: TBCTrackbarUpdown
-      Left = 449
-      Height = 25
-      Hint = 'Horizontal shadow offset'
-      Top = 2
-      Width = 51
-      AllowNegativeValues = True
-      BarExponent = 1
-      Increment = 1
-      LongTimeInterval = 400
-      MinValue = 0
-      MaxValue = 100
-      Value = 5
-      ShortTimeInterval = 100
-      Background.Color = clWindow
-      Background.Gradient1.StartColor = clWhite
-      Background.Gradient1.EndColor = clBlack
-      Background.Gradient2.StartColor = clWhite
-      Background.Gradient2.EndColor = clBlack
-      Background.Style = bbsColor
-      ButtonBackground.Gradient1.StartColor = clBtnShadow
-      ButtonBackground.Gradient1.EndColor = clBtnFace
-      ButtonBackground.Gradient1.Point1YPercent = -50
-      ButtonBackground.Gradient1.Point2YPercent = 50
-      ButtonBackground.Gradient2.StartColor = clBtnFace
-      ButtonBackground.Gradient2.EndColor = clBtnShadow
-      ButtonBackground.Gradient2.Point1YPercent = 50
-      ButtonBackground.Gradient2.Point2YPercent = 150
-      ButtonBackground.Gradient1EndPercent = 50
-      ButtonBackground.Style = bbsGradient
-      ButtonDownBackground.Color = clBtnShadow
-      ButtonDownBackground.Gradient1.StartColor = clWhite
-      ButtonDownBackground.Gradient1.EndColor = clBlack
-      ButtonDownBackground.Gradient2.StartColor = clWhite
-      ButtonDownBackground.Gradient2.EndColor = clBlack
-      ButtonDownBackground.Style = bbsColor
-      Border.Color = clWindowText
-      Rounding.RoundX = 1
-      Rounding.RoundY = 1
-      Font.Color = clWindowText
-      Font.Name = 'Arial'
-      HasTrackBar = True
-      ArrowColor = clBtnText
-      TabOrder = 3
-      TabStop = True
-      UseDockManager = False
-    end
-    object SpinEdit_TextShadowY: TBCTrackbarUpdown
-      Left = 502
-      Height = 25
-      Hint = 'Vertical shadow offset'
-      Top = 2
-      Width = 51
-      AllowNegativeValues = True
-      BarExponent = 1
-      Increment = 1
-      LongTimeInterval = 400
-      MinValue = 0
-      MaxValue = 100
-      Value = 5
-      ShortTimeInterval = 100
-      Background.Color = clWindow
-      Background.Gradient1.StartColor = clWhite
-      Background.Gradient1.EndColor = clBlack
-      Background.Gradient2.StartColor = clWhite
-      Background.Gradient2.EndColor = clBlack
-      Background.Style = bbsColor
-      ButtonBackground.Gradient1.StartColor = clBtnShadow
-      ButtonBackground.Gradient1.EndColor = clBtnFace
-      ButtonBackground.Gradient1.Point1YPercent = -50
-      ButtonBackground.Gradient1.Point2YPercent = 50
-      ButtonBackground.Gradient2.StartColor = clBtnFace
-      ButtonBackground.Gradient2.EndColor = clBtnShadow
-      ButtonBackground.Gradient2.Point1YPercent = 50
-      ButtonBackground.Gradient2.Point2YPercent = 150
-      ButtonBackground.Gradient1EndPercent = 50
-      ButtonBackground.Style = bbsGradient
-      ButtonDownBackground.Color = clBtnShadow
-      ButtonDownBackground.Gradient1.StartColor = clWhite
-      ButtonDownBackground.Gradient1.EndColor = clBlack
-      ButtonDownBackground.Gradient2.StartColor = clWhite
-      ButtonDownBackground.Gradient2.EndColor = clBlack
-      ButtonDownBackground.Style = bbsColor
-      Border.Color = clWindowText
-      Rounding.RoundX = 1
-      Rounding.RoundY = 1
-      Font.Color = clWindowText
-      Font.Name = 'Arial'
-      HasTrackBar = True
-      ArrowColor = clBtnText
-      TabOrder = 4
-      TabStop = True
-      UseDockManager = False
-    end
   end
   end
   object Panel_PhongShape: TPanel
   object Panel_PhongShape: TPanel
     Left = 10
     Left = 10
@@ -2298,7 +2119,7 @@ object FMain: TFMain
     end
     end
   end
   end
   object Panel_TextOutline: TPanel
   object Panel_TextOutline: TPanel
-    Left = 580
+    Left = 599
     Height = 45
     Height = 45
     Top = 250
     Top = 250
     Width = 146
     Width = 146
@@ -2700,6 +2521,235 @@ object FMain: TFMain
       end
       end
     end
     end
   end
   end
+  object Panel_CloseShape: TPanel
+    Left = 88
+    Height = 46
+    Top = 130
+    Width = 44
+    ClientHeight = 46
+    ClientWidth = 44
+    Font.Height = -15
+    ParentColor = False
+    ParentFont = False
+    TabOrder = 29
+    object ToolBar23: TToolBar
+      Left = 1
+      Height = 28
+      Top = 1
+      Width = 30
+      Align = alNone
+      AutoSize = True
+      EdgeBorders = []
+      Font.Height = -15
+      Images = ImageList16
+      ParentFont = False
+      TabOrder = 0
+      object Tool_CloseShape: TToolButton
+        Left = 1
+        Hint = 'Close shape'
+        Top = 0
+        ImageIndex = 10
+        Style = tbsCheck
+      end
+    end
+  end
+  object Panel_TextShadow: TPanel
+    Left = 280
+    Height = 45
+    Top = 250
+    Width = 307
+    ClientHeight = 45
+    ClientWidth = 307
+    Font.Height = -15
+    ParentColor = False
+    ParentFont = False
+    TabOrder = 30
+    object ToolBar24: TToolBar
+      Left = 1
+      Height = 28
+      Top = 1
+      Width = 30
+      Align = alNone
+      AutoSize = True
+      EdgeBorders = []
+      Font.Height = -15
+      Images = ImageList16
+      ParentFont = False
+      TabOrder = 0
+      object Tool_TextShadow: TToolButton
+        Left = 1
+        Hint = 'Text shadow'
+        Top = 0
+        ImageIndex = 62
+        Style = tbsCheck
+      end
+    end
+    object Label_TextBlur: TLabel
+      Left = 35
+      Height = 28
+      Top = 1
+      Width = 40
+      AutoSize = False
+      Caption = 'Blur'
+      Font.Height = -15
+      Layout = tlCenter
+      ParentColor = False
+      ParentFont = False
+    end
+    object SpinEdit_TextBlur: TBCTrackbarUpdown
+      Left = 75
+      Height = 25
+      Hint = 'Shadow blur'
+      Top = 1
+      Width = 51
+      AllowNegativeValues = False
+      BarExponent = 1
+      Increment = 1
+      LongTimeInterval = 400
+      MinValue = 0
+      MaxValue = 200
+      Value = 5
+      ShortTimeInterval = 100
+      Background.Color = clWindow
+      Background.Gradient1.StartColor = clWhite
+      Background.Gradient1.EndColor = clBlack
+      Background.Gradient2.StartColor = clWhite
+      Background.Gradient2.EndColor = clBlack
+      Background.Style = bbsColor
+      ButtonBackground.Gradient1.StartColor = clBtnShadow
+      ButtonBackground.Gradient1.EndColor = clBtnFace
+      ButtonBackground.Gradient1.Point1YPercent = -50
+      ButtonBackground.Gradient1.Point2YPercent = 50
+      ButtonBackground.Gradient2.StartColor = clBtnFace
+      ButtonBackground.Gradient2.EndColor = clBtnShadow
+      ButtonBackground.Gradient2.Point1YPercent = 50
+      ButtonBackground.Gradient2.Point2YPercent = 150
+      ButtonBackground.Gradient1EndPercent = 50
+      ButtonBackground.Style = bbsGradient
+      ButtonDownBackground.Color = clBtnShadow
+      ButtonDownBackground.Gradient1.StartColor = clWhite
+      ButtonDownBackground.Gradient1.EndColor = clBlack
+      ButtonDownBackground.Gradient2.StartColor = clWhite
+      ButtonDownBackground.Gradient2.EndColor = clBlack
+      ButtonDownBackground.Style = bbsColor
+      Border.Color = clWindowText
+      Rounding.RoundX = 1
+      Rounding.RoundY = 1
+      Font.Color = clWindowText
+      Font.Name = 'Arial'
+      HasTrackBar = True
+      ArrowColor = clBtnText
+      TabOrder = 1
+      TabStop = True
+      UseDockManager = False
+    end
+    object Label_ShadowOffset: TLabel
+      Left = 138
+      Height = 28
+      Top = 0
+      Width = 54
+      AutoSize = False
+      Caption = 'Offset'
+      Font.Height = -15
+      Layout = tlCenter
+      ParentColor = False
+      ParentFont = False
+    end
+    object SpinEdit_TextShadowX: TBCTrackbarUpdown
+      Left = 193
+      Height = 25
+      Hint = 'Horizontal shadow offset'
+      Top = 1
+      Width = 51
+      AllowNegativeValues = True
+      BarExponent = 1
+      Increment = 1
+      LongTimeInterval = 400
+      MinValue = 0
+      MaxValue = 100
+      Value = 5
+      ShortTimeInterval = 100
+      Background.Color = clWindow
+      Background.Gradient1.StartColor = clWhite
+      Background.Gradient1.EndColor = clBlack
+      Background.Gradient2.StartColor = clWhite
+      Background.Gradient2.EndColor = clBlack
+      Background.Style = bbsColor
+      ButtonBackground.Gradient1.StartColor = clBtnShadow
+      ButtonBackground.Gradient1.EndColor = clBtnFace
+      ButtonBackground.Gradient1.Point1YPercent = -50
+      ButtonBackground.Gradient1.Point2YPercent = 50
+      ButtonBackground.Gradient2.StartColor = clBtnFace
+      ButtonBackground.Gradient2.EndColor = clBtnShadow
+      ButtonBackground.Gradient2.Point1YPercent = 50
+      ButtonBackground.Gradient2.Point2YPercent = 150
+      ButtonBackground.Gradient1EndPercent = 50
+      ButtonBackground.Style = bbsGradient
+      ButtonDownBackground.Color = clBtnShadow
+      ButtonDownBackground.Gradient1.StartColor = clWhite
+      ButtonDownBackground.Gradient1.EndColor = clBlack
+      ButtonDownBackground.Gradient2.StartColor = clWhite
+      ButtonDownBackground.Gradient2.EndColor = clBlack
+      ButtonDownBackground.Style = bbsColor
+      Border.Color = clWindowText
+      Rounding.RoundX = 1
+      Rounding.RoundY = 1
+      Font.Color = clWindowText
+      Font.Name = 'Arial'
+      HasTrackBar = True
+      ArrowColor = clBtnText
+      TabOrder = 2
+      TabStop = True
+      UseDockManager = False
+    end
+    object SpinEdit_TextShadowY: TBCTrackbarUpdown
+      Left = 246
+      Height = 25
+      Hint = 'Vertical shadow offset'
+      Top = 1
+      Width = 51
+      AllowNegativeValues = True
+      BarExponent = 1
+      Increment = 1
+      LongTimeInterval = 400
+      MinValue = 0
+      MaxValue = 100
+      Value = 5
+      ShortTimeInterval = 100
+      Background.Color = clWindow
+      Background.Gradient1.StartColor = clWhite
+      Background.Gradient1.EndColor = clBlack
+      Background.Gradient2.StartColor = clWhite
+      Background.Gradient2.EndColor = clBlack
+      Background.Style = bbsColor
+      ButtonBackground.Gradient1.StartColor = clBtnShadow
+      ButtonBackground.Gradient1.EndColor = clBtnFace
+      ButtonBackground.Gradient1.Point1YPercent = -50
+      ButtonBackground.Gradient1.Point2YPercent = 50
+      ButtonBackground.Gradient2.StartColor = clBtnFace
+      ButtonBackground.Gradient2.EndColor = clBtnShadow
+      ButtonBackground.Gradient2.Point1YPercent = 50
+      ButtonBackground.Gradient2.Point2YPercent = 150
+      ButtonBackground.Gradient1EndPercent = 50
+      ButtonBackground.Style = bbsGradient
+      ButtonDownBackground.Color = clBtnShadow
+      ButtonDownBackground.Gradient1.StartColor = clWhite
+      ButtonDownBackground.Gradient1.EndColor = clBlack
+      ButtonDownBackground.Gradient2.StartColor = clWhite
+      ButtonDownBackground.Gradient2.EndColor = clBlack
+      ButtonDownBackground.Style = bbsColor
+      Border.Color = clWindowText
+      Rounding.RoundX = 1
+      Rounding.RoundY = 1
+      Font.Color = clWindowText
+      Font.Name = 'Arial'
+      HasTrackBar = True
+      ArrowColor = clBtnText
+      TabOrder = 3
+      TabStop = True
+      UseDockManager = False
+    end
+  end
   object ImageList16: TBGRAImageList
   object ImageList16: TBGRAImageList
     left = 48
     left = 48
     top = 672
     top = 672

+ 153 - 35
lazpaint/lazpaintmainform.pas

@@ -13,11 +13,11 @@ uses
   Graphics, Dialogs, Menus, ExtDlgs, ComCtrls, ActnList, StdCtrls, ExtCtrls,
   Graphics, Dialogs, Menus, ExtDlgs, ComCtrls, ActnList, StdCtrls, ExtCtrls,
   Buttons, types, LCLType, BGRAImageList, BCTrackbarUpdown, BCComboBox, BCButton,
   Buttons, types, LCLType, BGRAImageList, BCTrackbarUpdown, BCComboBox, BCButton,
 
 
-  BGRABitmap, BGRABitmapTypes, BGRALayers, BGRASVGOriginal,
+  BGRABitmap, BGRABitmapTypes, BGRALayers, BGRASVGOriginal, BGRAGradientScanner,
 
 
   LazPaintType, UMainFormLayout, UTool, UImage, UImageAction, UZoom, UImageView,
   LazPaintType, UMainFormLayout, UTool, UImage, UImageAction, UZoom, UImageView,
   UImageObservation, UConfig, LCScaleDPI, UResourceStrings,
   UImageObservation, UConfig, LCScaleDPI, UResourceStrings,
-  UMenu, uscripting, ubrowseimages, UToolPolygon,
+  UMenu, uscripting, ubrowseimages, UToolPolygon, UToolVectorial, LCVectorRectShapes,
 
 
   laztablet, udarktheme;
   laztablet, udarktheme;
 
 
@@ -28,6 +28,15 @@ type
   { TFMain }
   { TFMain }
 
 
   TFMain = class(TForm)
   TFMain = class(TForm)
+    Label_ShadowOffset: TLabel;
+    Label_TextBlur: TLabel;
+    Panel_TextShadow: TPanel;
+    Panel_CloseShape: TPanel;
+    SpinEdit_TextBlur: TBCTrackbarUpdown;
+    SpinEdit_TextShadowX: TBCTrackbarUpdown;
+    SpinEdit_TextShadowY: TBCTrackbarUpdown;
+    ToolBar23: TToolBar;
+    ToolBar24: TToolBar;
     ToolEditShape: TAction;
     ToolEditShape: TAction;
     ComboBox_ArrowStart: TBCComboBox;
     ComboBox_ArrowStart: TBCComboBox;
     ComboBox_ArrowEnd: TBCComboBox;
     ComboBox_ArrowEnd: TBCComboBox;
@@ -46,13 +55,12 @@ type
     SpinEdit_Tolerance: TBCTrackbarUpdown;
     SpinEdit_Tolerance: TBCTrackbarUpdown;
     SpinEdit_BrushSpacing: TBCTrackbarUpdown;
     SpinEdit_BrushSpacing: TBCTrackbarUpdown;
     SpinEdit_ShapeAltitude: TBCTrackbarUpdown;
     SpinEdit_ShapeAltitude: TBCTrackbarUpdown;
-    SpinEdit_TextShadowX: TBCTrackbarUpdown;
-    SpinEdit_TextBlur: TBCTrackbarUpdown;
     SpinEdit_TextOutlineWidth: TBCTrackbarUpdown;
     SpinEdit_TextOutlineWidth: TBCTrackbarUpdown;
     SpinEdit_PhongBorderSize: TBCTrackbarUpdown;
     SpinEdit_PhongBorderSize: TBCTrackbarUpdown;
-    SpinEdit_TextShadowY: TBCTrackbarUpdown;
     SpinEdit_TextSize: TBCTrackbarUpdown;
     SpinEdit_TextSize: TBCTrackbarUpdown;
     SpinEdit_TextureOpacity: TBCTrackbarUpdown;
     SpinEdit_TextureOpacity: TBCTrackbarUpdown;
+    Tool_CloseShape: TToolButton;
+    Tool_TextShadow: TToolButton;
     ViewDarkTheme: TAction;
     ViewDarkTheme: TAction;
     MenuFileToolbar: TMenuItem;
     MenuFileToolbar: TMenuItem;
     ViewWorkspaceColor: TAction;
     ViewWorkspaceColor: TAction;
@@ -304,13 +312,10 @@ type
     Tool_PhongShapeRoundRect: TToolButton;
     Tool_PhongShapeRoundRect: TToolButton;
     FontDialog1: TFontDialog;
     FontDialog1: TFontDialog;
     LoadSelectionDialog: TOpenPictureDialog;
     LoadSelectionDialog: TOpenPictureDialog;
-    Label_TextBlur: TLabel;
-    Label_ShadowOffset: TLabel;
     Label_Text: TLabel;
     Label_Text: TLabel;
     Panel_Text: TPanel;
     Panel_Text: TPanel;
     ToolBar15: TToolBar;
     ToolBar15: TToolBar;
     Tool_TextFont: TToolButton;
     Tool_TextFont: TToolButton;
-    Tool_TextShadow: TToolButton;
     PaintBox_Picture: TPaintBox;
     PaintBox_Picture: TPaintBox;
     PaintBox_PenPreview: TPaintBox;
     PaintBox_PenPreview: TPaintBox;
     Panel_Embedded: TPanel;
     Panel_Embedded: TPanel;
@@ -322,7 +327,6 @@ type
     Label_GridX: TLabel;
     Label_GridX: TLabel;
     TimerHidePenPreview: TTimer;
     TimerHidePenPreview: TTimer;
     ToolBar13: TToolBar;
     ToolBar13: TToolBar;
-    Tool_CloseShape: TToolButton;
     ToolBar14: TToolBar;
     ToolBar14: TToolBar;
     ToolButton19: TToolButton;
     ToolButton19: TToolButton;
     ToolButton20: TToolButton;
     ToolButton20: TToolButton;
@@ -643,7 +647,19 @@ type
 
 
   private
   private
     function GetImage: TLazPaintImage;
     function GetImage: TLazPaintImage;
-    procedure OnTextureChanged(Sender: TObject);
+    procedure ManagerGradientChanged(Sender: TObject);
+    procedure ManagerJoinStyleChanged(Sender: TObject);
+    procedure ManagerLineCapChanged(Sender: TObject);
+    procedure ManagerOnPhongShapeChanged(Sender: TObject);
+    procedure ManagerPenStyleChanged(Sender: TObject);
+    procedure ManagerPenWidthChanged(Sender: TObject);
+    procedure ManagerSplineStyleChanged(Sender: TObject);
+    procedure ManagerTextFontChanged(Sender: TObject);
+    procedure ManagerTextOutlineChanged(Sender: TObject);
+    procedure ManagerTextPhongChanged(Sender: TObject);
+    procedure ManagerTextShadowChanged(Sender: TObject);
+    procedure ManagerTextureChanged(Sender: TObject);
+    procedure ManagerShapeOptionChanged(Sender: TObject);
   private
   private
     { private declarations }
     { private declarations }
     FLayout: TMainFormLayout;
     FLayout: TMainFormLayout;
@@ -692,6 +708,7 @@ type
     FImageView: TImageView;
     FImageView: TImageView;
     FUpdateStackWhenIdle: boolean;
     FUpdateStackWhenIdle: boolean;
     FToolbarElementsInitDone: boolean;
     FToolbarElementsInitDone: boolean;
+    FInSplineStyleChange: Boolean;
 
 
     function GetCurrentPressure: single;
     function GetCurrentPressure: single;
     function GetDarkTheme: boolean;
     function GetDarkTheme: boolean;
@@ -703,6 +720,18 @@ type
     procedure NoTextureIcon;
     procedure NoTextureIcon;
     procedure RegisterToolbarElements;
     procedure RegisterToolbarElements;
     procedure InitToolbarElements;
     procedure InitToolbarElements;
+    procedure UpdateToolOptions;
+    procedure UpdatePenStyleToolbar;
+    procedure UpdateJoinStyleToolbar;
+    procedure UpdateTextFontToolbar;
+    procedure UpdateTextOutlineToolbar;
+    procedure UpdateTextPhongToolbar;
+    procedure UpdateTextShadowToolbar;
+    procedure UpdateLineCapToolbar;
+    procedure UpdateSplineStyleToolbar;
+    procedure UpdateGradientToolbar;
+    procedure UpdatePenWidthToolbar;
+    procedure UpdatePhongToolbar;
     function ShowOpenBrushDialog: boolean;
     function ShowOpenBrushDialog: boolean;
     function TextSpinEditFocused: boolean;
     function TextSpinEditFocused: boolean;
     procedure UpdateBrush;
     procedure UpdateBrush;
@@ -710,12 +739,11 @@ type
     procedure CreateMenuAndToolbar;
     procedure CreateMenuAndToolbar;
     function GetToolManager: TToolManager;
     function GetToolManager: TToolManager;
     procedure LayoutPictureAreaChange({%H-}ASender: TObject; {%H-}ANewArea: TRect);
     procedure LayoutPictureAreaChange({%H-}ASender: TObject; {%H-}ANewArea: TRect);
-    procedure UpdatePanelTextWidth;
     function GetCurrentTool: TPaintToolType;
     function GetCurrentTool: TPaintToolType;
     procedure SwitchColors;
     procedure SwitchColors;
     procedure Init;
     procedure Init;
     procedure OnLatestVersionUpdate(ANewVersion: string);
     procedure OnLatestVersionUpdate(ANewVersion: string);
-    procedure OnToolChanged({%H-}sender: TToolManager; {%H-}ANewTool: TPaintToolType);
+    procedure ManagerToolChanged({%H-}sender: TToolManager; {%H-}ANewTool: TPaintToolType);
     procedure OnQueryExitToolHandler({%H-}sender: TLazPaintImage);
     procedure OnQueryExitToolHandler({%H-}sender: TLazPaintImage);
     procedure OnZoomChanged({%H-}sender: TZoom; {%H-}ANewZoom: single);
     procedure OnZoomChanged({%H-}sender: TZoom; {%H-}ANewZoom: single);
     procedure SetLazPaintInstance(const AValue: TLazPaintCustomInstance);
     procedure SetLazPaintInstance(const AValue: TLazPaintCustomInstance);
@@ -738,8 +766,7 @@ type
     procedure LabelAutosize(ALabel: TLabel);
     procedure LabelAutosize(ALabel: TLabel);
     procedure AskMergeSelection(ACaption: string);
     procedure AskMergeSelection(ACaption: string);
     procedure ReleaseMouseButtons(Shift: TShiftState);
     procedure ReleaseMouseButtons(Shift: TShiftState);
-    procedure UpdatePanelPhongShape;
-    procedure UpdateCurveMode;
+    procedure UpdateCurveModeToolbar;
     function ShowOpenTextureDialog: boolean;
     function ShowOpenTextureDialog: boolean;
     procedure ShowNoPicture;
     procedure ShowNoPicture;
     procedure SetCurveMode(AMode: TToolSplineMode);
     procedure SetCurveMode(AMode: TToolSplineMode);
@@ -783,6 +810,7 @@ type
       ASkipDialogIfSingleImage: boolean = false): Boolean;
       ASkipDialogIfSingleImage: boolean = false): Boolean;
     function PictureCanvasOfs: TPoint;
     function PictureCanvasOfs: TPoint;
     procedure UpdateLineCapBar;
     procedure UpdateLineCapBar;
+    procedure UpdateColorToolbar(AUpdateColorDiff: boolean);
     procedure UpdateToolbar;
     procedure UpdateToolbar;
     function ChooseTool(Tool : TPaintToolType): boolean;
     function ChooseTool(Tool : TPaintToolType): boolean;
     procedure PictureSelectedLayerIndexChanged({%H-}sender: TLazPaintImage);
     procedure PictureSelectedLayerIndexChanged({%H-}sender: TLazPaintImage);
@@ -883,8 +911,10 @@ begin
   m.PredefinedMainMenus([MenuFile,MenuEdit,MenuSelect,MenuView, MenuImage,MenuRemoveTransparency,
   m.PredefinedMainMenus([MenuFile,MenuEdit,MenuSelect,MenuView, MenuImage,MenuRemoveTransparency,
     MenuColors,MenuTool, MenuFilter,MenuRadialBlur, MenuRender,MenuHelp]);
     MenuColors,MenuTool, MenuFilter,MenuRadialBlur, MenuRender,MenuHelp]);
   m.Toolbars([Panel_Embedded,Panel_File,Panel_Zoom,Panel_Undo,Panel_CopyPaste,Panel_Coordinates,
   m.Toolbars([Panel_Embedded,Panel_File,Panel_Zoom,Panel_Undo,Panel_CopyPaste,Panel_Coordinates,
-    Panel_Tool,Panel_Color,Panel_Texture,Panel_Grid,Panel_PenWidth,Panel_Aliasing,Panel_ShapeOption,Panel_LineCap,Panel_JoinStyle,
-    Panel_PenStyle,Panel_SplineStyle,Panel_Eraser,Panel_Tolerance,Panel_GradientType,Panel_Text,Panel_TextOutline,
+    Panel_Tool,Panel_Color,Panel_Texture,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_PhongShape,Panel_Altitude,Panel_PerspectiveOption,Panel_Brush,Panel_Ratio],Panel_ToolbarBackground);
     Panel_PhongShape,Panel_Altitude,Panel_PerspectiveOption,Panel_Brush,Panel_Ratio],Panel_ToolbarBackground);
   m.ImageList := LazPaintInstance.Icons[ScaleY(16, 96)];
   m.ImageList := LazPaintInstance.Icons[ScaleY(16, 96)];
   m.Apply;
   m.Apply;
@@ -912,10 +942,20 @@ begin
 
 
   If Assigned(ToolManager) then
   If Assigned(ToolManager) then
   begin
   begin
-    if ToolManager.OnToolChanged = @OnToolChanged then
-      ToolManager.OnToolChanged := nil;
-    if ToolManager.OnTextureChanged = @OnTextureChanged then
-      ToolManager.OnTextureChanged := nil;
+    if ToolManager.OnToolChanged = @ManagerToolChanged then ToolManager.OnToolChanged := nil;
+    if ToolManager.OnTextureChanged = @ManagerTextureChanged then ToolManager.OnTextureChanged := nil;
+    if ToolManager.OnPenWidthChanged = @ManagerPenWidthChanged then ToolManager.OnPenWidthChanged := nil;
+    if ToolManager.OnPenStyleChanged = @ManagerPenStyleChanged then ToolManager.OnPenStyleChanged := nil;
+    if ToolManager.OnJoinStyleChanged = @ManagerJoinStyleChanged then ToolManager.OnJoinStyleChanged := nil;
+    if ToolManager.OnShapeOptionChanged = @ManagerShapeOptionChanged then ToolManager.OnShapeOptionChanged := nil;
+    if ToolManager.OnTextFontChanged = @ManagerTextFontChanged then ToolManager.OnTextFontChanged := nil;
+    if ToolManager.OnTextOutlineChanged = @ManagerTextOutlineChanged then ToolManager.OnTextOutlineChanged := nil;
+    if ToolManager.OnTextPhongChanged = @ManagerTextPhongChanged then ToolManager.OnTextPhongChanged := nil;
+    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 = @ManagerOnPhongShapeChanged then ToolManager.OnPhongShapeChanged := nil;
   end;
   end;
   FreeAndNil(Zoom);
   FreeAndNil(Zoom);
   FreeAndNil(FOnlineUpdater);
   FreeAndNil(FOnlineUpdater);
@@ -974,8 +1014,20 @@ begin
   RegisterToolbarElements;
   RegisterToolbarElements;
 
 
   ToolManager.SetCurrentToolType(ptHand);
   ToolManager.SetCurrentToolType(ptHand);
-  ToolManager.OnToolChanged := @OnToolChanged;
-  ToolManager.OnTextureChanged := @OnTextureChanged;
+  ToolManager.OnToolChanged  :=  @ManagerToolChanged;
+  ToolManager.OnTextureChanged := @ManagerTextureChanged;
+  ToolManager.OnPenWidthChanged:= @ManagerPenWidthChanged;
+  ToolManager.OnPenStyleChanged:= @ManagerPenStyleChanged;
+  ToolManager.OnJoinStyleChanged:= @ManagerJoinStyleChanged;
+  ToolManager.OnShapeOptionChanged:=@ManagerShapeOptionChanged;
+  ToolManager.OnTextFontChanged := @ManagerTextFontChanged;
+  ToolManager.OnTextOutlineChanged:=@ManagerTextOutlineChanged;
+  ToolManager.OnTextPhongChanged:=@ManagerTextPhongChanged;
+  ToolManager.OnTextShadowChanged:=@ManagerTextShadowChanged;
+  ToolManager.OnLineCapChanged := @ManagerLineCapChanged;
+  ToolManager.OnSplineStyleChanged:=@ManagerSplineStyleChanged;
+  ToolManager.OnGradientChanged:=@ManagerGradientChanged;
+  ToolManager.OnPhongShapeChanged:=@ManagerOnPhongShapeChanged;
 
 
   InitToolbarElements;
   InitToolbarElements;
 
 
@@ -1097,7 +1149,8 @@ begin
     else
     else
       exit;
       exit;
   end;
   end;
-  if (CurrentTool = ptText) and TextSpinEditFocused then SpinEdit_PenOpacity.SetFocus;
+  if (CurrentTool in[ptText,ptEditShape]) and TextSpinEditFocused then SpinEdit_PenOpacity.SetFocus;
+  Image.CurrentState.LayeredBitmap.EditorFocused := true;
 
 
   FormMouseMovePos := Point(X,Y);
   FormMouseMovePos := Point(X,Y);
   if InFormMouseMove then exit;
   if InFormMouseMove then exit;
@@ -1964,7 +2017,7 @@ begin
   try
   try
     if Zoom.EditingZoom then exit;
     if Zoom.EditingZoom then exit;
     toolProcessKey:= true;
     toolProcessKey:= true;
-    if (CurrentTool = ptText) and ((UTF8Key = #8) or ((length(UTF8Key)=1) and (UTF8Key[1] in['-','0'..'9']))) then
+    if (CurrentTool in[ptText,ptEditShape]) and ((UTF8Key = #8) or ((length(UTF8Key)=1) and (UTF8Key[1] in['-','0'..'9']))) then
     begin
     begin
       if TextSpinEditFocused then
       if TextSpinEditFocused then
          toolProcessKey:= false;
          toolProcessKey:= false;
@@ -2407,7 +2460,7 @@ end;
 procedure TFMain.ToolNoTextureExecute(Sender: TObject);
 procedure TFMain.ToolNoTextureExecute(Sender: TObject);
 begin
 begin
   try
   try
-    ToolManager.SetToolTexture(nil);
+    ToolManager.SetTexture(nil);
     UpdateEditPicture;
     UpdateEditPicture;
 
 
   except
   except
@@ -2418,7 +2471,7 @@ end;
 
 
 procedure TFMain.ToolNoTextureUpdate(Sender: TObject);
 procedure TFMain.ToolNoTextureUpdate(Sender: TObject);
 begin
 begin
-  ToolNoTexture.Enabled := ToolManager.GetToolTexture <> nil;
+  ToolNoTexture.Enabled := ToolManager.GetTexture <> nil;
 end;
 end;
 
 
 procedure TFMain.ViewColorsExecute(Sender: TObject);
 procedure TFMain.ViewColorsExecute(Sender: TObject);
@@ -2663,14 +2716,14 @@ begin
                     begin
                     begin
                       FImageActions.RemoveSelection;
                       FImageActions.RemoveSelection;
                       BGRAReplace(newTexture, newTexture.GetPart(newTexture.GetImageBounds));
                       BGRAReplace(newTexture, newTexture.GetPart(newTexture.GetImageBounds));
-                      ToolManager.SetToolTexture(newTexture);
+                      ToolManager.SetTexture(newTexture);
                       newTexture.FreeReference;
                       newTexture.FreeReference;
                     end;
                     end;
                   end;
                   end;
                 end;
                 end;
               end;
               end;
             end;
             end;
-            if (ToolManager.GetToolTexture = nil) or ToolManager.GetToolTexture.Empty then
+            if (ToolManager.GetTexture = nil) or ToolManager.GetTexture.Empty then
             begin
             begin
               if useSelection then
               if useSelection then
               begin
               begin
@@ -2683,7 +2736,7 @@ begin
                 result := srCancelledByUser;
                 result := srCancelledByUser;
               end
               end
               else
               else
-              if (ToolManager.GetToolTexture = nil) or ToolManager.GetToolTexture.Empty then
+              if (ToolManager.GetTexture = nil) or ToolManager.GetTexture.Empty then
               begin
               begin
                 Tool := ptHand;
                 Tool := ptHand;
                 result := srException;
                 result := srException;
@@ -2823,7 +2876,7 @@ end;
 
 
 procedure TFMain.BrushCreateGeometricUpdate(Sender: TObject);
 procedure TFMain.BrushCreateGeometricUpdate(Sender: TObject);
 begin
 begin
-  BrushCreateGeometric.Enabled := ToolManager.ToolBrushCount < 9;
+  BrushCreateGeometric.Enabled := ToolManager.BrushCount < 9;
 end;
 end;
 
 
 procedure TFMain.EditSelectionUpdate(Sender: TObject);
 procedure TFMain.EditSelectionUpdate(Sender: TObject);
@@ -3137,7 +3190,7 @@ begin
           newTex := LoadFlatImageUTF8(texFilename).bmp;
           newTex := LoadFlatImageUTF8(texFilename).bmp;
         if LazPaintInstance.BlackAndWhite then
         if LazPaintInstance.BlackAndWhite then
           newTex.InplaceGrayscale;
           newTex.InplaceGrayscale;
-        ToolManager.SetToolTexture(newTex);
+        ToolManager.SetTexture(newTex);
         newTex.FreeReference;
         newTex.FreeReference;
         newTex := nil;
         newTex := nil;
         result := true;
         result := true;
@@ -3256,16 +3309,17 @@ begin
   result := ToolManager.GetCurrentToolType;
   result := ToolManager.GetCurrentToolType;
 end;
 end;
 
 
-procedure TFMain.OnToolChanged(sender: TToolManager; ANewTool: TPaintToolType);
+procedure TFMain.ManagerToolChanged(sender: TToolManager; ANewTool: TPaintToolType);
 begin
 begin
   if self.Visible then
   if self.Visible then
   begin
   begin
-    UpdatePanelTextWidth;
     FLayout.Arrange;
     FLayout.Arrange;
     PaintBox_PenPreview.Invalidate;
     PaintBox_PenPreview.Invalidate;
     Image.OnImageChanged.NotifyObservers;
     Image.OnImageChanged.NotifyObservers;
     UpdateToolImage;
     UpdateToolImage;
     UpdateToolBar;
     UpdateToolBar;
+    UpdatePenWidthToolbar;
+    UpdateCurveModeToolbar;
   end;
   end;
 end;
 end;
 
 
@@ -3483,7 +3537,10 @@ begin
   if not image.CurrentLayerVisible and not ToolManager.ToolCanBeUsed then
   if not image.CurrentLayerVisible and not ToolManager.ToolCanBeUsed then
     ChooseTool(ptHand)
     ChooseTool(ptHand)
   else
   else
+  begin
     ToolManager.ToolOpen;
     ToolManager.ToolOpen;
+    ToolManager.UpdateContextualToolbars;
+  end;
 end;
 end;
 
 
 procedure TFMain.PictureSelectedLayerIndexChanging(sender: TLazPaintImage);
 procedure TFMain.PictureSelectedLayerIndexChanging(sender: TLazPaintImage);
@@ -3509,10 +3566,71 @@ begin
   result := LazPaintInstance.Image;
   result := LazPaintInstance.Image;
 end;
 end;
 
 
-procedure TFMain.OnTextureChanged(Sender: TObject);
+procedure TFMain.ManagerGradientChanged(Sender: TObject);
+begin
+  UpdateGradientToolbar;
+end;
+
+procedure TFMain.ManagerJoinStyleChanged(Sender: TObject);
+begin
+  UpdateJoinStyleToolbar;
+end;
+
+procedure TFMain.ManagerLineCapChanged(Sender: TObject);
+begin
+  UpdateLineCapToolbar;
+end;
+
+procedure TFMain.ManagerOnPhongShapeChanged(Sender: TObject);
+begin
+  UpdatePhongToolbar;
+end;
+
+procedure TFMain.ManagerPenStyleChanged(Sender: TObject);
+begin
+  UpdatePenStyleToolbar;
+end;
+
+procedure TFMain.ManagerPenWidthChanged(Sender: TObject);
+begin
+  UpdatePenWidthToolbar;
+end;
+
+procedure TFMain.ManagerSplineStyleChanged(Sender: TObject);
+begin
+  UpdateSplineStyleToolbar;
+end;
+
+procedure TFMain.ManagerTextFontChanged(Sender: TObject);
+begin
+  UpdateTextFontToolbar;
+end;
+
+procedure TFMain.ManagerTextOutlineChanged(Sender: TObject);
+begin
+  UpdateTextOutlineToolbar;
+end;
+
+procedure TFMain.ManagerTextPhongChanged(Sender: TObject);
+begin
+  UpdateTextPhongToolbar;
+end;
+
+procedure TFMain.ManagerTextShadowChanged(Sender: TObject);
+begin
+  UpdateTextShadowToolbar;
+end;
+
+procedure TFMain.ManagerTextureChanged(Sender: TObject);
 begin
 begin
   UpdateTextureIcon;
   UpdateTextureIcon;
-  SpinEdit_TextureOpacity.Value := ToolManager.ToolTextureOpacity;
+  SpinEdit_TextureOpacity.Value := ToolManager.TextureOpacity;
+end;
+
+procedure TFMain.ManagerShapeOptionChanged(Sender: TObject);
+begin
+  UpdateToolOptions;
+  FLayout.Arrange;
 end;
 end;
 
 
 procedure TFMain.UpdateStatusText;
 procedure TFMain.UpdateStatusText;

Plik diff jest za duży
+ 316 - 239
lazpaint/maintoolbar.inc


Plik diff jest za duży
+ 479 - 176
lazpaint/tools/utool.pas


+ 47 - 47
lazpaint/tools/utoolbasic.pas

@@ -94,7 +94,7 @@ end;
 
 
 function TToolErase.BlurRadius: single;
 function TToolErase.BlurRadius: single;
 begin
 begin
-  result := manager.ToolPenWidth/4*Manager.ToolEraserAlpha/255;
+  result := manager.PenWidth/4*Manager.ToolEraserAlpha/255;
 end;
 end;
 
 
 function TToolErase.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
 function TToolErase.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
@@ -105,22 +105,22 @@ var ix,iy: integer;
 begin
 begin
   if Manager.ToolEraserMode = emSoften then
   if Manager.ToolEraserMode = emSoften then
   begin
   begin
-    result := GetShapeBounds([ptF],Manager.ToolPenWidth+BlurRadius);
+    result := GetShapeBounds([ptF],Manager.PenWidth+BlurRadius);
     if IntersectRect(result, result, rect(0,0,toolDest.width,toolDest.height)) then
     if IntersectRect(result, result, rect(0,0,toolDest.width,toolDest.height)) then
     begin
     begin
       areaCopy := toolDest.GetPart(result) as TBGRABitmap;
       areaCopy := toolDest.GetPart(result) as TBGRABitmap;
       ApplySoften(areaCopy);
       ApplySoften(areaCopy);
       mask := TBGRABitmap.Create(result.Right-result.left,result.bottom-result.top, BGRABlack);
       mask := TBGRABitmap.Create(result.Right-result.left,result.bottom-result.top, BGRABlack);
       mask.LinearAntialiasing := true;
       mask.LinearAntialiasing := true;
-      if Manager.ToolOptionAliasing then
+      if Manager.ShapeOptionAliasing then
       begin
       begin
-        r := rect(round(ptF.X-result.left-Manager.ToolPenWidth/2+0.5),round(ptF.Y-result.top-Manager.ToolPenWidth/2+0.5),
-                  round(ptF.X-result.left+Manager.ToolPenWidth/2+0.5),round(ptF.Y-result.top+Manager.ToolPenWidth/2+0.5));
+        r := rect(round(ptF.X-result.left-Manager.PenWidth/2+0.5),round(ptF.Y-result.top-Manager.PenWidth/2+0.5),
+                  round(ptF.X-result.left+Manager.PenWidth/2+0.5),round(ptF.Y-result.top+Manager.PenWidth/2+0.5));
         mask.FillEllipseInRect(r,Manager.ApplyPressure(BGRAWhite));
         mask.FillEllipseInRect(r,Manager.ApplyPressure(BGRAWhite));
       end
       end
       else
       else
         mask.FillEllipseAntialias(ptF.X-result.left,ptF.Y-result.top,
         mask.FillEllipseAntialias(ptF.X-result.left,ptF.Y-result.top,
-          Manager.ToolPenWidth/2,Manager.ToolPenWidth/2,Manager.ApplyPressure(BGRAWhite));
+          Manager.PenWidth/2,Manager.PenWidth/2,Manager.ApplyPressure(BGRAWhite));
       mask.ScanOffset := Point(-result.left,-result.top);
       mask.ScanOffset := Point(-result.left,-result.top);
       areaCopy.ScanOffset := Point(-result.left,-result.top);
       areaCopy.ScanOffset := Point(-result.left,-result.top);
       toolDest.CrossFade(result,toolDest,areaCopy,mask,dmSet);
       toolDest.CrossFade(result,toolDest,areaCopy,mask,dmSet);
@@ -129,7 +129,7 @@ begin
     end;
     end;
   end else
   end else
   begin
   begin
-    if (snapToPixel or Manager.ToolOptionAliasing) and (Manager.ToolPenWidth = 1) then
+    if (snapToPixel or Manager.ShapeOptionAliasing) and (Manager.PenWidth = 1) then
     begin
     begin
       ix := round(ptF.X);
       ix := round(ptF.X);
       iy := round(ptF.Y);
       iy := round(ptF.Y);
@@ -138,15 +138,15 @@ begin
     end
     end
     else
     else
     begin
     begin
-      result := GetShapeBounds([ptF],Manager.ToolPenWidth);
+      result := GetShapeBounds([ptF],Manager.PenWidth);
       toolDest.ClipRect := result;
       toolDest.ClipRect := result;
-      if Manager.ToolOptionAliasing then
+      if Manager.ShapeOptionAliasing then
       begin
       begin
-        r := rect(round(ptF.X-Manager.ToolPenWidth/2+0.5),round(ptF.Y-Manager.ToolPenWidth/2+0.5),
-             round(ptF.X+Manager.ToolPenWidth/2+0.5),round(ptF.Y+Manager.ToolPenWidth/2+0.5));
+        r := rect(round(ptF.X-Manager.PenWidth/2+0.5),round(ptF.Y-Manager.PenWidth/2+0.5),
+             round(ptF.X+Manager.PenWidth/2+0.5),round(ptF.Y+Manager.PenWidth/2+0.5));
         toolDest.EraseEllipseInRect(r,round(Manager.ToolEraserAlpha*Manager.ToolPressure));
         toolDest.EraseEllipseInRect(r,round(Manager.ToolEraserAlpha*Manager.ToolPressure));
       end else
       end else
-        toolDest.EraseEllipseAntialias(ptF.X,ptF.Y,Manager.ToolPenWidth/2,Manager.ToolPenWidth/2,round(Manager.ToolEraserAlpha*Manager.ToolPressure));
+        toolDest.EraseEllipseAntialias(ptF.X,ptF.Y,Manager.PenWidth/2,Manager.PenWidth/2,round(Manager.ToolEraserAlpha*Manager.ToolPressure));
       toolDest.NoClip;
       toolDest.NoClip;
     end;
     end;
   end;
   end;
@@ -159,24 +159,24 @@ var areaCopy, mask: TBGRABitmap;
 begin
 begin
   if Manager.ToolEraserMode = emSoften then
   if Manager.ToolEraserMode = emSoften then
   begin
   begin
-    result := GetShapeBounds([destF,originF],Manager.ToolPenWidth+BlurRadius);
+    result := GetShapeBounds([destF,originF],Manager.PenWidth+BlurRadius);
     if IntersectRect(result, result, rect(0,0,toolDest.width,toolDest.height)) then
     if IntersectRect(result, result, rect(0,0,toolDest.width,toolDest.height)) then
     begin
     begin
       areaCopy := toolDest.GetPart(result) as TBGRABitmap;
       areaCopy := toolDest.GetPart(result) as TBGRABitmap;
       ApplySoften(areaCopy);
       ApplySoften(areaCopy);
       mask := TBGRABitmap.Create(result.Right-result.left,result.bottom-result.top, BGRABlack);
       mask := TBGRABitmap.Create(result.Right-result.left,result.bottom-result.top, BGRABlack);
       mask.LinearAntialiasing := true;
       mask.LinearAntialiasing := true;
-      if Manager.ToolOptionAliasing then
+      if Manager.ShapeOptionAliasing then
       begin
       begin
         pts := toolDest.Pen.ComputePolyline(
         pts := toolDest.Pen.ComputePolyline(
           [PointF(destF.X-result.left,destF.Y-result.top),
           [PointF(destF.X-result.left,destF.Y-result.top),
            PointF(originF.X-result.left,originF.Y-result.top)],
            PointF(originF.X-result.left,originF.Y-result.top)],
-           Manager.ToolPenWidth,BGRAPixelTransparent,False);
+           Manager.PenWidth,BGRAPixelTransparent,False);
         mask.FillPoly(pts,BGRAWhite);
         mask.FillPoly(pts,BGRAWhite);
       end else
       end else
         mask.DrawLineAntialias(destF.X-result.left,destF.Y-result.top,originF.X-result.left,originF.Y-result.top,
         mask.DrawLineAntialias(destF.X-result.left,destF.Y-result.top,originF.X-result.left,originF.Y-result.top,
           Manager.ApplyPressure(BGRAWhite),
           Manager.ApplyPressure(BGRAWhite),
-          Manager.ToolPenWidth,false);
+          Manager.PenWidth,false);
       mask.ScanOffset := Point(-result.left,-result.top);
       mask.ScanOffset := Point(-result.left,-result.top);
       areaCopy.ScanOffset := Point(-result.left,-result.top);
       areaCopy.ScanOffset := Point(-result.left,-result.top);
       toolDest.CrossFade(result,toolDest,areaCopy,mask,dmSet);
       toolDest.CrossFade(result,toolDest,areaCopy,mask,dmSet);
@@ -184,28 +184,28 @@ begin
       areaCopy.Free;
       areaCopy.Free;
     end;
     end;
   end else
   end else
-  if Manager.ToolOptionAliasing then
+  if Manager.ShapeOptionAliasing then
   begin
   begin
-    if Manager.ToolPenWidth = 1 then
+    if Manager.PenWidth = 1 then
     begin
     begin
       toolDest.EraseLine(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),round(Manager.ToolEraserAlpha*Manager.ToolPressure),false);
       toolDest.EraseLine(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),round(Manager.ToolEraserAlpha*Manager.ToolPressure),false);
       result := GetShapeBounds([destF,originF],1);
       result := GetShapeBounds([destF,originF],1);
     end else
     end else
     begin
     begin
-      pts := toolDest.Pen.ComputePolyline([PointF(destF.X,destF.Y),PointF(originF.X,originF.Y)],Manager.ToolPenWidth,BGRAPixelTransparent,False);
+      pts := toolDest.Pen.ComputePolyline([PointF(destF.X,destF.Y),PointF(originF.X,originF.Y)],Manager.PenWidth,BGRAPixelTransparent,False);
       toolDest.ErasePoly(pts, round(Manager.ToolEraserAlpha*Manager.ToolPressure));
       toolDest.ErasePoly(pts, round(Manager.ToolEraserAlpha*Manager.ToolPressure));
-      result := GetShapeBounds([destF,originF],Manager.ToolPenWidth);
+      result := GetShapeBounds([destF,originF],Manager.PenWidth);
     end;
     end;
   end else
   end else
   begin
   begin
-    if snapToPixel and (Manager.ToolPenWidth = 1) then
+    if snapToPixel and (Manager.PenWidth = 1) then
     begin
     begin
       toolDest.EraseLineAntialias(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),round(Manager.ToolEraserAlpha*Manager.ToolPressure),false);
       toolDest.EraseLineAntialias(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),round(Manager.ToolEraserAlpha*Manager.ToolPressure),false);
       result := GetShapeBounds([destF,originF],1);
       result := GetShapeBounds([destF,originF],1);
     end else
     end else
     begin
     begin
-      toolDest.EraseLineAntialias(destF.X,destF.Y,originF.X,originF.Y,round(Manager.ToolEraserAlpha*Manager.ToolPressure),Manager.ToolPenWidth,False);
-      result := GetShapeBounds([destF,originF],Manager.ToolPenWidth);
+      toolDest.EraseLineAntialias(destF.X,destF.Y,originF.X,originF.Y,round(Manager.ToolEraserAlpha*Manager.ToolPressure),Manager.PenWidth,False);
+      result := GetShapeBounds([destF,originF],Manager.PenWidth);
     end;
     end;
   end;
   end;
 end;
 end;
@@ -227,8 +227,8 @@ function TToolPen.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
 var ix,iy: integer;
 var ix,iy: integer;
   r: TRect;
   r: TRect;
 begin
 begin
-  if rightBtn then penColor := Manager.ToolBackColor else penColor := Manager.ToolForeColor;
-  if (snapToPixel or Manager.ToolOptionAliasing) and (Manager.ToolPenWidth = 1) and (Manager.GetToolTexture = nil) then
+  if rightBtn then penColor := Manager.BackColor else penColor := Manager.ForeColor;
+  if (snapToPixel or Manager.ShapeOptionAliasing) and (Manager.PenWidth = 1) and (Manager.GetTexture = nil) then
   begin
   begin
     ix := round(ptF.X);
     ix := round(ptF.X);
     iy := round(ptF.Y);
     iy := round(ptF.Y);
@@ -236,23 +236,23 @@ begin
     result := rect(ix,iy,ix+1,iy+1);
     result := rect(ix,iy,ix+1,iy+1);
   end else
   end else
   begin
   begin
-    result := GetShapeBounds([ptF],Manager.ToolPenWidth);
+    result := GetShapeBounds([ptF],Manager.PenWidth);
     toolDest.ClipRect := result;
     toolDest.ClipRect := result;
-    if Manager.ToolOptionAliasing then
+    if Manager.ShapeOptionAliasing then
     begin
     begin
-      r := rect(round(ptF.X-Manager.ToolPenWidth/2+0.5),round(ptF.Y-Manager.ToolPenWidth/2+0.5),
-                round(ptF.X+Manager.ToolPenWidth/2+0.5),round(ptF.Y+Manager.ToolPenWidth/2+0.5));
-      if Manager.GetToolTextureAfterAlpha <> nil then
-        toolDest.FillEllipseInRect(r,Manager.GetToolTextureAfterAlpha,dmDrawWithTransparency)
+      r := rect(round(ptF.X-Manager.PenWidth/2+0.5),round(ptF.Y-Manager.PenWidth/2+0.5),
+                round(ptF.X+Manager.PenWidth/2+0.5),round(ptF.Y+Manager.PenWidth/2+0.5));
+      if Manager.GetTextureAfterAlpha <> nil then
+        toolDest.FillEllipseInRect(r,Manager.GetTextureAfterAlpha,dmDrawWithTransparency)
       else
       else
         toolDest.FillEllipseInRect(r,Manager.ApplyPressure(penColor),dmDrawWithTransparency);
         toolDest.FillEllipseInRect(r,Manager.ApplyPressure(penColor),dmDrawWithTransparency);
     end
     end
     else
     else
     begin
     begin
-      if Manager.GetToolTextureAfterAlpha <> nil then
-        toolDest.FillEllipseAntialias(ptF.X,ptF.Y,Manager.ToolPenWidth/2,Manager.ToolPenWidth/2,Manager.GetToolTextureAfterAlpha)
+      if Manager.GetTextureAfterAlpha <> nil then
+        toolDest.FillEllipseAntialias(ptF.X,ptF.Y,Manager.PenWidth/2,Manager.PenWidth/2,Manager.GetTextureAfterAlpha)
       else
       else
-        toolDest.FillEllipseAntialias(ptF.X,ptF.Y,Manager.ToolPenWidth/2,Manager.ToolPenWidth/2,Manager.ApplyPressure(penColor));
+        toolDest.FillEllipseAntialias(ptF.X,ptF.Y,Manager.PenWidth/2,Manager.PenWidth/2,Manager.ApplyPressure(penColor));
     end;
     end;
     toolDest.NoClip;
     toolDest.NoClip;
   end;
   end;
@@ -262,30 +262,30 @@ function TToolPen.ContinueDrawing(toolDest: TBGRABitmap; originF, destF: TPointF
 var
 var
   pts: ArrayOfTPointF;
   pts: ArrayOfTPointF;
 begin
 begin
-  if (snapToPixel or Manager.ToolOptionAliasing) and (Manager.ToolPenWidth = 1) and (Manager.GetToolTexture = nil) then
+  if (snapToPixel or Manager.ShapeOptionAliasing) and (Manager.PenWidth = 1) and (Manager.GetTexture = nil) then
   begin
   begin
-    if Manager.ToolOptionAliasing then
+    if Manager.ShapeOptionAliasing then
       toolDest.DrawLine(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),Manager.ApplyPressure(penColor),false)
       toolDest.DrawLine(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),Manager.ApplyPressure(penColor),false)
     else
     else
       toolDest.DrawLineAntialias(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),Manager.ApplyPressure(penColor),false);
       toolDest.DrawLineAntialias(round(destF.X),round(destF.Y),round(originF.X),round(originF.Y),Manager.ApplyPressure(penColor),false);
     result := GetShapeBounds([destF,originF],1);
     result := GetShapeBounds([destF,originF],1);
   end else
   end else
   begin
   begin
-    result := GetShapeBounds([destF,originF],Manager.ToolPenWidth+1);
+    result := GetShapeBounds([destF,originF],Manager.PenWidth+1);
     toolDest.ClipRect := result;
     toolDest.ClipRect := result;
-    if Manager.ToolOptionAliasing then
+    if Manager.ShapeOptionAliasing then
     begin
     begin
-      pts := toolDest.Pen.ComputePolyline([PointF(destF.X,destF.Y),PointF(originF.X,originF.Y)],Manager.ToolPenWidth,BGRAPixelTransparent,False);
-      if Manager.GetToolTextureAfterAlpha <> nil then
-        toolDest.FillPoly(pts,Manager.GetToolTextureAfterAlpha,dmDrawWithTransparency)
+      pts := toolDest.Pen.ComputePolyline([PointF(destF.X,destF.Y),PointF(originF.X,originF.Y)],Manager.PenWidth,BGRAPixelTransparent,False);
+      if Manager.GetTextureAfterAlpha <> nil then
+        toolDest.FillPoly(pts,Manager.GetTextureAfterAlpha,dmDrawWithTransparency)
       else
       else
         toolDest.FillPoly(pts,Manager.ApplyPressure(penColor),dmDrawWithTransparency);
         toolDest.FillPoly(pts,Manager.ApplyPressure(penColor),dmDrawWithTransparency);
     end else
     end else
     begin
     begin
-      if Manager.GetToolTextureAfterAlpha <> nil then
-        toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,Manager.GetToolTextureAfterAlpha,Manager.ToolPenWidth,False)
+      if Manager.GetTextureAfterAlpha <> nil then
+        toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,Manager.GetTextureAfterAlpha,Manager.PenWidth,False)
       else
       else
-        toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,Manager.ApplyPressure(penColor),Manager.ToolPenWidth,False);
+        toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,Manager.ApplyPressure(penColor),Manager.PenWidth,False);
     end;
     end;
     toolDest.NoClip;
     toolDest.NoClip;
   end;
   end;
@@ -308,7 +308,7 @@ end;
 function TToolPen.DoToolMove(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF
 function TToolPen.DoToolMove(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF
   ): TRect;
   ): TRect;
 begin
 begin
-  if (manager.ToolPenWidth <= 3) and not HintShowed then
+  if (manager.PenWidth <= 3) and not HintShowed then
   begin
   begin
     Manager.ToolPopup(tpmHoldCtrlSnapToPixel);
     Manager.ToolPopup(tpmHoldCtrlSnapToPixel);
     HintShowed:= true;
     HintShowed:= true;
@@ -391,8 +391,8 @@ begin
   begin
   begin
     if (pt.X >= 0) and (pt.Y >= 0) and (pt.X < toolDest.Width) and (pt.Y < toolDest.Height) then
     if (pt.X >= 0) and (pt.Y >= 0) and (pt.X < toolDest.Width) and (pt.Y < toolDest.Height) then
     begin
     begin
-      if colorpickingRight then Manager.ToolBackColor := toolDest.GetPixel(pt.X,pt.Y) else
-        Manager.ToolForeColor := toolDest.GetPixel(pt.X,pt.Y);
+      if colorpickingRight then Manager.BackColor := toolDest.GetPixel(pt.X,pt.Y) else
+        Manager.ForeColor := toolDest.GetPixel(pt.X,pt.Y);
     end;
     end;
   end;
   end;
 end;
 end;

+ 3 - 3
lazpaint/tools/utoolbrush.pas

@@ -223,14 +223,14 @@ end;
 
 
 function TToolGenericBrush.GetBrushInfo: TLazPaintBrush;
 function TToolGenericBrush.GetBrushInfo: TLazPaintBrush;
 begin
 begin
-  result := manager.ToolBrushInfo;
+  result := manager.BrushInfo;
   if result = nil then
   if result = nil then
   begin
   begin
     if defaultBrush = nil then
     if defaultBrush = nil then
       defaultBrush := TLazPaintBrush.Create;
       defaultBrush := TLazPaintBrush.Create;
     result := defaultBrush;
     result := defaultBrush;
   end;
   end;
-  result.Size := manager.ToolPenWidth;
+  result.Size := manager.PenWidth;
 end;
 end;
 
 
 function TToolGenericBrush.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
 function TToolGenericBrush.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
@@ -239,7 +239,7 @@ begin
   if not SubPixelAccuracy then
   if not SubPixelAccuracy then
     brushOrigin:= PointF(round(ptF.x),round(ptF.y))
     brushOrigin:= PointF(round(ptF.x),round(ptF.y))
   else brushOrigin := ptF;
   else brushOrigin := ptF;
-  if rightBtn then penColor := Manager.ToolBackColor else penColor := Manager.ToolForeColor;
+  if rightBtn then penColor := Manager.BackColor else penColor := Manager.ForeColor;
   originDrawn := false;
   originDrawn := false;
   PrepareBrush(rightBtn);
   PrepareBrush(rightBtn);
   result := ContinueDrawing(toolDest,brushOrigin,brushOrigin);
   result := ContinueDrawing(toolDest,brushOrigin,brushOrigin);

+ 19 - 19
lazpaint/tools/utooldeformationgrid.pas

@@ -488,7 +488,7 @@ end;
 
 
 function TToolTextureMapping.GetTexture: TBGRABitmap;
 function TToolTextureMapping.GetTexture: TBGRABitmap;
 begin
 begin
-  result := Manager.GetToolTextureAfterAlpha;
+  result := Manager.GetTextureAfterAlpha;
 end;
 end;
 
 
 procedure TToolTextureMapping.OnTryStop(sender: TCustomLayerAction);
 procedure TToolTextureMapping.OnTryStop(sender: TCustomLayerAction);
@@ -738,13 +738,13 @@ begin
       result := false;
       result := false;
       exit;
       exit;
     end;
     end;
-    setlength(DeformationGrid,Manager.ToolDeformationGridNbY,Manager.ToolDeformationGridNbX);
-    setlength(DeformationGridTexCoord,Manager.ToolDeformationGridNbY,Manager.ToolDeformationGridNbX);
-    for yb := 0 to Manager.ToolDeformationGridNbY-1 do
-      for xb := 0 to Manager.ToolDeformationGridNbX-1 do
+    setlength(DeformationGrid,Manager.DeformationGridNbY,Manager.DeformationGridNbX);
+    setlength(DeformationGridTexCoord,Manager.DeformationGridNbY,Manager.DeformationGridNbX);
+    for yb := 0 to Manager.DeformationGridNbY-1 do
+      for xb := 0 to Manager.DeformationGridNbX-1 do
       begin
       begin
-        DeformationGridTexCoord[yb,xb] := PointF(xb/(Manager.ToolDeformationGridNbX-1)*layer.Width-0.5,
-                                                     yb/(Manager.ToolDeformationGridNbY-1)*layer.Height-0.5);
+        DeformationGridTexCoord[yb,xb] := PointF(xb/(Manager.DeformationGridNbX-1)*layer.Width-0.5,
+                                                     yb/(Manager.DeformationGridNbY-1)*layer.Height-0.5);
         DeformationGrid[yb,xb] :=DeformationGridTexCoord[yb,xb];
         DeformationGrid[yb,xb] :=DeformationGridTexCoord[yb,xb];
       end;
       end;
   end;
   end;
@@ -779,8 +779,8 @@ begin
   begin
   begin
     ValidateAction;
     ValidateAction;
     DoingDeformation := false;
     DoingDeformation := false;
-    for yb := 0 to Manager.ToolDeformationGridNbY-2 do
-      for xb := 0 to Manager.ToolDeformationGridNbX-2 do
+    for yb := 0 to Manager.DeformationGridNbY-2 do
+      for xb := 0 to Manager.DeformationGridNbX-2 do
         DeformationGridTexCoord[yb,xb] := DeformationGrid[yb,xb];
         DeformationGridTexCoord[yb,xb] := DeformationGrid[yb,xb];
   end;
   end;
 end;
 end;
@@ -808,8 +808,8 @@ begin
   deformationGridY := 1;
   deformationGridY := 1;
   if DeformationGrid <> nil then
   if DeformationGrid <> nil then
   begin
   begin
-    for yb := 1 to Manager.ToolDeformationGridNbY-2 do
-      for xb := 1 to Manager.ToolDeformationGridNbX-2 do
+    for yb := 1 to Manager.DeformationGridNbY-2 do
+      for xb := 1 to Manager.DeformationGridNbX-2 do
       begin
       begin
         curDist := sqr(ptF.x-DeformationGrid[yb,xb].x)+sqr(ptF.y-DeformationGrid[yb,xb].y);
         curDist := sqr(ptF.x-DeformationGrid[yb,xb].x)+sqr(ptF.y-DeformationGrid[yb,xb].y);
         if curDist < minDist then
         if curDist < minDist then
@@ -871,8 +871,8 @@ begin
 
 
     layer := GetToolDrawingLayer;
     layer := GetToolDrawingLayer;
     backupLayer := GetBackupLayerIfExists;
     backupLayer := GetBackupLayerIfExists;
-    NbX := Manager.ToolDeformationGridNbX;
-    NbY := Manager.ToolDeformationGridNbY;
+    NbX := Manager.DeformationGridNbX;
+    NbY := Manager.DeformationGridNbY;
 
 
     DeformationGrid[deformationGridY,deformationGridX] := PointF(
     DeformationGrid[deformationGridY,deformationGridX] := PointF(
       DeformationGrid[deformationGridY,deformationGridX].X + ptF.X-deformationOrigin.X,
       DeformationGrid[deformationGridY,deformationGridX].X + ptF.X-deformationOrigin.X,
@@ -964,14 +964,14 @@ var curPt,rightPt,downPt: TPointF;
 begin
 begin
   result := EmptyRect;
   result := EmptyRect;
   if not ToolDeformationGridNeeded then exit;
   if not ToolDeformationGridNeeded then exit;
-  for xb := 0 to Manager.ToolDeformationGridNbX-1 do
-    for yb := 0 to Manager.ToolDeformationGridNbY-1 do
+  for xb := 0 to Manager.DeformationGridNbX-1 do
+    for yb := 0 to Manager.DeformationGridNbY-1 do
     begin
     begin
       curPt := BitmapToVirtualScreen(DeformationGrid[yb,xb]);
       curPt := BitmapToVirtualScreen(DeformationGrid[yb,xb]);
       if not deformationGridMoving or ((xb+1 >= deformationGridX) and (xb <= deformationGridX) and
       if not deformationGridMoving or ((xb+1 >= deformationGridX) and (xb <= deformationGridX) and
         (yb >= deformationGridY-1) and (yb <= deformationGridY+1)) then
         (yb >= deformationGridY-1) and (yb <= deformationGridY+1)) then
       begin
       begin
-        if (xb < Manager.ToolDeformationGridNbX-1) and (yb > 0) and (yb < Manager.ToolDeformationGridNbY-1) then
+        if (xb < Manager.DeformationGridNbX-1) and (yb > 0) and (yb < Manager.DeformationGridNbY-1) then
         begin
         begin
           rightPt := BitmapToVirtualScreen(DeformationGrid[yb,xb+1]);
           rightPt := BitmapToVirtualScreen(DeformationGrid[yb,xb+1]);
           if Assigned(VirtualScreen) then NiceLine(VirtualScreen, curPt.X,curPt.Y, rightPt.X,rightPt.Y);
           if Assigned(VirtualScreen) then NiceLine(VirtualScreen, curPt.X,curPt.Y, rightPt.X,rightPt.Y);
@@ -984,7 +984,7 @@ begin
       if not deformationGridMoving or ((xb >= deformationGridX-1) and (xb <= deformationGridX+1) and
       if not deformationGridMoving or ((xb >= deformationGridX-1) and (xb <= deformationGridX+1) and
         (yb+1 >= deformationGridY) and (yb <= deformationGridY)) then
         (yb+1 >= deformationGridY) and (yb <= deformationGridY)) then
       begin
       begin
-        if (yb < Manager.ToolDeformationGridNbY-1) and (xb > 0) and (xb < Manager.ToolDeformationGridNbX-1) then
+        if (yb < Manager.DeformationGridNbY-1) and (xb > 0) and (xb < Manager.DeformationGridNbX-1) then
         begin
         begin
           downPt := BitmapToVirtualScreen(DeformationGrid[yb+1,xb]);
           downPt := BitmapToVirtualScreen(DeformationGrid[yb+1,xb]);
           if Assigned(virtualScreen) then NiceLine(VirtualScreen, curPt.X,curPt.Y, downPt.X,downPt.Y);
           if Assigned(virtualScreen) then NiceLine(VirtualScreen, curPt.X,curPt.Y, downPt.X,downPt.Y);
@@ -995,8 +995,8 @@ begin
         end;
         end;
       end;
       end;
     end;
     end;
-  for xb := 1 to Manager.ToolDeformationGridNbX-2 do
-    for yb := 1 to Manager.ToolDeformationGridNbY-2 do
+  for xb := 1 to Manager.DeformationGridNbX-2 do
+    for yb := 1 to Manager.DeformationGridNbY-2 do
     begin
     begin
       if not deformationGridMoving or ((xb >= deformationGridX-1) and (xb <= deformationGridX+1) and
       if not deformationGridMoving or ((xb >= deformationGridX-1) and (xb <= deformationGridX+1) and
         (yb >= deformationGridY-1) and (yb <= deformationGridY+1)) then
         (yb >= deformationGridY-1) and (yb <= deformationGridY+1)) then

+ 8 - 16
lazpaint/tools/utoolfloodfill.pas

@@ -73,19 +73,11 @@ procedure TToolGradient.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
 begin
   with FShape.BackFill.Gradient do
   with FShape.BackFill.Gradient do
   begin
   begin
-    StartColor := Manager.ToolForeColor;
-    EndColor := Manager.ToolBackColor;
-    GradientType := Manager.ToolGradientType;
-    case Manager.ToolGradientColorspace of
-     gcsLinearRgb: ColorInterpolation := ciStdRGB;
-     gcsHueCW: ColorInterpolation := ciLinearHSLPositive;
-     gcsHueCCW: ColorInterpolation := ciLinearHSLNegative;
-     gcsCorrectedHueCW: ColorInterpolation := ciGSBPositive;
-     gcsCorrectedHueCCW: ColorInterpolation := ciGSBPositive;
-    else
-      ColorInterpolation := ciLinearRGB;
-    end;
-    if Manager.ToolGradientSine then
+    StartColor := Manager.ForeColor;
+    EndColor := Manager.BackColor;
+    GradientType := Manager.GradientType;
+    ColorInterpolation := Manager.GradientColorspace;
+    if Manager.GradientSine then
       Repetition := grSine
       Repetition := grSine
     else
     else
       Repetition := grPad;
       Repetition := grPad;
@@ -134,11 +126,11 @@ function TToolFloodFill.DoToolDown(toolDest: TBGRABitmap; pt: TPoint;
 var
 var
    floodFillMask,floodFillTex: TBGRABitmap;
    floodFillMask,floodFillTex: TBGRABitmap;
 begin
 begin
-  if rightBtn then penColor := Manager.ToolBackColor else penColor := Manager.ToolForeColor;
-  if Manager.GetToolTextureAfterAlpha <> nil then
+  if rightBtn then penColor := Manager.BackColor else penColor := Manager.ForeColor;
+  if Manager.GetTextureAfterAlpha <> nil then
   begin
   begin
     floodFillMask := TBGRABitmap.Create(toolDest.Width,toolDest.Height,BGRABlack);
     floodFillMask := TBGRABitmap.Create(toolDest.Width,toolDest.Height,BGRABlack);
-    floodFillTex := Manager.GetToolTextureAfterAlpha.GetPart(rect(0,0,toolDest.Width,toolDest.Height)) as TBGRABitmap;
+    floodFillTex := Manager.GetTextureAfterAlpha.GetPart(rect(0,0,toolDest.Width,toolDest.Height)) as TBGRABitmap;
     toolDest.ParallelFloodFill(pt.X,pt.Y,floodFillMask,BGRAWhite,fmSet,Manager.ToolTolerance);
     toolDest.ParallelFloodFill(pt.X,pt.Y,floodFillMask,BGRAWhite,fmSet,Manager.ToolTolerance);
     floodFillTex.ApplyMask(floodFillMask);
     floodFillTex.ApplyMask(floodFillMask);
     toolDest.PutImage(0,0,floodFillTex,dmDrawWithTransparency);
     toolDest.PutImage(0,0,floodFillTex,dmDrawWithTransparency);

+ 5 - 11
lazpaint/tools/utoolphong.pas

@@ -45,7 +45,7 @@ var
   posF: TPointF;
   posF: TPointF;
 begin
 begin
   posF := AffineMatrixInverse(FMatrix)*(FShape as TPhongShape).LightPosition;
   posF := AffineMatrixInverse(FMatrix)*(FShape as TPhongShape).LightPosition;
-  Manager.ToolLightPosition := posF;
+  Manager.LightPosition := posF;
   inherited ShapeChange(ASender, ABounds, ADiff);
   inherited ShapeChange(ASender, ABounds, ADiff);
 end;
 end;
 
 
@@ -55,16 +55,10 @@ begin
   FMatrix := AMatrix;
   FMatrix := AMatrix;
   with (FShape as TPhongShape) do
   with (FShape as TPhongShape) do
   begin
   begin
-    if Manager.ToolShapeType = 'RoundRectangle' then ShapeKind:= pskRoundRectangle else
-    if Manager.ToolShapeType = 'Sphere' then ShapeKind := pskHalfSphere else
-    if Manager.ToolShapeType = 'Cone' then ShapeKind := pskConeTop else
-    if Manager.ToolShapeType = 'VerticalCone' then ShapeKind := pskConeSide else
-    if Manager.ToolShapeType = 'VerticalCylinder' then ShapeKind := pskVertCylinder else
-    if Manager.ToolShapeType = 'HorizontalCylinder' then ShapeKind := pskHorizCylinder
-    else ShapeKind := pskRectangle;
-    LightPosition := AMatrix*Manager.ToolLightPosition;
-    ShapeAltitudePercent := Manager.ToolShapeAltitude;
-    BorderSizePercent:= Manager.ToolShapeBorderSize;
+    ShapeKind := Manager.PhongShapeKind;
+    LightPosition := AMatrix*Manager.LightPosition;
+    ShapeAltitudePercent := Manager.PhongShapeAltitude;
+    BorderSizePercent:= Manager.PhongShapeBorderSize;
   end;
   end;
 end;
 end;
 
 

+ 11 - 31
lazpaint/tools/utoolpolygon.pas

@@ -12,8 +12,6 @@ const
   EasyBezierMinimumDotProduct = 0.5;
   EasyBezierMinimumDotProduct = 0.5;
 
 
 type
 type
-  TToolSplineMode = (tsmMovePoint, tsmCurveModeAuto, tsmCurveModeAngle, tsmCurveModeSpline);
-
   { TToolRectangle }
   { TToolRectangle }
 
 
   TToolRectangle = class(TVectorialTool)
   TToolRectangle = class(TVectorialTool)
@@ -76,7 +74,7 @@ end;
 
 
 function TToolEllipse.GetContextualToolbars: TContextualToolbars;
 function TToolEllipse.GetContextualToolbars: TContextualToolbars;
 begin
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle];
 end;
 end;
 
 
 { TToolRectangle }
 { TToolRectangle }
@@ -88,34 +86,15 @@ end;
 
 
 function TToolRectangle.GetContextualToolbars: TContextualToolbars;
 function TToolRectangle.GetContextualToolbars: TContextualToolbars;
 begin
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctJoinStyle];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle];
 end;
 end;
 
 
 { TToolSpline }
 { TToolSpline }
 
 
 function TToolSpline.GetCurrentMode: TToolSplineMode;
 function TToolSpline.GetCurrentMode: TToolSplineMode;
-var
-  c: TCurveShape;
 begin
 begin
   if Assigned(FShape) then
   if Assigned(FShape) then
-  begin
-    c := TCurveShape(FShape);
-    case c.Usermode of
-    vsuEdit: FCurrentMode := tsmMovePoint;
-    vsuCreate: if c.PointCount > 1 then
-               begin
-                 case c.CurveMode[c.PointCount-2] of
-                   cmAuto: FCurrentMode := tsmCurveModeAuto;
-                   cmAngle: FCurrentMode := tsmCurveModeAngle;
-                   cmCurve: FCurrentMode := tsmCurveModeSpline;
-                 end;
-               end else
-                 result := tsmCurveModeAuto;
-    vsuCurveSetAuto: FCurrentMode := tsmCurveModeAuto;
-    vsuCurveSetAngle: FCurrentMode := tsmCurveModeAngle;
-    vsuCurveSetCurve: FCurrentMode := tsmCurveModeSpline;
-    end;
-  end;
+    FCurrentMode := ToolSplineModeFromShape(FShape);
   result := FCurrentMode;
   result := FCurrentMode;
 end;
 end;
 
 
@@ -163,7 +142,7 @@ end;
 procedure TToolSpline.AssignShapeStyle(AMatrix: TAffineMatrix);
 procedure TToolSpline.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
 begin
   inherited AssignShapeStyle(AMatrix);
   inherited AssignShapeStyle(AMatrix);
-  TCurveShape(FShape).SplineStyle:= Manager.ToolSplineStyle;
+  TCurveShape(FShape).SplineStyle:= Manager.SplineStyle;
 end;
 end;
 
 
 constructor TToolSpline.Create(AManager: TToolManager);
 constructor TToolSpline.Create(AManager: TToolManager);
@@ -180,7 +159,7 @@ end;
 
 
 function TToolSpline.GetContextualToolbars: TContextualToolbars;
 function TToolSpline.GetContextualToolbars: TContextualToolbars;
 begin
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctLineCap];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctLineCap,ctSplineStyle];
 end;
 end;
 
 
 { TToolPolygon }
 { TToolPolygon }
@@ -193,10 +172,11 @@ end;
 procedure TToolPolygon.AssignShapeStyle(AMatrix: TAffineMatrix);
 procedure TToolPolygon.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
 begin
   inherited AssignShapeStyle(AMatrix);
   inherited AssignShapeStyle(AMatrix);
-  TCustomPolypointShape(FShape).Closed := Manager.ToolOptionCloseShape;
-  TCustomPolypointShape(FShape).ArrowStartKind := StrToArrowKind(Manager.ToolArrowStart);
-  TCustomPolypointShape(FShape).ArrowEndKind := StrToArrowKind(Manager.ToolArrowEnd);
-  TCustomPolypointShape(FShape).ArrowSize := Manager.ToolArrowSize;
+  TCustomPolypointShape(FShape).Closed := toCloseShape in Manager.ShapeOptions;
+  TCustomPolypointShape(FShape).ArrowStartKind := Manager.ArrowStart;
+  TCustomPolypointShape(FShape).ArrowEndKind := Manager.ArrowEnd;
+  TCustomPolypointShape(FShape).ArrowSize := Manager.ArrowSize;
+  if not (self is TToolSpline) then TCustomPolypointShape(FShape).LineCap:= Manager.LineCap;
   UpdateUserMode;
   UpdateUserMode;
 end;
 end;
 
 
@@ -208,7 +188,7 @@ end;
 
 
 function TToolPolygon.GetContextualToolbars: TContextualToolbars;
 function TToolPolygon.GetContextualToolbars: TContextualToolbars;
 begin
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctJoinStyle,ctLineCap];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap];
 end;
 end;
 
 
 initialization
 initialization

+ 4 - 4
lazpaint/tools/utoolselect.pas

@@ -550,15 +550,15 @@ function TToolSelectionPen.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
   rightBtn: boolean): TRect;
   rightBtn: boolean): TRect;
 begin
 begin
   if rightBtn then penColor := BGRABlack else penColor := BGRAWhite;
   if rightBtn then penColor := BGRABlack else penColor := BGRAWhite;
-  toolDest.DrawLineAntialias(ptF.X,ptF.Y,ptF.X,ptF.Y,penColor,Manager.ToolPenWidth,True);
-  result := GetShapeBounds([ptF],Manager.ToolPenWidth+1);
+  toolDest.DrawLineAntialias(ptF.X,ptF.Y,ptF.X,ptF.Y,penColor,Manager.PenWidth,True);
+  result := GetShapeBounds([ptF],Manager.PenWidth+1);
 end;
 end;
 
 
 function TToolSelectionPen.ContinueDrawing(toolDest: TBGRABitmap; originF,
 function TToolSelectionPen.ContinueDrawing(toolDest: TBGRABitmap; originF,
   destF: TPointF): TRect;
   destF: TPointF): TRect;
 begin
 begin
-  toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,penColor,Manager.ToolPenWidth,False);
-  result := GetShapeBounds([destF,originF],Manager.ToolPenWidth+1);
+  toolDest.DrawLineAntialias(destF.X,destF.Y,originF.X,originF.Y,penColor,Manager.PenWidth,False);
+  result := GetShapeBounds([destF,originF],Manager.PenWidth+1);
 end;
 end;
 
 
 function TToolSelectionPen.GetContextualToolbars: TContextualToolbars;
 function TToolSelectionPen.GetContextualToolbars: TContextualToolbars;

+ 34 - 34
lazpaint/tools/utooltext.pas

@@ -55,18 +55,18 @@ end;
 
 
 function TToolText.AlwaysRasterizeShape: boolean;
 function TToolText.AlwaysRasterizeShape: boolean;
 begin
 begin
-  Result:= Manager.ToolTextShadow;
+  Result:= Manager.TextShadow;
 end;
 end;
 
 
 procedure TToolText.IncludeShadowBounds(var ARect: TRect);
 procedure TToolText.IncludeShadowBounds(var ARect: TRect);
 var
 var
   shadowRect: TRect;
   shadowRect: TRect;
 begin
 begin
-  if Manager.ToolTextShadow then
+  if Manager.TextShadow then
   begin
   begin
     shadowRect := ARect;
     shadowRect := ARect;
-    shadowRect.Inflate(ceil(Manager.ToolTextBlur),ceil(Manager.ToolTextBlur));
-    shadowRect.Offset(Manager.ToolTextShadowOffset.X,Manager.ToolTextShadowOffset.Y);
+    shadowRect.Inflate(ceil(Manager.TextShadowBlurRadius),ceil(Manager.TextShadowBlurRadius));
+    shadowRect.Offset(Manager.TextShadowOffset.X,Manager.TextShadowOffset.Y);
     ARect := RectUnion(ARect, shadowRect);
     ARect := RectUnion(ARect, shadowRect);
   end;
   end;
 end;
 end;
@@ -84,7 +84,7 @@ var
   blur, gray, grayShape: TGrayscaleMask;
   blur, gray, grayShape: TGrayscaleMask;
   shapeBounds, blurBounds, r, actualShapeBounds: TRect;
   shapeBounds, blurBounds, r, actualShapeBounds: TRect;
 begin
 begin
-  if Manager.ToolTextShadow then
+  if Manager.TextShadow then
   begin
   begin
     shapeBounds := GetCustomShapeBounds(rect(0,0,ADest.Width,ADest.Height),AMatrix,ADraft);
     shapeBounds := GetCustomShapeBounds(rect(0,0,ADest.Width,ADest.Height),AMatrix,ADraft);
     shapeBounds.Intersect(ADest.ClipRect);
     shapeBounds.Intersect(ADest.ClipRect);
@@ -100,16 +100,16 @@ begin
         grayShape.CopyFrom(temp, cAlpha);
         grayShape.CopyFrom(temp, cAlpha);
 
 
         blurBounds := actualShapeBounds;
         blurBounds := actualShapeBounds;
-        blurBounds.Inflate(ceil(Manager.ToolTextBlur),ceil(Manager.ToolTextBlur));
-        blurBounds.Offset(Manager.ToolTextShadowOffset.X,Manager.ToolTextShadowOffset.Y);
+        blurBounds.Inflate(ceil(Manager.TextShadowBlurRadius),ceil(Manager.TextShadowBlurRadius));
+        blurBounds.Offset(Manager.TextShadowOffset.X,Manager.TextShadowOffset.Y);
         r := ADest.ClipRect;
         r := ADest.ClipRect;
-        r.Inflate(ceil(Manager.ToolTextBlur),ceil(Manager.ToolTextBlur));
+        r.Inflate(ceil(Manager.TextShadowBlurRadius),ceil(Manager.TextShadowBlurRadius));
         blurBounds.Intersect(r);
         blurBounds.Intersect(r);
         gray := TGrayscaleMask.Create(blurBounds.Width,blurBounds.Height);
         gray := TGrayscaleMask.Create(blurBounds.Width,blurBounds.Height);
-        gray.PutImage(shapeBounds.Left-blurBounds.Left+Manager.ToolTextShadowOffset.X,
-                      shapeBounds.Top-blurBounds.Top+Manager.ToolTextShadowOffset.Y,grayShape,dmSet);
+        gray.PutImage(shapeBounds.Left-blurBounds.Left+Manager.TextShadowOffset.X,
+                      shapeBounds.Top-blurBounds.Top+Manager.TextShadowOffset.Y,grayShape,dmSet);
         grayShape.Free;
         grayShape.Free;
-        blur := gray.FilterBlurRadial(Manager.ToolTextBlur,Manager.ToolTextBlur, rbFast) as TGrayscaleMask;
+        blur := gray.FilterBlurRadial(Manager.TextShadowBlurRadius,Manager.TextShadowBlurRadius, rbFast) as TGrayscaleMask;
         gray.Free;
         gray.Free;
         ADest.FillMask(blurBounds.Left,blurBounds.Top,blur,BGRABlack,dmDrawWithTransparency);
         ADest.FillMask(blurBounds.Left,blurBounds.Top,blur,BGRABlack,dmDrawWithTransparency);
         blur.Free;
         blur.Free;
@@ -118,8 +118,8 @@ begin
       temp.Free;
       temp.Free;
     end;
     end;
     FPrevShadow := true;
     FPrevShadow := true;
-    FPrevShadowRadius := Manager.ToolTextBlur;
-    FPrevShadowOffset := Manager.ToolTextShadowOffset;
+    FPrevShadowRadius := Manager.TextShadowBlurRadius;
+    FPrevShadowOffset := Manager.TextShadowOffset;
   end else
   end else
   begin
   begin
     inherited DrawCustomShape(ADest, AMatrix, ADraft);
     inherited DrawCustomShape(ADest, AMatrix, ADraft);
@@ -133,7 +133,7 @@ var
   posF: TPointF;
   posF: TPointF;
 begin
 begin
   posF := AffineMatrixInverse(FMatrix)*(FShape as TTextShape).LightPosition;
   posF := AffineMatrixInverse(FMatrix)*(FShape as TTextShape).LightPosition;
-  Manager.ToolLightPosition := posF;
+  Manager.LightPosition := posF;
   with ABounds do r := rect(floor(Left),floor(Top),ceil(Right),ceil(Bottom));
   with ABounds do r := rect(floor(Left),floor(Top),ceil(Right),ceil(Bottom));
   IncludeShadowBounds(r);
   IncludeShadowBounds(r);
   inherited ShapeChange(ASender, RectF(r.Left,r.Top,r.Right,r.Bottom), ADiff);
   inherited ShapeChange(ASender, RectF(r.Left,r.Top,r.Right,r.Bottom), ADiff);
@@ -156,40 +156,40 @@ begin
   with TTextShape(FShape) do
   with TTextShape(FShape) do
   begin
   begin
     zoom := (VectLen(AMatrix[1,1],AMatrix[2,1])+VectLen(AMatrix[1,2],AMatrix[2,2]))/2;
     zoom := (VectLen(AMatrix[1,1],AMatrix[2,1])+VectLen(AMatrix[1,2],AMatrix[2,2]))/2;
-    FontEmHeight:= zoom*Manager.ToolTextFont.Size*ScreenInfo.PixelsPerInchY/72;
-    FontName:= Manager.ToolTextFont.Name;
-    FontStyle:= Manager.ToolTextFont.Style;
+    FontEmHeight:= zoom*Manager.TextFontSize*Manager.Image.DPI/72;
+    FontName:= Manager.TextFontName;
+    FontStyle:= Manager.TextFontStyle;
 
 
-    if Manager.GetToolTexture <> nil then
-      FShape.PenFill.SetTexture(Manager.GetToolTexture,AffineMatrixIdentity,Manager.ToolTextureOpacity)
+    if Manager.GetTexture <> nil then
+      FShape.PenFill.SetTexture(Manager.GetTexture,AffineMatrixIdentity,Manager.TextureOpacity)
     else
     else
     begin
     begin
       if FSwapColor then
       if FSwapColor then
-        FShape.PenFill.SetSolid(Manager.ToolBackColor)
+        FShape.PenFill.SetSolid(Manager.BackColor)
       else
       else
-        FShape.PenFill.SetSolid(Manager.ToolForeColor);
+        FShape.PenFill.SetSolid(Manager.ForeColor);
     end;
     end;
 
 
-    if Manager.ToolTextOutline and (Manager.ToolTextOutlineWidth>0) and
-       (Manager.ToolBackColor.alpha > 0) then
+    if Manager.TextOutline and (Manager.TextOutlineWidth>0) and
+       (Manager.BackColor.alpha > 0) then
     begin
     begin
       if FSwapColor then
       if FSwapColor then
-        FShape.OutlineFill.SetSolid(Manager.ToolForeColor)
+        FShape.OutlineFill.SetSolid(Manager.ForeColor)
       else
       else
-        FShape.OutlineFill.SetSolid(Manager.ToolBackColor);
-      OutlineWidth := Manager.ToolTextOutlineWidth;
+        FShape.OutlineFill.SetSolid(Manager.BackColor);
+      OutlineWidth := Manager.TextOutlineWidth;
     end
     end
     else
     else
       OutlineFill.Clear;
       OutlineFill.Clear;
 
 
-    LightPosition := AMatrix*Manager.ToolLightPosition;
-    AltitudePercent:= Manager.ToolShapeAltitude;
+    LightPosition := AMatrix*Manager.LightPosition;
+    AltitudePercent:= Manager.PhongShapeAltitude;
     ParagraphAlignment:= Manager.ToolTextAlign;
     ParagraphAlignment:= Manager.ToolTextAlign;
-    PenPhong := Manager.ToolTextPhong;
+    PenPhong := Manager.TextPhong;
   end;
   end;
-  if (Manager.ToolTextShadow <> FPrevShadow) or
-     (Manager.ToolTextBlur <> FPrevShadowRadius) or
-     (Manager.ToolTextShadowOffset <> FPrevShadowOffset) then
+  if (Manager.TextShadow <> FPrevShadow) or
+     (Manager.TextShadowBlurRadius <> FPrevShadowRadius) or
+     (Manager.TextShadowOffset <> FPrevShadowOffset) then
   begin
   begin
     toolDest := GetToolDrawingLayer;
     toolDest := GetToolDrawingLayer;
     r:= UpdateShape(toolDest);
     r:= UpdateShape(toolDest);
@@ -220,8 +220,8 @@ end;
 
 
 function TToolText.GetContextualToolbars: TContextualToolbars;
 function TToolText.GetContextualToolbars: TContextualToolbars;
 begin
 begin
-  Result:= [ctColor,ctTexture,ctText];
-  if Manager.ToolTextPhong then include(result, ctAltitude);
+  Result:= [ctColor,ctTexture,ctText,ctTextShadow];
+  if Manager.TextPhong then include(result, ctAltitude);
 end;
 end;
 
 
 function TToolText.ToolKeyDown(var key: Word): TRect;
 function TToolText.ToolKeyDown(var key: Word): TRect;

+ 431 - 92
lazpaint/tools/utoolvectorial.pas

@@ -6,8 +6,14 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, LCLType, BGRABitmap, BGRABitmapTypes,
   Classes, SysUtils, LCLType, BGRABitmap, BGRABitmapTypes,
-  BGRALayerOriginal, LCVectorOriginal,
-  UTool, UImageType, ULayerAction, LCVectorRectShapes;
+  BGRALayerOriginal, BGRAGraphics, LCVectorOriginal,
+  UTool, UImageType, ULayerAction, LCVectorRectShapes,
+  BGRAGradientOriginal;
+
+type
+  TToolSplineMode = (tsmMovePoint, tsmCurveModeAuto, tsmCurveModeAngle, tsmCurveModeSpline);
+
+function ToolSplineModeFromShape(AShape: TVectorShape): TToolSplineMode;
 
 
 type
 type
   { TVectorialTool }
   { TVectorialTool }
@@ -75,25 +81,25 @@ type
   { TEditShapeTool }
   { TEditShapeTool }
 
 
   TEditShapeTool = class(TGenericTool)
   TEditShapeTool = class(TGenericTool)
-  private
-    procedure SelectShape({%H-}ASender: TObject; AShape: TVectorShape;
-      {%H-}APreviousShape: TVectorShape);
   protected
   protected
     FShiftState: TShiftState;
     FShiftState: TShiftState;
-    FLeftButton,FRightButton: boolean;
+    FDownHandled,FLeftButton,FRightButton: boolean;
     FLastPos: TPointF;
     FLastPos: TPointF;
     FOriginalRect: TRectShape;
     FOriginalRect: TRectShape;
     FOriginalRectUntransformed: TRectF;
     FOriginalRectUntransformed: TRectF;
     FOriginalRectEditor: TBGRAOriginalEditor;
     FOriginalRectEditor: TBGRAOriginalEditor;
     FIsEditingGradient: boolean;
     FIsEditingGradient: boolean;
+    procedure RetrieveLightPosition;
+    procedure UpdateToolManagerFromShape(AShape: TVectorShape);
     procedure BindOriginalEvent(ABind: boolean);
     procedure BindOriginalEvent(ABind: boolean);
+    procedure SelectShape({%H-}ASender: TObject; AShape: TVectorShape; {%H-}APreviousShape: TVectorShape);
     function DoToolDown({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF; rightBtn: boolean): TRect; override;
     function DoToolDown({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF; rightBtn: boolean): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF): TRect; override;
     function DoToolUpdate({%H-}toolDest: TBGRABitmap): TRect; override;
     function DoToolUpdate({%H-}toolDest: TBGRABitmap): TRect; override;
     function GetAction: TLayerAction; override;
     function GetAction: TLayerAction; override;
     function DoGetToolDrawingLayer: TBGRABitmap; override;
     function DoGetToolDrawingLayer: TBGRABitmap; override;
     procedure OnTryStop({%H-}sender: TCustomLayerAction); override;
     procedure OnTryStop({%H-}sender: TCustomLayerAction); override;
-    procedure StopEdit;
+    procedure StopEdit(AUpdateToolbars: boolean);
     function IsVectorOriginal: boolean;
     function IsVectorOriginal: boolean;
     function IsGradientOriginal: boolean;
     function IsGradientOriginal: boolean;
     function IsOtherOriginal: boolean;
     function IsOtherOriginal: boolean;
@@ -102,10 +108,15 @@ type
     procedure UpdateOriginalMatrixFromRect;
     procedure UpdateOriginalMatrixFromRect;
     function GetIsSelectingTool: boolean; override;
     function GetIsSelectingTool: boolean; override;
     function GetVectorOriginal: TVectorOriginal;
     function GetVectorOriginal: TVectorOriginal;
+    function GetGradientOriginal: TBGRALayerGradientOriginal;
     function FixLayerOffset: boolean; override;
     function FixLayerOffset: boolean; override;
+    function GetCurrentSplineMode: TToolSplineMode;
+    procedure SetCurrentSplineMode(AMode: TToolSplineMode);
+    function IsGradientShape(AShape: TVectorShape): boolean;
   public
   public
     constructor Create(AManager: TToolManager); override;
     constructor Create(AManager: TToolManager); override;
     destructor Destroy; override;
     destructor Destroy; override;
+    function GetContextualToolbars: TContextualToolbars; override;
     function Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth, VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect; override;
     function Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth, VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect; override;
     function ToolKeyDown(var key: Word): TRect; override;
     function ToolKeyDown(var key: Word): TRect; override;
     function ToolKeyPress(var key: TUTF8Char): TRect; override;
     function ToolKeyPress(var key: TUTF8Char): TRect; override;
@@ -117,13 +128,14 @@ type
     function ToolProvideCopy: boolean; override;
     function ToolProvideCopy: boolean; override;
     function ToolProvideCut: boolean; override;
     function ToolProvideCut: boolean; override;
     function ToolProvidePaste: boolean; override;
     function ToolProvidePaste: boolean; override;
+    property CurrentSplineMode: TToolSplineMode read GetCurrentSplineMode write SetCurrentSplineMode;
   end;
   end;
 
 
 implementation
 implementation
 
 
-uses LazPaintType, LCVectorTextShapes, LCVectorialFill, BGRASVGOriginal,
+uses LazPaintType, LCVectorPolyShapes, LCVectorTextShapes, LCVectorialFill, BGRASVGOriginal,
   ULoading, BGRATransform, math, UStateType, UImageDiff, Controls, BGRAPen, UResourceStrings, ugraph,
   ULoading, BGRATransform, math, UStateType, UImageDiff, Controls, BGRAPen, UResourceStrings, ugraph,
-  LCScaleDPI, LCVectorClipboard, BGRAGradientOriginal;
+  LCScaleDPI, LCVectorClipboard, BGRAGradientScanner;
 
 
 const PointSize = 6;
 const PointSize = 6;
 
 
@@ -145,32 +157,183 @@ begin
   end;
   end;
 end;
 end;
 
 
+function ToolSplineModeFromShape(AShape: TVectorShape): TToolSplineMode;
+var
+  c: TCurveShape;
+begin
+  result := tsmMovePoint;
+  if not (AShape is TCurveShape) then exit;
+  c := TCurveShape(AShape);
+  case c.Usermode of
+  vsuEdit: result := tsmMovePoint;
+  vsuCreate: if c.PointCount > 1 then
+             begin
+               case c.CurveMode[c.PointCount-2] of
+                 cmAuto: result := tsmCurveModeAuto;
+                 cmAngle: result := tsmCurveModeAngle;
+                 cmCurve: result := tsmCurveModeSpline;
+               end;
+             end else
+               result := tsmCurveModeAuto;
+  vsuCurveSetAuto: result := tsmCurveModeAuto;
+  vsuCurveSetAngle: result := tsmCurveModeAngle;
+  vsuCurveSetCurve: result := tsmCurveModeSpline;
+  end;
+end;
+
 { TEditShapeTool }
 { TEditShapeTool }
 
 
 procedure TEditShapeTool.SelectShape(ASender: TObject; AShape: TVectorShape;
 procedure TEditShapeTool.SelectShape(ASender: TObject; AShape: TVectorShape;
   APreviousShape: TVectorShape);
   APreviousShape: TVectorShape);
 begin
 begin
-  if Assigned(AShape) then
+  if Assigned(AShape) and IsVectorOriginal then
+  begin
+    UpdateToolManagerFromShape(AShape);
+    Manager.UpdateContextualToolbars;
+  end else
+  if Assigned(APreviousShape) then
+    Manager.UpdateContextualToolbars;
+end;
+
+procedure TEditShapeTool.RetrieveLightPosition;
+var
+  shape: TVectorShape;
+  m: TAffineMatrix;
+begin
+  if IsVectorOriginal then
+  begin
+    shape := GetVectorOriginal.SelectedShape;
+    if shape=nil then exit;
+    m := Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex];
+    if (shape is TTextShape) and TTextShape(shape).PenPhong then
+      Manager.LightPosition := m*TTextShape(shape).LightPosition
+    else if shape is TPhongShape then
+      Manager.LightPosition := m*TPhongShape(shape).LightPosition;
+  end;
+end;
+
+procedure TEditShapeTool.UpdateToolManagerFromShape(AShape: TVectorShape);
+var
+  ps: TPenStyle;
+  opt: TShapeOptions;
+  zoom: single;
+  m: TAffineMatrix;
+  doFill, doDraw: Boolean;
+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
+  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
   begin
-    if (vsfBackFill in AShape.Fields) and (AShape.BackFill.FillType = vftGradient) then
+    opt := Manager.ShapeOptions;
+    if AShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
     begin
     begin
-      Manager.ToolForeColor := AShape.BackFill.Gradient.StartColor;
-      Manager.ToolBackColor := AShape.BackFill.Gradient.EndColor;
-      Manager.SetToolTexture(nil);
+      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
     end else
     begin
     begin
-      if (vsfPenFill in AShape.Fields) and (AShape.PenFill.FillType = vftSolid) then
-        Manager.ToolForeColor := AShape.PenFill.SolidColor;
-      if (vsfBackFill in AShape.Fields) and (AShape.BackFill.FillType = vftSolid) then
-        Manager.ToolBackColor := AShape.BackFill.SolidColor;
-      if (vsfBackFill in AShape.Fields) and (AShape.BackFill.FillType = vftTexture) then
-        Manager.SetToolTexture(AShape.BackFill.Texture,AShape.BackFill.TextureOpacity)
-      else if (vsfPenFill in AShape.Fields) and (AShape.PenFill.FillType = vftTexture) then
-        Manager.SetToolTexture(AShape.PenFill.Texture,AShape.PenFill.TextureOpacity)
-      else
-        Manager.SetToolTexture(nil);
+      doDraw := vsfPenFill in AShape.Fields;
+      doFill := vsfBackFill in AShape.Fields;
+    end;
+
+    if doDraw 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
+    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;
+    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)
+    else
+      Manager.SetTexture(nil);
+
+    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 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;
+    end;
+    Manager.ShapeOptions := opt;
+  end;
+
+  if AShape is TTextShape then
+  with TTextShape(AShape) do
+  begin
+    Manager.TextPhong := PenPhong;
+    Manager.LightPosition := m*LightPosition;
+    Manager.PhongShapeAltitude := round(AltitudePercent);
+    Manager.ToolTextAlign:= ParagraphAlignment;
+    Manager.SetTextFont(FontName,round(FontEmHeight*zoom*72/Manager.Image.DPI),FontStyle);
+    Manager.TextShadow:= false;
+    if OutlineFill.FillType = vftNone then
+      Manager.SetTextOutline(false, Manager.TextOutlineWidth) else
+    begin
+      Manager.SetTextOutline(true, OutlineWidth);
+      if OutlineFill.FillType = vftSolid then
+        Manager.BackColor := OutlineFill.SolidColor;
     end;
     end;
   end;
   end;
+
+  if AShape is TPhongShape then
+  with TPhongShape(AShape) do
+  begin
+    Manager.PhongShapeKind:= ShapeKind;
+    Manager.LightPosition:= LightPosition;
+    Manager.PhongShapeAltitude:= round(ShapeAltitudePercent);
+    Manager.PhongShapeBorderSize:= round(BorderSizePercent);
+  end;
 end;
 end;
 
 
 procedure TEditShapeTool.BindOriginalEvent(ABind: boolean);
 procedure TEditShapeTool.BindOriginalEvent(ABind: boolean);
@@ -212,11 +375,21 @@ begin
   FRightButton:= rightBtn;
   FRightButton:= rightBtn;
   FLeftButton:= not rightBtn;
   FLeftButton:= not rightBtn;
   FLastPos := ptF;
   FLastPos := ptF;
+  handled := false;
   if IsVectorOriginal or IsGradientOriginal then
   if IsVectorOriginal or IsGradientOriginal then
   begin
   begin
-    if not FIsEditingGradient then
+    if IsGradientOriginal and not FIsEditingGradient then
     begin
     begin
       FIsEditingGradient:= true;
       FIsEditingGradient:= true;
+      with GetGradientOriginal do
+      begin
+        Manager.ForeColor := StartColor;
+        Manager.BackColor := EndColor;
+        Manager.GradientType := GradientType;
+        Manager.GradientSine := (Repetition = grSine);
+        Manager.GradientColorspace := ColorInterpolation;
+      end;
+      Manager.UpdateContextualToolbars;
       result := OnlyRenderChange;
       result := OnlyRenderChange;
     end else
     end else
     begin
     begin
@@ -246,6 +419,7 @@ begin
           FOriginalRect.Origin := (box.TopLeft+box.BottomRight)*0.5;
           FOriginalRect.Origin := (box.TopLeft+box.BottomRight)*0.5;
           FOriginalRect.XAxis := FOriginalRect.Origin+(box.TopRight-box.TopLeft)*0.5;
           FOriginalRect.XAxis := FOriginalRect.Origin+(box.TopRight-box.TopLeft)*0.5;
           FOriginalRect.YAxis := FOriginalRect.Origin+(box.BottomLeft-box.TopLeft)*0.5;
           FOriginalRect.YAxis := FOriginalRect.Origin+(box.BottomLeft-box.TopLeft)*0.5;
+          Manager.UpdateContextualToolbars;
         end;
         end;
         result := OnlyRenderChange;
         result := OnlyRenderChange;
       end;
       end;
@@ -261,10 +435,11 @@ begin
           result := OnlyRenderChange;
           result := OnlyRenderChange;
           UpdateOriginalMatrixFromRect;
           UpdateOriginalMatrixFromRect;
         end else
         end else
-          StopEdit;
+          StopEdit(true);
       end;
       end;
     end;
     end;
   end;
   end;
+  FDownHandled:= handled;
 end;
 end;
 
 
 function TEditShapeTool.DoToolMove(toolDest: TBGRABitmap; pt: TPoint;
 function TEditShapeTool.DoToolMove(toolDest: TBGRABitmap; pt: TPoint;
@@ -297,72 +472,153 @@ begin
 end;
 end;
 
 
 function TEditShapeTool.DoToolUpdate(toolDest: TBGRABitmap): TRect;
 function TEditShapeTool.DoToolUpdate(toolDest: TBGRABitmap): TRect;
+var
+  doDraw, doFill: Boolean;
+  m: TAffineMatrix;
+  zoom: Single;
 begin
 begin
   if IsVectorOriginal then
   if IsVectorOriginal then
   with GetVectorOriginal do
   with GetVectorOriginal do
   begin
   begin
+    m := AffineMatrixInverse(Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex]);
+    zoom := (VectLen(m[1,1],m[2,1])+VectLen(m[1,2],m[2,2]))/2;
     BindOriginalEvent(true);
     BindOriginalEvent(true);
     if Assigned(SelectedShape) then
     if Assigned(SelectedShape) then
     begin
     begin
-      if (vsfBackFill in SelectedShape.Fields) and (SelectedShape.BackFill.FillType = vftGradient) then
+      if IsGradientShape(SelectedShape) then
       begin
       begin
-        if Assigned(Manager.GetToolTexture) then
-          SelectedShape.BackFill.SetTexture(Manager.GetToolTexture, AffineMatrixIdentity, Manager.ToolTextureOpacity)
-        else
+        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
         begin
-          SelectedShape.BackFill.Gradient.StartColor := Manager.ToolForeColor;
-          SelectedShape.BackFill.Gradient.EndColor := Manager.ToolBackColor;
+          if Manager.GradientSine then
+            SelectedShape.BackFill.Gradient.Repetition := grSine
+          else
+            SelectedShape.BackFill.Gradient.Repetition := grPad;
         end;
         end;
       end else
       end else
       begin
       begin
-        if Assigned(Manager.GetToolTexture) then
+        if SelectedShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
         begin
         begin
-          case SelectedShape.BackFill.FillType of
-          vftTexture:
+          doDraw := toDrawShape in Manager.ShapeOptions;
+          doFill := toFillShape in Manager.ShapeOptions;
+
+          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
+            TCustomPolypointShape(SelectedShape).Closed := toCloseShape in Manager.ShapeOptions;
+            if not TCustomPolypointShape(SelectedShape).Closed then
             begin
             begin
-              SelectedShape.BackFill.SetTexture(Manager.GetToolTexture,
-                SelectedShape.BackFill.TextureMatrix,Manager.ToolTextureOpacity,
-                SelectedShape.BackFill.TextureRepetition);
-              if (vsfPenFill in SelectedShape.Fields) and (SelectedShape.PenFill.FillType = vftSolid) then
-                SelectedShape.PenFill.SolidColor := Manager.ToolForeColor;
+              TCustomPolypointShape(SelectedShape).LineCap:= Manager.LineCap;
+              TCustomPolypointShape(SelectedShape).ArrowSize:= Manager.ArrowSize;
+              TCustomPolypointShape(SelectedShape).ArrowStartKind:= Manager.ArrowStart;
+              TCustomPolypointShape(SelectedShape).ArrowEndKind:= Manager.ArrowEnd;
             end;
             end;
-          vftGradient,vftSolid:
+          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
             begin
-              SelectedShape.BackFill.SetTexture(Manager.GetToolTexture, AffineMatrixIdentity,
-                Manager.ToolTextureOpacity);
-              if (vsfPenFill in SelectedShape.Fields) and (SelectedShape.PenFill.FillType = vftSolid) then
-                SelectedShape.PenFill.SolidColor := Manager.ToolForeColor;
-            end;
-          vftNone: begin
-              case SelectedShape.PenFill.FillType of
-              vftTexture:
-                begin
-                  SelectedShape.PenFill.SetTexture(Manager.GetToolTexture,
-                    SelectedShape.PenFill.TextureMatrix,Manager.ToolTextureOpacity,
-                    SelectedShape.PenFill.TextureRepetition);
-                  if (vsfBackFill in SelectedShape.Fields) and (SelectedShape.BackFill.FillType = vftSolid) then
-                    SelectedShape.BackFill.SolidColor := Manager.ToolBackColor;
-                end;
-              vftGradient,vftSolid:
-                begin
-                  SelectedShape.PenFill.SetTexture(Manager.GetToolTexture, AffineMatrixIdentity,
-                    Manager.ToolTextureOpacity);
-                  if (vsfBackFill in SelectedShape.Fields) and (SelectedShape.BackFill.FillType = vftSolid) then
-                    SelectedShape.BackFill.SolidColor := Manager.ToolBackColor;
-                end;
-              end;
-            end;
+              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;
         end else
         end else
+          if vsfBackFill in SelectedShape.Fields then
+            SelectedShape.BackFill.Clear;
+        if doDraw 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
+          begin
+            if SelectedShape.PenFill.FillType <> vftGradient then
+              SelectedShape.PenFill.SetSolid(Manager.ForeColor);
+          end;
+        end;
+        if SelectedShape is TTextShape then
+        with TTextShape(SelectedShape) do
+        begin
+          PenPhong := Manager.TextPhong;
+          LightPosition := m*Manager.LightPosition;
+          AltitudePercent := Manager.PhongShapeAltitude;
+          ParagraphAlignment := Manager.ToolTextAlign;
+          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
         begin
         begin
-          if (vsfPenFill in SelectedShape.Fields) and (SelectedShape.PenFill.FillType in [vftSolid,vftTexture]) then
-            SelectedShape.PenFill.SolidColor := Manager.ToolForeColor;
-          if (vsfBackFill in SelectedShape.Fields) and (SelectedShape.BackFill.FillType in [vftSolid,vftTexture]) then
-            SelectedShape.BackFill.SolidColor := Manager.ToolBackColor;
+          ShapeKind := Manager.PhongShapeKind;
+          LightPosition := Manager.LightPosition;
+          ShapeAltitudePercent := Manager.PhongShapeAltitude;
+          BorderSizePercent := Manager.PhongShapeBorderSize;
         end;
         end;
       end;
       end;
     end;
     end;
     BindOriginalEvent(false);
     BindOriginalEvent(false);
+  end else
+  if IsGradientOriginal then
+  begin
+    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;
+    end;
+    BindOriginalEvent(false);
   end;
   end;
   Result := EmptyRect;
   Result := EmptyRect;
 end;
 end;
@@ -379,11 +635,11 @@ end;
 
 
 procedure TEditShapeTool.OnTryStop(sender: TCustomLayerAction);
 procedure TEditShapeTool.OnTryStop(sender: TCustomLayerAction);
 begin
 begin
-  StopEdit;
+  StopEdit(True);
   inherited OnTryStop(sender);
   inherited OnTryStop(sender);
 end;
 end;
 
 
-procedure TEditShapeTool.StopEdit;
+procedure TEditShapeTool.StopEdit(AUpdateToolbars: boolean);
 var
 var
   r: TRect;
   r: TRect;
 begin
 begin
@@ -399,6 +655,7 @@ begin
   FreeAndNil(FOriginalRectEditor);
   FreeAndNil(FOriginalRectEditor);
   Cursor := crDefault;
   Cursor := crDefault;
   Manager.Image.OnImageChanged.NotifyObservers;
   Manager.Image.OnImageChanged.NotifyObservers;
+  if AUpdateToolbars then Manager.UpdateContextualToolbars;
 end;
 end;
 
 
 function TEditShapeTool.IsVectorOriginal: boolean;
 function TEditShapeTool.IsVectorOriginal: boolean;
@@ -468,22 +725,49 @@ begin
   result := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal;
   result := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal;
 end;
 end;
 
 
-function TEditShapeTool.FixLayerOffset: boolean;
+function TEditShapeTool.GetGradientOriginal: TBGRALayerGradientOriginal;
 begin
 begin
-  Result:= false;
+  result := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TBGRALayerGradientOriginal;
 end;
 end;
 
 
-constructor TEditShapeTool.Create(AManager: TToolManager);
+function TEditShapeTool.FixLayerOffset: boolean;
 begin
 begin
-  inherited Create(AManager);
+  Result:= false;
 end;
 end;
 
 
 destructor TEditShapeTool.Destroy;
 destructor TEditShapeTool.Destroy;
 begin
 begin
-  StopEdit;
+  StopEdit(False);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+function TEditShapeTool.GetContextualToolbars: TContextualToolbars;
+var
+  shape: TVectorShape;
+begin
+  Result:= [ctColor,ctTexture];
+  if IsVectorOriginal then
+    shape := GetVectorOriginal.SelectedShape
+  else shape := nil;
+  if Assigned(shape) then
+  begin
+    if shape is TRectShape then result := result + [ctShape,ctPenWidth,ctPenStyle,ctJoinStyle]
+    else if shape is TEllipseShape then result := result + [ctShape,ctPenWidth,ctPenStyle]
+    else if shape is TCurveShape then result := result + [ctShape,ctPenWidth,ctPenStyle,ctLineCap,ctSplineStyle]
+    else if shape is TPolylineShape then result := result + [ctShape,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap]
+    else if shape is TPhongShape then result := result + [ctPhong,ctAltitude]
+    else if shape is TTextShape then
+    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 else
+  if IsGradientOriginal and FIsEditingGradient then
+    result := [ctColor,ctGradient];
+end;
+
 function TEditShapeTool.Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth,
 function TEditShapeTool.Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth,
   VirtualScreenHeight: integer;
   VirtualScreenHeight: integer;
   BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;
   BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;
@@ -508,6 +792,7 @@ begin
       result := Manager.Image.CurrentState.LayeredBitmap.GetEditorBounds(
       result := Manager.Image.CurrentState.LayeredBitmap.GetEditorBounds(
         rect(0,0,VirtualScreenWidth,VirtualScreenHeight),
         rect(0,0,VirtualScreenWidth,VirtualScreenHeight),
         Manager.Image.CurrentLayerIndex, viewMatrix, DoScaleX(PointSize,OriginalDPI));
         Manager.Image.CurrentLayerIndex, viewMatrix, DoScaleX(PointSize,OriginalDPI));
+    RetrieveLightPosition;
   end else
   end else
   begin
   begin
     result := EmptyRect;
     result := EmptyRect;
@@ -534,6 +819,54 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TEditShapeTool.GetCurrentSplineMode: TToolSplineMode;
+var
+  orig: TVectorOriginal;
+begin
+  if IsVectorOriginal then
+  begin
+    orig := GetVectorOriginal;
+    if Assigned(orig.SelectedShape) and
+      (orig.SelectedShape is TCurveShape) then
+      exit(ToolSplineModeFromShape(orig.SelectedShape));
+  end;
+  result := tsmMovePoint;
+end;
+
+procedure TEditShapeTool.SetCurrentSplineMode(AMode: TToolSplineMode);
+var
+  c: TCurveShape;
+begin
+  if IsVectorOriginal and Assigned(GetVectorOriginal.SelectedShape) and
+    (GetVectorOriginal.SelectedShape is TCurveShape) then
+  begin
+    c := TCurveShape(GetVectorOriginal.SelectedShape);
+    case AMode of
+    tsmMovePoint: if not (c.Usermode in [vsuEdit,vsuCreate]) then c.Usermode := vsuEdit;
+    tsmCurveModeAuto: if c.Usermode <> vsuCreate then c.Usermode := vsuCurveSetAuto else
+                      if c.PointCount > 1 then c.CurveMode[c.PointCount-2] := cmAuto;
+    tsmCurveModeAngle: if c.Usermode <> vsuCreate then c.Usermode := vsuCurveSetAngle else
+                       if c.PointCount > 1 then c.CurveMode[c.PointCount-2] := cmAngle;
+    tsmCurveModeSpline: if c.Usermode <> vsuCreate then c.Usermode := vsuCurveSetCurve else
+                        if c.PointCount > 1 then c.CurveMode[c.PointCount-2] := cmCurve;
+    end;
+  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;
+
+constructor TEditShapeTool.Create(AManager: TToolManager);
+begin
+  inherited Create(AManager);
+  if IsVectorOriginal and Assigned(GetVectorOriginal.SelectedShape) then
+    UpdateToolManagerFromShape(GetVectorOriginal.SelectedShape);
+end;
+
 function TEditShapeTool.ToolKeyDown(var key: Word): TRect;
 function TEditShapeTool.ToolKeyDown(var key: Word): TRect;
 var
 var
   handled: boolean;
   handled: boolean;
@@ -559,17 +892,21 @@ begin
     begin
     begin
       BindOriginalEvent(true);
       BindOriginalEvent(true);
       Manager.Image.CurrentState.LayeredBitmap.KeyDown(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
       Manager.Image.CurrentState.LayeredBitmap.KeyDown(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
+      if handled then key := 0;
       if not handled and IsVectorOriginal then
       if not handled and IsVectorOriginal then
       begin
       begin
         if (key = VK_DELETE) and Assigned(GetVectorOriginal.SelectedShape) then
         if (key = VK_DELETE) and Assigned(GetVectorOriginal.SelectedShape) then
+        begin
           GetVectorOriginal.RemoveShape(GetVectorOriginal.SelectedShape);
           GetVectorOriginal.RemoveShape(GetVectorOriginal.SelectedShape);
+          key := 0;
+        end;
       end;
       end;
       BindOriginalEvent(false);
       BindOriginalEvent(false);
     end else
     end else
     begin
     begin
       if key = VK_RETURN then
       if key = VK_RETURN then
       begin
       begin
-        StopEdit;
+        StopEdit(true);
         key := 0;
         key := 0;
       end;
       end;
     end;
     end;
@@ -585,6 +922,7 @@ begin
   begin
   begin
     BindOriginalEvent(true);
     BindOriginalEvent(true);
     Manager.Image.CurrentState.LayeredBitmap.KeyPress(key, handled);
     Manager.Image.CurrentState.LayeredBitmap.KeyPress(key, handled);
+    if handled then key := #0;
     BindOriginalEvent(false);
     BindOriginalEvent(false);
   end;
   end;
 end;
 end;
@@ -614,6 +952,7 @@ begin
     begin
     begin
       BindOriginalEvent(true);
       BindOriginalEvent(true);
       Manager.Image.CurrentState.LayeredBitmap.KeyUp(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
       Manager.Image.CurrentState.LayeredBitmap.KeyUp(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
+      if handled then key := 0;
       BindOriginalEvent(false);
       BindOriginalEvent(false);
     end;
     end;
   end;
   end;
@@ -640,7 +979,7 @@ begin
         Cursor := OriginalCursorToCursor(cur);
         Cursor := OriginalCursorToCursor(cur);
         result := OnlyRenderChange;
         result := OnlyRenderChange;
       end;
       end;
-      if not handled and IsVectorOriginal then
+      if not handled and not FDownHandled and IsVectorOriginal then
       begin
       begin
         m := AffineMatrixInverse(Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex]);
         m := AffineMatrixInverse(Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex]);
         GetVectorOriginal.MouseClick(m*FLastPos);
         GetVectorOriginal.MouseClick(m*FLastPos);
@@ -934,35 +1273,35 @@ begin
   f:= FShape.Fields;
   f:= FShape.Fields;
   if vsfPenFill in f then
   if vsfPenFill in f then
   begin
   begin
-    if Manager.ToolOptionDrawShape then
+    if Manager.ShapeOptionDraw then
     begin
     begin
-      if (not (vsfBackFill in f) or not Manager.ToolOptionFillShape) and (Manager.GetToolTexture <> nil) then
-        FShape.PenFill.SetTexture(Manager.GetToolTexture,AMatrix,Manager.ToolTextureOpacity)
+      if (not (vsfBackFill in f) or not Manager.ShapeOptionFill) and (Manager.GetTexture <> nil) then
+        FShape.PenFill.SetTexture(Manager.GetTexture,AMatrix,Manager.TextureOpacity)
       else
       else
       begin
       begin
         if FSwapColor then
         if FSwapColor then
-          FShape.PenFill.SetSolid(Manager.ToolBackColor)
+          FShape.PenFill.SetSolid(Manager.BackColor)
         else
         else
-          FShape.PenFill.SetSolid(Manager.ToolForeColor);
+          FShape.PenFill.SetSolid(Manager.ForeColor);
       end;
       end;
     end else
     end else
       FShape.PenFill.Clear;
       FShape.PenFill.Clear;
   end;
   end;
-  if vsfPenWidth in f then FShape.PenWidth := zoom*Manager.ToolPenWidth;
-  if vsfPenStyle in f Then FShape.PenStyle := PenStyleToBGRA(Manager.ToolPenStyle);
-  if vsfJoinStyle in f then FShape.JoinStyle:= Manager.ToolJoinStyle;
+  if vsfPenWidth in f then FShape.PenWidth := zoom*Manager.PenWidth;
+  if vsfPenStyle in f Then FShape.PenStyle := PenStyleToBGRA(Manager.PenStyle);
+  if vsfJoinStyle in f then FShape.JoinStyle:= Manager.JoinStyle;
   if vsfBackFill in f then
   if vsfBackFill in f then
   begin
   begin
-    if Manager.ToolOptionFillShape then
+    if Manager.ShapeOptionFill then
     begin
     begin
-      if Manager.GetToolTexture <> nil then
-        FShape.BackFill.SetTexture(Manager.GetToolTexture,AffineMatrixIdentity,Manager.ToolTextureOpacity)
+      if Manager.GetTexture <> nil then
+        FShape.BackFill.SetTexture(Manager.GetTexture,AffineMatrixIdentity,Manager.TextureOpacity)
       else
       else
       begin
       begin
         if FSwapColor then
         if FSwapColor then
-          FShape.BackFill.SetSolid(Manager.ToolForeColor)
+          FShape.BackFill.SetSolid(Manager.ForeColor)
         else
         else
-          FShape.BackFill.SetSolid(Manager.ToolBackColor);
+          FShape.BackFill.SetSolid(Manager.BackColor);
       end;
       end;
     end else
     end else
       FShape.BackFill.Clear;
       FShape.BackFill.Clear;
@@ -976,7 +1315,7 @@ end;
 
 
 function TVectorialTool.RoundCoordinate(ptF: TPointF): TPointF;
 function TVectorialTool.RoundCoordinate(ptF: TPointF): TPointF;
 begin
 begin
-  if not Manager.ToolOptionDrawShape or
+  if not Manager.ShapeOptionDraw or
     (Assigned(FShape) and not (vsfPenFill in FShape.Fields)) then
     (Assigned(FShape) and not (vsfPenFill in FShape.Fields)) then
     result := PointF(floor(ptF.x)+0.5,floor(ptF.y)+0.5)
     result := PointF(floor(ptF.x)+0.5,floor(ptF.y)+0.5)
   else
   else

+ 33 - 14
lazpaint/uconfig.pas

@@ -6,7 +6,7 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, IniFiles, BGRABitmapTypes, Graphics, LCLType, uscripting,
   Classes, SysUtils, IniFiles, BGRABitmapTypes, Graphics, LCLType, uscripting,
-  Forms;
+  Forms, LCVectorRectShapes;
 
 
 type
 type
   TLazPaintConfig = class;
   TLazPaintConfig = class;
@@ -203,7 +203,7 @@ type
     function DefaultToolTextShadow: boolean;
     function DefaultToolTextShadow: boolean;
     procedure SetDefaultToolTextShadow(value: boolean);
     procedure SetDefaultToolTextShadow(value: boolean);
     function DefaultToolTextFont: TFont;
     function DefaultToolTextFont: TFont;
-    procedure SetDefaultToolTextFont(value: TFont);
+    procedure SetDefaultToolTextFont(AFont: TFont);
     function DefaultToolTextBlur: single;
     function DefaultToolTextBlur: single;
     procedure SetDefaultToolTextBlur(value: single);
     procedure SetDefaultToolTextBlur(value: single);
     function DefaultToolTextShadowOffsetX: integer;
     function DefaultToolTextShadowOffsetX: integer;
@@ -230,8 +230,8 @@ type
     procedure SetDefaultToolShapeAltitude(value: integer);
     procedure SetDefaultToolShapeAltitude(value: integer);
     function DefaultToolShapeBorderSize: integer;
     function DefaultToolShapeBorderSize: integer;
     procedure SetDefaultToolShapeBorderSize(value: integer);
     procedure SetDefaultToolShapeBorderSize(value: integer);
-    function DefaultToolShapeType: string;
-    procedure SetDefaultToolShapeType(value: string);
+    function DefaultToolShapeType: TPhongShapeKind;
+    procedure SetDefaultToolShapeType(value: TPhongShapeKind);
 
 
     function DefaultRetrieveSelectionAnswer: TModalResult;
     function DefaultRetrieveSelectionAnswer: TModalResult;
     procedure SetDefaultRetrieveSelectionAnswer(value: TModalResult);
     procedure SetDefaultRetrieveSelectionAnswer(value: TModalResult);
@@ -855,8 +855,7 @@ function TLazPaintConfig.DefaultToolTextFont: TFont;
 var fontStyle: TFontStyles;
 var fontStyle: TFontStyles;
 begin
 begin
   tempFont.Name := iniOptions.ReadString('Tool','TextFontName','Arial');
   tempFont.Name := iniOptions.ReadString('Tool','TextFontName','Arial');
-  tempFont.Height := iniOptions.ReadInteger('Tool','TextFontHeight',-13);
-  tempFont.CharSet := iniOptions.ReadInteger('Tool','TextFontCharSet',ANSI_CHARSET);
+  tempFont.Size := iniOptions.ReadInteger('Tool','TextFontSize',10);
   fontStyle := [];
   fontStyle := [];
   if iniOptions.ReadBool('Tool','TextFontBold',False) then fontStyle += [fsBold];
   if iniOptions.ReadBool('Tool','TextFontBold',False) then fontStyle += [fsBold];
   if iniOptions.ReadBool('Tool','TextFontItalic',False) then fontStyle += [fsItalic];
   if iniOptions.ReadBool('Tool','TextFontItalic',False) then fontStyle += [fsItalic];
@@ -866,13 +865,13 @@ begin
   result := tempFont;
   result := tempFont;
 end;
 end;
 
 
-procedure TLazPaintConfig.SetDefaultToolTextFont(value: TFont);
+procedure TLazPaintConfig.SetDefaultToolTextFont(AFont: TFont);
 begin
 begin
-  tempFont.Assign(value);
+  tempFont.Assign(AFont);
 
 
   iniOptions.WriteString('Tool','TextFontName',tempFont.Name);
   iniOptions.WriteString('Tool','TextFontName',tempFont.Name);
   iniOptions.WriteInteger('Tool','TextFontHeight',tempFont.Height);
   iniOptions.WriteInteger('Tool','TextFontHeight',tempFont.Height);
-  iniOptions.WriteInteger('Tool','TextFontCharSet',tempFont.CharSet);
+  iniOptions.WriteInteger('Tool','TextFontSize',tempFont.Size);
   iniOptions.WriteBool('Tool','TextFontBold',fsBold in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontBold',fsBold in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontItalic',fsItalic in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontItalic',fsItalic in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontStrikeOut',fsStrikeOut in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontStrikeOut',fsStrikeOut in tempFont.Style);
@@ -1002,14 +1001,34 @@ begin
   iniOptions.WriteInteger('Filter','ShapeBorderSize',value);
   iniOptions.WriteInteger('Filter','ShapeBorderSize',value);
 end;
 end;
 
 
-function TLazPaintConfig.DefaultToolShapeType: string;
+function TLazPaintConfig.DefaultToolShapeType: TPhongShapeKind;
+var
+  str: String;
 begin
 begin
-  result := iniOptions.ReadString('Filter','ShapeType','Rectangle');
+  str := iniOptions.ReadString('Filter','ShapeType','Rectangle');
+  if str = 'RoundRectangle' then result := pskRoundRectangle else
+  if str = 'Sphere' then result := pskHalfSphere else
+  if str = 'Cone' then result := pskConeTop else
+  if str = 'VerticalCone' then result := pskConeSide else
+  if str = 'VerticalCylinder' then result := pskVertCylinder else
+  if str = 'HorizontalCylinder' then result := pskHorizCylinder
+  else result := pskRectangle;
 end;
 end;
 
 
-procedure TLazPaintConfig.SetDefaultToolShapeType(value: string);
-begin
-  iniOptions.WriteString('Filter','ShapeType',value);
+procedure TLazPaintConfig.SetDefaultToolShapeType(value: TPhongShapeKind);
+var
+  str: String;
+begin
+  case value of
+  pskRoundRectangle: str := 'RoundRectangle';
+  pskHalfSphere: str := 'Sphere';
+  pskConeTop: str := 'Cone';
+  pskConeSide: str := 'VerticalCone';
+  pskVertCylinder: str := 'VerticalCylinder';
+  pskHorizCylinder: str := 'HorizontalCylinder';
+  else str:= 'Rectangle'
+  end;
+  iniOptions.WriteString('Filter','ShapeType',str);
 end;
 end;
 
 
 function TLazPaintConfig.DefaultRetrieveSelectionAnswer: TModalResult;
 function TLazPaintConfig.DefaultRetrieveSelectionAnswer: TModalResult;

+ 2 - 2
lazpaint/ufilters.pas

@@ -175,12 +175,12 @@ begin
     pfClouds:
     pfClouds:
       begin
       begin
         filteredLayer := layer.Duplicate as TBGRABitmap;
         filteredLayer := layer.Duplicate as TBGRABitmap;
-        RenderCloudsOn(filteredLayer,AInstance.ToolManager.ToolForeColor);
+        RenderCloudsOn(filteredLayer,AInstance.ToolManager.ForeColor);
       end;
       end;
     pfCustomWater:
     pfCustomWater:
     begin
     begin
       filteredLayer := layer.Duplicate as TBGRABitmap;
       filteredLayer := layer.Duplicate as TBGRABitmap;
-      RenderWaterOn(filteredLayer,AInstance.ToolManager.ToolForeColor,AInstance.ToolManager.ToolBackColor);
+      RenderWaterOn(filteredLayer,AInstance.ToolManager.ForeColor,AInstance.ToolManager.BackColor);
     end;
     end;
     pfWater: filteredLayer := CreateWaterTexture(layer.Width,layer.Height);
     pfWater: filteredLayer := CreateWaterTexture(layer.Width,layer.Height);
     pfWood: filteredLayer := CreateWoodTexture(layer.Width,layer.Height);
     pfWood: filteredLayer := CreateWoodTexture(layer.Width,layer.Height);

+ 3 - 3
lazpaint/uimageview.pas

@@ -435,8 +435,8 @@ begin
   with LazPaintInstance.ToolManager do
   with LazPaintInstance.ToolManager do
   begin
   begin
     result.c := self.BitmapToVirtualScreen(ToolCurrentCursorPos);
     result.c := self.BitmapToVirtualScreen(ToolCurrentCursorPos);
-    tl := self.BitmapToVirtualScreen(ToolCurrentCursorPos.X-ToolPenWidth/2,ToolCurrentCursorPos.Y-ToolPenWidth/2);
-    br := self.BitmapToVirtualScreen(ToolCurrentCursorPos.X+ToolPenWidth/2,ToolCurrentCursorPos.Y+ToolPenWidth/2);
+    tl := self.BitmapToVirtualScreen(ToolCurrentCursorPos.X-PenWidth/2,ToolCurrentCursorPos.Y-PenWidth/2);
+    br := self.BitmapToVirtualScreen(ToolCurrentCursorPos.X+PenWidth/2,ToolCurrentCursorPos.Y+PenWidth/2);
   end;
   end;
   result.rx := (br.x-tl.x)/2-0.5;
   result.rx := (br.x-tl.x)/2-0.5;
   result.ry := (br.y-tl.y)/2-0.5;
   result.ry := (br.y-tl.y)/2-0.5;
@@ -515,7 +515,7 @@ var virtualScreenPenCursorBefore: boolean;
   function UseVSPenCursor: boolean;
   function UseVSPenCursor: boolean;
   begin
   begin
     if FLastPictureParameters.Defined and
     if FLastPictureParameters.Defined and
-      (LazPaintInstance.ToolManager.ToolPenWidth * FLastPictureParameters.zoomFactorX > 6) and
+      (LazPaintInstance.ToolManager.PenWidth * FLastPictureParameters.zoomFactorX > 6) and
       PtInRect(FLastPictureParameters.scaledArea, Point(X,Y)) then
       PtInRect(FLastPictureParameters.scaledArea, Point(X,Y)) then
     begin
     begin
       FPenCursorVisible := True;
       FPenCursorVisible := True;

+ 4 - 4
lazpaint/upalettetoolbar.pas

@@ -626,14 +626,14 @@ begin
     if (ssLeft in Shift) and not (ssRight in Shift) then
     if (ssLeft in Shift) and not (ssRight in Shift) then
     begin
     begin
       c := FColors.Color[idx];
       c := FColors.Color[idx];
-      if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.ToolForeColor.alpha;
-      LazPaintInstance.ToolManager.ToolForeColor := c;
+      if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.ForeColor.alpha;
+      LazPaintInstance.ToolManager.ForeColor := c;
     end else
     end else
     if not (ssLeft in Shift) and (ssRight in Shift) then
     if not (ssLeft in Shift) and (ssRight in Shift) then
     begin
     begin
       c := FColors.Color[idx];
       c := FColors.Color[idx];
-      if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.ToolBackColor.alpha;
-      LazPaintInstance.ToolManager.ToolBackColor := c;
+      if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.BackColor.alpha;
+      LazPaintInstance.ToolManager.BackColor := c;
     end else
     end else
         exit;
         exit;
     LazPaintInstance.UpdateToolbar;
     LazPaintInstance.UpdateToolbar;

+ 49 - 3
lazpaintcontrols/lcvectorpolyshapes.pas

@@ -6,7 +6,7 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, Types, LCVectorOriginal, BGRABitmapTypes, BGRALayerOriginal,
   Classes, SysUtils, Types, LCVectorOriginal, BGRABitmapTypes, BGRALayerOriginal,
-  BGRABitmap, BGRATransform, BGRAGradients;
+  BGRABitmap, BGRATransform, BGRAGradients, BGRAGraphics;
 
 
 type
 type
   TArrowKind = (akNone, akTail, akTip, akNormal, akCut, akFlipped, akFlippedCut,
   TArrowKind = (akNone, akTail, akTip, akNormal, akCut, akFlipped, akFlippedCut,
@@ -18,8 +18,11 @@ const
     ('none', 'tail', 'tip', 'normal', 'cut', 'flipped', 'flipped-cut',
     ('none', 'tail', 'tip', 'normal', 'cut', 'flipped', 'flipped-cut',
      'triangle', 'triangle-back1', 'triangle-back2',
      'triangle', 'triangle-back1', 'triangle-back2',
      'hollow-triangle', 'hollow-triangle-back1', 'hollow-triangle-back2');
      'hollow-triangle', 'hollow-triangle-back1', 'hollow-triangle-back2');
+  LineCapToStr: array[TPenEndCap] of string =
+    ('round','square','flat');
 
 
 function StrToArrowKind(AStr: string): TArrowKind;
 function StrToArrowKind(AStr: string): TArrowKind;
+function StrToLineCap(AStr: string): TPenEndCap;
 
 
 type
 type
   TCustomPolypointShape = class;
   TCustomPolypointShape = class;
@@ -37,10 +40,12 @@ type
     FStartClosed: boolean;
     FStartClosed: boolean;
     FStartArrowStartKind,FStartArrowEndKind: TArrowKind;
     FStartArrowStartKind,FStartArrowEndKind: TArrowKind;
     FStartArrowSize: TPointF;
     FStartArrowSize: TPointF;
+    FStartLineCap: TPenEndCap;
     FEndPoints: array of TCustomPolypointPoint;
     FEndPoints: array of TCustomPolypointPoint;
     FEndClosed: boolean;
     FEndClosed: boolean;
     FEndArrowStartKind,FEndArrowEndKind: TArrowKind;
     FEndArrowStartKind,FEndArrowEndKind: TArrowKind;
     FEndArrowSize: TPointF;
     FEndArrowSize: TPointF;
+    FEndLineCap: TPenEndCap;
   public
   public
     constructor Create(AStartShape: TVectorShape); override;
     constructor Create(AStartShape: TVectorShape); override;
     procedure ComputeDiff(AEndShape: TVectorShape); override;
     procedure ComputeDiff(AEndShape: TVectorShape); override;
@@ -55,11 +60,13 @@ type
   TCustomPolypointShape = class(TVectorShape)
   TCustomPolypointShape = class(TVectorShape)
   private
   private
     FClosed: boolean;
     FClosed: boolean;
+    function GetLineCap: TPenEndCap;
     function GetPoint(AIndex: integer): TPointF;
     function GetPoint(AIndex: integer): TPointF;
     function GetPointCount: integer;
     function GetPointCount: integer;
     procedure SetArrowEndKind(AValue: TArrowKind);
     procedure SetArrowEndKind(AValue: TArrowKind);
     procedure SetArrowSize(AValue: TPointF);
     procedure SetArrowSize(AValue: TPointF);
     procedure SetArrowStartKind(AValue: TArrowKind);
     procedure SetArrowStartKind(AValue: TArrowKind);
+    procedure SetLineCap(AValue: TPenEndCap);
     procedure SetPoint(AIndex: integer; AValue: TPointF);
     procedure SetPoint(AIndex: integer; AValue: TPointF);
   protected
   protected
     FPoints: array of TCustomPolypointPoint;
     FPoints: array of TCustomPolypointPoint;
@@ -110,6 +117,7 @@ type
     property ArrowStartKind: TArrowKind read FArrowStartKind write SetArrowStartKind;
     property ArrowStartKind: TArrowKind read FArrowStartKind write SetArrowStartKind;
     property ArrowEndKind: TArrowKind read FArrowEndKind write SetArrowEndKind;
     property ArrowEndKind: TArrowKind read FArrowEndKind write SetArrowEndKind;
     property ArrowSize: TPointF read FArrowSize write SetArrowSize;
     property ArrowSize: TPointF read FArrowSize write SetArrowSize;
+    property LineCap: TPenEndCap read GetLineCap write SetLineCap;
   end;
   end;
 
 
   { TPolylineShape }
   { TPolylineShape }
@@ -143,6 +151,7 @@ type
     procedure Apply(AStartShape: TVectorShape); override;
     procedure Apply(AStartShape: TVectorShape); override;
     procedure Unapply(AEndShape: TVectorShape); override;
     procedure Unapply(AEndShape: TVectorShape); override;
     procedure Append(ADiff: TVectorShapeDiff); override;
     procedure Append(ADiff: TVectorShapeDiff); override;
+    function IsIdentity: boolean; override;
   end;
   end;
 
 
   { TCurveShape }
   { TCurveShape }
@@ -176,7 +185,7 @@ procedure ApplyArrowStyle(AArrow: TBGRACustomArrow; AStart: boolean; AKind: TArr
 
 
 implementation
 implementation
 
 
-uses BGRAPen, BGRAGraphics, BGRAFillInfo, BGRAPath, math, LCVectorialFill,
+uses BGRAPen, BGRAFillInfo, BGRAPath, math, LCVectorialFill,
   BGRAArrow;
   BGRAArrow;
 
 
 function StrToArrowKind(AStr: string): TArrowKind;
 function StrToArrowKind(AStr: string): TArrowKind;
@@ -188,6 +197,15 @@ begin
   result := akNone;
   result := akNone;
 end;
 end;
 
 
+function StrToLineCap(AStr: string): TPenEndCap;
+var
+  ec: TPenEndCap;
+begin
+  for ec := low(TPenEndCap) to high(TPenEndCap) do
+    if CompareText(AStr, LineCapToStr[ec])=0 then exit(ec);
+  result := pecRound;
+end;
+
 procedure ApplyArrowStyle(AArrow: TBGRACustomArrow; AStart: boolean; AKind: TArrowKind; ASize: TPointF);
 procedure ApplyArrowStyle(AArrow: TBGRACustomArrow; AStart: boolean; AKind: TArrowKind; ASize: TPointF);
 var backOfs: single;
 var backOfs: single;
 begin
 begin
@@ -291,6 +309,12 @@ begin
   FEndSplineStyle:= next.FEndSplineStyle;
   FEndSplineStyle:= next.FEndSplineStyle;
 end;
 end;
 
 
+function TCurveShapeDiff.IsIdentity: boolean;
+begin
+  result := (FStartCosineAngle = FEndCosineAngle) and
+    (FStartSplineStyle = FEndSplineStyle);
+end;
+
 { TCustomPolypointShapeDiff }
 { TCustomPolypointShapeDiff }
 
 
 constructor TCustomPolypointShapeDiff.Create(AStartShape: TVectorShape);
 constructor TCustomPolypointShapeDiff.Create(AStartShape: TVectorShape);
@@ -305,6 +329,7 @@ begin
     FStartArrowStartKind := FArrowStartKind;
     FStartArrowStartKind := FArrowStartKind;
     FStartArrowEndKind:= FArrowEndKind;
     FStartArrowEndKind:= FArrowEndKind;
     FStartArrowSize:= FArrowSize;
     FStartArrowSize:= FArrowSize;
+    FStartLineCap:= Stroker.LineCap;
   end;
   end;
 end;
 end;
 
 
@@ -320,6 +345,7 @@ begin
     FEndArrowStartKind := FArrowStartKind;
     FEndArrowStartKind := FArrowStartKind;
     FEndArrowEndKind:= FArrowEndKind;
     FEndArrowEndKind:= FArrowEndKind;
     FEndArrowSize:= FArrowSize;
     FEndArrowSize:= FArrowSize;
+    FEndLineCap:= Stroker.LineCap;
   end;
   end;
 end;
 end;
 
 
@@ -336,6 +362,7 @@ begin
     FArrowStartKind := FEndArrowStartKind;
     FArrowStartKind := FEndArrowStartKind;
     FArrowEndKind := FEndArrowEndKind;
     FArrowEndKind := FEndArrowEndKind;
     FArrowSize := FEndArrowSize;
     FArrowSize := FEndArrowSize;
+    Stroker.LineCap:= FEndLineCap;
     EndUpdate;
     EndUpdate;
   end;
   end;
 end;
 end;
@@ -353,6 +380,7 @@ begin
     FArrowStartKind := FStartArrowStartKind;
     FArrowStartKind := FStartArrowStartKind;
     FArrowEndKind := FStartArrowEndKind;
     FArrowEndKind := FStartArrowEndKind;
     FArrowSize := FStartArrowSize;
     FArrowSize := FStartArrowSize;
+    Stroker.LineCap:= FStartLineCap;
     EndUpdate;
     EndUpdate;
   end;
   end;
 end;
 end;
@@ -369,6 +397,7 @@ begin
   FEndArrowStartKind := next.FEndArrowStartKind;
   FEndArrowStartKind := next.FEndArrowStartKind;
   FEndArrowEndKind := next.FEndArrowEndKind;
   FEndArrowEndKind := next.FEndArrowEndKind;
   FEndArrowSize := next.FEndArrowSize;
   FEndArrowSize := next.FEndArrowSize;
+  FEndLineCap:= next.FEndLineCap;
 end;
 end;
 
 
 function TCustomPolypointShapeDiff.IsIdentity: boolean;
 function TCustomPolypointShapeDiff.IsIdentity: boolean;
@@ -379,7 +408,8 @@ begin
     (FStartClosed = FEndClosed) and
     (FStartClosed = FEndClosed) and
     (FStartArrowStartKind = FEndArrowStartKind) and
     (FStartArrowStartKind = FEndArrowStartKind) and
     (FStartArrowEndKind = FEndArrowEndKind) and
     (FStartArrowEndKind = FEndArrowEndKind) and
-    (FStartArrowSize = FEndArrowSize);
+    (FStartArrowSize = FEndArrowSize) and
+    (FStartLineCap = FEndLineCap);
   if result then
   if result then
   begin
   begin
     for i := 0 to high(FStartPoints) do
     for i := 0 to high(FStartPoints) do
@@ -406,6 +436,11 @@ begin
   result := FPoints[AIndex].coord;
   result := FPoints[AIndex].coord;
 end;
 end;
 
 
+function TCustomPolypointShape.GetLineCap: TPenEndCap;
+begin
+  result := Stroker.LineCap;
+end;
+
 function TCustomPolypointShape.GetPointCount: integer;
 function TCustomPolypointShape.GetPointCount: integer;
 begin
 begin
   result:= length(FPoints);
   result:= length(FPoints);
@@ -435,6 +470,14 @@ begin
   EndUpdate;
   EndUpdate;
 end;
 end;
 
 
+procedure TCustomPolypointShape.SetLineCap(AValue: TPenEndCap);
+begin
+  if Stroker.LineCap=AValue then Exit;
+  BeginUpdate(TCustomPolypointShapeDiff);
+  Stroker.LineCap:=AValue;
+  EndUpdate;
+end;
+
 procedure TCustomPolypointShape.SetClosed(AValue: boolean);
 procedure TCustomPolypointShape.SetClosed(AValue: boolean);
 begin
 begin
   if AValue = FClosed then exit;
   if AValue = FClosed then exit;
@@ -650,6 +693,7 @@ begin
     Stroker.Arrow := TBGRAArrow.Create;
     Stroker.Arrow := TBGRAArrow.Create;
     Stroker.ArrowOwned:= true;
     Stroker.ArrowOwned:= true;
   end;
   end;
+  Stroker.Arrow.LineCap:= LineCap;
   ApplyArrowStyle(Stroker.Arrow, true, ArrowStartKind, ArrowSize);
   ApplyArrowStyle(Stroker.Arrow, true, ArrowStartKind, ArrowSize);
   ApplyArrowStyle(Stroker.Arrow, false, ArrowEndKind, ArrowSize);
   ApplyArrowStyle(Stroker.Arrow, false, ArrowEndKind, ArrowSize);
   Result:=inherited ComputeStroke(APoints, AClosed, AStrokeMatrix);
   Result:=inherited ComputeStroke(APoints, AClosed, AStrokeMatrix);
@@ -807,6 +851,7 @@ begin
   else FArrowSize := DefaultArrowSize;
   else FArrowSize := DefaultArrowSize;
   FArrowStartKind:= StrToArrowKind(AStorage.RawString['arrow-start-kind']);
   FArrowStartKind:= StrToArrowKind(AStorage.RawString['arrow-start-kind']);
   FArrowEndKind:= StrToArrowKind(AStorage.RawString['arrow-end-kind']);
   FArrowEndKind:= StrToArrowKind(AStorage.RawString['arrow-end-kind']);
+  Stroker.LineCap := StrToLineCap(AStorage.RawString['line-cap']);
   EndUpdate;
   EndUpdate;
 end;
 end;
 
 
@@ -832,6 +877,7 @@ begin
   else AStorage.RawString['arrow-end-kind'] := ArrowKindToStr[ArrowEndKind];
   else AStorage.RawString['arrow-end-kind'] := ArrowKindToStr[ArrowEndKind];
   if (ArrowStartKind=akNone) and (ArrowEndKind=akNone) then AStorage.RemoveAttribute('arrow-size')
   if (ArrowStartKind=akNone) and (ArrowEndKind=akNone) then AStorage.RemoveAttribute('arrow-size')
   else AStorage.PointF['arrow-size'] := FArrowSize;
   else AStorage.PointF['arrow-size'] := FArrowSize;
+  AStorage.RawString['line-cap'] := LineCapToStr[Stroker.LineCap];
 end;
 end;
 
 
 procedure TCustomPolypointShape.ConfigureCustomEditor(AEditor: TBGRAOriginalEditor);
 procedure TCustomPolypointShape.ConfigureCustomEditor(AEditor: TBGRAOriginalEditor);

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików