Răsfoiți Sursa

edit vector shapes, some refactoring, LineCap

Johann 6 ani în urmă
părinte
comite
066bc7ca30

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

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

+ 8 - 1
lazpaint/image/uimage.pas

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

+ 2 - 2
lazpaint/image/uimageaction.pas

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

+ 2 - 2
lazpaint/image/uimagediff.pas

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

+ 9 - 51
lazpaint/lazpaintinstance.pas

@@ -350,28 +350,7 @@ procedure TLazPaintInstance.UseConfig(ini: TInifile);
 begin
   FreeAndNil(FConfig);
   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;
   FDockLayersAndColors:= Config.DefaultDockLayersAndColors;
 end;
@@ -847,11 +826,11 @@ begin
       FTextureEditConfig := TStringStream.Create('[General]'+LineEnding+
         'DefaultImageWidth=256'+LineEnding+
         'DefaultImageHeight=256'+LineEnding);
-    tex := ToolManager.BorrowToolTexture;
+    tex := ToolManager.BorrowTexture;
     try
       EditBitmap(tex,FTextureEditConfig,rsEditTexture,nil,nil,BlackAndWhite);
     finally
-      ToolManager.SetToolTexture(tex);
+      ToolManager.SetTexture(tex);
     end;
   except
     on ex: Exception do
@@ -868,7 +847,7 @@ end;
 procedure TLazPaintInstance.ToolColorChanged(Sender: TObject);
 begin
   ColorToFChooseColor;
-  if Assigned(FMain) then FMain.UpdateToolbar;
+  if Assigned(FMain) then FMain.UpdateColorToolbar(false);
 end;
 
 function TLazPaintInstance.GetIcons(ASize: integer): TImageList;
@@ -1084,28 +1063,7 @@ begin
     Config.SetDefaultToolboxWindowVisible(ToolboxVisible or (FTopMostInfo.toolboxHidden > 0));
     Config.SetDefaultToolboxWindowPosition(FToolBox.BoundsRect);
   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
   begin
@@ -1248,9 +1206,9 @@ begin
   if InColorFromFChooseColor then exit;
   InColorFromFChooseColor := True;
   if FChooseColor.colorTarget = ctForeColor then
-    ToolManager.ToolForeColor := FChooseColor.GetCurrentColor else
+    ToolManager.ForeColor := FChooseColor.GetCurrentColor else
   if FChooseColor.colorTarget = ctBackColor then
-    ToolManager.ToolBackColor := FChooseColor.GetCurrentColor;
+    ToolManager.BackColor := FChooseColor.GetCurrentColor;
   if Assigned(FMain) then FMain.UpdateEditPicture;
   InColorFromFChooseColor := false;
 end;
@@ -1259,9 +1217,9 @@ procedure TLazPaintInstance.ColorToFChooseColor;
 begin
   if not Assigned(FChooseColor) or InColorFromFChooseColor then exit;
   if FChooseColor.colorTarget = ctForeColor then
-    FChooseColor.SetCurrentColor(ToolManager.ToolForeColor) else
+    FChooseColor.SetCurrentColor(ToolManager.ForeColor) else
   if FChooseColor.colorTarget = ctBackColor then
-    FChooseColor.SetCurrentColor(ToolManager.ToolBackColor);
+    FChooseColor.SetCurrentColor(ToolManager.BackColor);
 end;
 
 function TLazPaintInstance.ShowSaveOptionDlg(AParameters: TVariableSet;

+ 242 - 192
lazpaint/lazpaintmainform.lfm

@@ -940,12 +940,12 @@ object FMain: TFMain
     end
   end
   object Panel_LineCap: TPanel
-    Left = 90
+    Left = 144
     Height = 45
     Top = 130
-    Width = 348
+    Width = 318
     ClientHeight = 45
-    ClientWidth = 348
+    ClientWidth = 318
     Font.Height = -15
     ParentColor = False
     ParentFont = False
@@ -954,7 +954,7 @@ object FMain: TFMain
       Left = 221
       Height = 28
       Top = 1
-      Width = 117
+      Width = 88
       Align = alNone
       AutoSize = True
       EdgeBorders = []
@@ -963,7 +963,7 @@ object FMain: TFMain
       ParentFont = False
       TabOrder = 0
       object Tool_CapFlat: TToolButton
-        Left = 30
+        Left = 1
         Hint = 'Flat cap'
         Top = 0
         Grouped = True
@@ -971,7 +971,7 @@ object FMain: TFMain
         Style = tbsCheck
       end
       object Tool_CapRound: TToolButton
-        Left = 59
+        Left = 30
         Hint = 'Round cap'
         Top = 0
         Down = True
@@ -980,20 +980,13 @@ object FMain: TFMain
         Style = tbsCheck
       end
       object Tool_CapSquare: TToolButton
-        Left = 88
+        Left = 59
         Hint = 'Square cap'
         Top = 0
         Grouped = True
         ImageIndex = 47
         Style = tbsCheck
       end
-      object Tool_CloseShape: TToolButton
-        Left = 1
-        Hint = 'Close shape'
-        Top = 0
-        ImageIndex = 10
-        Style = tbsCheck
-      end
     end
     object SpinEdit_ArrowSizeX: TBCTrackbarUpdown
       Left = 116
@@ -1229,7 +1222,7 @@ object FMain: TFMain
     end
   end
   object Panel_JoinStyle: TPanel
-    Left = 460
+    Left = 480
     Height = 45
     Top = 130
     Width = 94
@@ -1279,7 +1272,7 @@ object FMain: TFMain
     end
   end
   object Panel_PenStyle: TPanel
-    Left = 576
+    Left = 584
     Height = 45
     Top = 130
     Width = 150
@@ -1785,9 +1778,9 @@ object FMain: TFMain
     Left = 10
     Height = 45
     Top = 250
-    Width = 556
+    Width = 262
     ClientHeight = 45
-    ClientWidth = 556
+    ClientWidth = 262
     Font.Height = -15
     ParentColor = False
     ParentFont = False
@@ -1808,7 +1801,7 @@ object FMain: TFMain
       Left = 106
       Height = 28
       Top = 1
-      Width = 175
+      Width = 146
       Align = alNone
       AutoSize = True
       EdgeBorders = []
@@ -1822,13 +1815,6 @@ object FMain: TFMain
         Top = 0
         ImageIndex = 61
       end
-      object Tool_TextShadow: TToolButton
-        Left = 146
-        Hint = 'Text shadow'
-        Top = 0
-        ImageIndex = 62
-        Style = tbsCheck
-      end
       object Tool_TextPhong: TToolButton
         Left = 117
         Hint = 'Text phong shading'
@@ -1859,30 +1845,6 @@ object FMain: TFMain
         Style = tbsCheck
       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
       Left = 46
       Height = 25
@@ -1930,147 +1892,6 @@ object FMain: TFMain
       TabStop = True
       UseDockManager = False
     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
   object Panel_PhongShape: TPanel
     Left = 10
@@ -2298,7 +2119,7 @@ object FMain: TFMain
     end
   end
   object Panel_TextOutline: TPanel
-    Left = 580
+    Left = 599
     Height = 45
     Top = 250
     Width = 146
@@ -2700,6 +2521,235 @@ object FMain: TFMain
       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
     left = 48
     top = 672

+ 153 - 35
lazpaint/lazpaintmainform.pas

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

Fișier diff suprimat deoarece este prea mare
+ 316 - 239
lazpaint/maintoolbar.inc


Fișier diff suprimat deoarece este prea mare
+ 479 - 176
lazpaint/tools/utool.pas


+ 47 - 47
lazpaint/tools/utoolbasic.pas

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

+ 3 - 3
lazpaint/tools/utoolbrush.pas

@@ -223,14 +223,14 @@ end;
 
 function TToolGenericBrush.GetBrushInfo: TLazPaintBrush;
 begin
-  result := manager.ToolBrushInfo;
+  result := manager.BrushInfo;
   if result = nil then
   begin
     if defaultBrush = nil then
       defaultBrush := TLazPaintBrush.Create;
     result := defaultBrush;
   end;
-  result.Size := manager.ToolPenWidth;
+  result.Size := manager.PenWidth;
 end;
 
 function TToolGenericBrush.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
@@ -239,7 +239,7 @@ begin
   if not SubPixelAccuracy then
     brushOrigin:= PointF(round(ptF.x),round(ptF.y))
   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;
   PrepareBrush(rightBtn);
   result := ContinueDrawing(toolDest,brushOrigin,brushOrigin);

+ 19 - 19
lazpaint/tools/utooldeformationgrid.pas

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

+ 8 - 16
lazpaint/tools/utoolfloodfill.pas

@@ -73,19 +73,11 @@ procedure TToolGradient.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
   with FShape.BackFill.Gradient do
   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
     else
       Repetition := grPad;
@@ -134,11 +126,11 @@ function TToolFloodFill.DoToolDown(toolDest: TBGRABitmap; pt: TPoint;
 var
    floodFillMask,floodFillTex: TBGRABitmap;
 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
     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);
     floodFillTex.ApplyMask(floodFillMask);
     toolDest.PutImage(0,0,floodFillTex,dmDrawWithTransparency);

+ 5 - 11
lazpaint/tools/utoolphong.pas

@@ -45,7 +45,7 @@ var
   posF: TPointF;
 begin
   posF := AffineMatrixInverse(FMatrix)*(FShape as TPhongShape).LightPosition;
-  Manager.ToolLightPosition := posF;
+  Manager.LightPosition := posF;
   inherited ShapeChange(ASender, ABounds, ADiff);
 end;
 
@@ -55,16 +55,10 @@ begin
   FMatrix := AMatrix;
   with (FShape as TPhongShape) do
   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;
 

+ 11 - 31
lazpaint/tools/utoolpolygon.pas

@@ -12,8 +12,6 @@ const
   EasyBezierMinimumDotProduct = 0.5;
 
 type
-  TToolSplineMode = (tsmMovePoint, tsmCurveModeAuto, tsmCurveModeAngle, tsmCurveModeSpline);
-
   { TToolRectangle }
 
   TToolRectangle = class(TVectorialTool)
@@ -76,7 +74,7 @@ end;
 
 function TToolEllipse.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle];
 end;
 
 { TToolRectangle }
@@ -88,34 +86,15 @@ end;
 
 function TToolRectangle.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctJoinStyle];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle];
 end;
 
 { TToolSpline }
 
 function TToolSpline.GetCurrentMode: TToolSplineMode;
-var
-  c: TCurveShape;
 begin
   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;
 end;
 
@@ -163,7 +142,7 @@ end;
 procedure TToolSpline.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
   inherited AssignShapeStyle(AMatrix);
-  TCurveShape(FShape).SplineStyle:= Manager.ToolSplineStyle;
+  TCurveShape(FShape).SplineStyle:= Manager.SplineStyle;
 end;
 
 constructor TToolSpline.Create(AManager: TToolManager);
@@ -180,7 +159,7 @@ end;
 
 function TToolSpline.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctLineCap];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctLineCap,ctSplineStyle];
 end;
 
 { TToolPolygon }
@@ -193,10 +172,11 @@ end;
 procedure TToolPolygon.AssignShapeStyle(AMatrix: TAffineMatrix);
 begin
   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;
 end;
 
@@ -208,7 +188,7 @@ end;
 
 function TToolPolygon.GetContextualToolbars: TContextualToolbars;
 begin
-  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctJoinStyle,ctLineCap];
+  Result:= [ctColor,ctTexture,ctShape,ctPenWidth,ctPenStyle,ctJoinStyle,ctLineCap];
 end;
 
 initialization

+ 4 - 4
lazpaint/tools/utoolselect.pas

@@ -550,15 +550,15 @@ function TToolSelectionPen.StartDrawing(toolDest: TBGRABitmap; ptF: TPointF;
   rightBtn: boolean): TRect;
 begin
   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;
 
 function TToolSelectionPen.ContinueDrawing(toolDest: TBGRABitmap; originF,
   destF: TPointF): TRect;
 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;
 
 function TToolSelectionPen.GetContextualToolbars: TContextualToolbars;

+ 34 - 34
lazpaint/tools/utooltext.pas

@@ -55,18 +55,18 @@ end;
 
 function TToolText.AlwaysRasterizeShape: boolean;
 begin
-  Result:= Manager.ToolTextShadow;
+  Result:= Manager.TextShadow;
 end;
 
 procedure TToolText.IncludeShadowBounds(var ARect: TRect);
 var
   shadowRect: TRect;
 begin
-  if Manager.ToolTextShadow then
+  if Manager.TextShadow then
   begin
     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);
   end;
 end;
@@ -84,7 +84,7 @@ var
   blur, gray, grayShape: TGrayscaleMask;
   shapeBounds, blurBounds, r, actualShapeBounds: TRect;
 begin
-  if Manager.ToolTextShadow then
+  if Manager.TextShadow then
   begin
     shapeBounds := GetCustomShapeBounds(rect(0,0,ADest.Width,ADest.Height),AMatrix,ADraft);
     shapeBounds.Intersect(ADest.ClipRect);
@@ -100,16 +100,16 @@ begin
         grayShape.CopyFrom(temp, cAlpha);
 
         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.Inflate(ceil(Manager.ToolTextBlur),ceil(Manager.ToolTextBlur));
+        r.Inflate(ceil(Manager.TextShadowBlurRadius),ceil(Manager.TextShadowBlurRadius));
         blurBounds.Intersect(r);
         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;
-        blur := gray.FilterBlurRadial(Manager.ToolTextBlur,Manager.ToolTextBlur, rbFast) as TGrayscaleMask;
+        blur := gray.FilterBlurRadial(Manager.TextShadowBlurRadius,Manager.TextShadowBlurRadius, rbFast) as TGrayscaleMask;
         gray.Free;
         ADest.FillMask(blurBounds.Left,blurBounds.Top,blur,BGRABlack,dmDrawWithTransparency);
         blur.Free;
@@ -118,8 +118,8 @@ begin
       temp.Free;
     end;
     FPrevShadow := true;
-    FPrevShadowRadius := Manager.ToolTextBlur;
-    FPrevShadowOffset := Manager.ToolTextShadowOffset;
+    FPrevShadowRadius := Manager.TextShadowBlurRadius;
+    FPrevShadowOffset := Manager.TextShadowOffset;
   end else
   begin
     inherited DrawCustomShape(ADest, AMatrix, ADraft);
@@ -133,7 +133,7 @@ var
   posF: TPointF;
 begin
   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));
   IncludeShadowBounds(r);
   inherited ShapeChange(ASender, RectF(r.Left,r.Top,r.Right,r.Bottom), ADiff);
@@ -156,40 +156,40 @@ begin
   with TTextShape(FShape) do
   begin
     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
     begin
       if FSwapColor then
-        FShape.PenFill.SetSolid(Manager.ToolBackColor)
+        FShape.PenFill.SetSolid(Manager.BackColor)
       else
-        FShape.PenFill.SetSolid(Manager.ToolForeColor);
+        FShape.PenFill.SetSolid(Manager.ForeColor);
     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
       if FSwapColor then
-        FShape.OutlineFill.SetSolid(Manager.ToolForeColor)
+        FShape.OutlineFill.SetSolid(Manager.ForeColor)
       else
-        FShape.OutlineFill.SetSolid(Manager.ToolBackColor);
-      OutlineWidth := Manager.ToolTextOutlineWidth;
+        FShape.OutlineFill.SetSolid(Manager.BackColor);
+      OutlineWidth := Manager.TextOutlineWidth;
     end
     else
       OutlineFill.Clear;
 
-    LightPosition := AMatrix*Manager.ToolLightPosition;
-    AltitudePercent:= Manager.ToolShapeAltitude;
+    LightPosition := AMatrix*Manager.LightPosition;
+    AltitudePercent:= Manager.PhongShapeAltitude;
     ParagraphAlignment:= Manager.ToolTextAlign;
-    PenPhong := Manager.ToolTextPhong;
+    PenPhong := Manager.TextPhong;
   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
     toolDest := GetToolDrawingLayer;
     r:= UpdateShape(toolDest);
@@ -220,8 +220,8 @@ end;
 
 function TToolText.GetContextualToolbars: TContextualToolbars;
 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;
 
 function TToolText.ToolKeyDown(var key: Word): TRect;

+ 431 - 92
lazpaint/tools/utoolvectorial.pas

@@ -6,8 +6,14 @@ interface
 
 uses
   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
   { TVectorialTool }
@@ -75,25 +81,25 @@ type
   { TEditShapeTool }
 
   TEditShapeTool = class(TGenericTool)
-  private
-    procedure SelectShape({%H-}ASender: TObject; AShape: TVectorShape;
-      {%H-}APreviousShape: TVectorShape);
   protected
     FShiftState: TShiftState;
-    FLeftButton,FRightButton: boolean;
+    FDownHandled,FLeftButton,FRightButton: boolean;
     FLastPos: TPointF;
     FOriginalRect: TRectShape;
     FOriginalRectUntransformed: TRectF;
     FOriginalRectEditor: TBGRAOriginalEditor;
     FIsEditingGradient: boolean;
+    procedure RetrieveLightPosition;
+    procedure UpdateToolManagerFromShape(AShape: TVectorShape);
     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 DoToolMove({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; {%H-}ptF: TPointF): TRect; override;
     function DoToolUpdate({%H-}toolDest: TBGRABitmap): TRect; override;
     function GetAction: TLayerAction; override;
     function DoGetToolDrawingLayer: TBGRABitmap; override;
     procedure OnTryStop({%H-}sender: TCustomLayerAction); override;
-    procedure StopEdit;
+    procedure StopEdit(AUpdateToolbars: boolean);
     function IsVectorOriginal: boolean;
     function IsGradientOriginal: boolean;
     function IsOtherOriginal: boolean;
@@ -102,10 +108,15 @@ type
     procedure UpdateOriginalMatrixFromRect;
     function GetIsSelectingTool: boolean; override;
     function GetVectorOriginal: TVectorOriginal;
+    function GetGradientOriginal: TBGRALayerGradientOriginal;
     function FixLayerOffset: boolean; override;
+    function GetCurrentSplineMode: TToolSplineMode;
+    procedure SetCurrentSplineMode(AMode: TToolSplineMode);
+    function IsGradientShape(AShape: TVectorShape): boolean;
   public
     constructor Create(AManager: TToolManager); override;
     destructor Destroy; override;
+    function GetContextualToolbars: TContextualToolbars; override;
     function Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth, VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect; override;
     function ToolKeyDown(var key: Word): TRect; override;
     function ToolKeyPress(var key: TUTF8Char): TRect; override;
@@ -117,13 +128,14 @@ type
     function ToolProvideCopy: boolean; override;
     function ToolProvideCut: boolean; override;
     function ToolProvidePaste: boolean; override;
+    property CurrentSplineMode: TToolSplineMode read GetCurrentSplineMode write SetCurrentSplineMode;
   end;
 
 implementation
 
-uses LazPaintType, LCVectorTextShapes, LCVectorialFill, BGRASVGOriginal,
+uses LazPaintType, LCVectorPolyShapes, LCVectorTextShapes, LCVectorialFill, BGRASVGOriginal,
   ULoading, BGRATransform, math, UStateType, UImageDiff, Controls, BGRAPen, UResourceStrings, ugraph,
-  LCScaleDPI, LCVectorClipboard, BGRAGradientOriginal;
+  LCScaleDPI, LCVectorClipboard, BGRAGradientScanner;
 
 const PointSize = 6;
 
@@ -145,32 +157,183 @@ begin
   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 }
 
 procedure TEditShapeTool.SelectShape(ASender: TObject; AShape: TVectorShape;
   APreviousShape: TVectorShape);
 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
-    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
-      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
     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;
+
+  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;
 
 procedure TEditShapeTool.BindOriginalEvent(ABind: boolean);
@@ -212,11 +375,21 @@ begin
   FRightButton:= rightBtn;
   FLeftButton:= not rightBtn;
   FLastPos := ptF;
+  handled := false;
   if IsVectorOriginal or IsGradientOriginal then
   begin
-    if not FIsEditingGradient then
+    if IsGradientOriginal and not FIsEditingGradient then
     begin
       FIsEditingGradient:= true;
+      with GetGradientOriginal do
+      begin
+        Manager.ForeColor := StartColor;
+        Manager.BackColor := EndColor;
+        Manager.GradientType := GradientType;
+        Manager.GradientSine := (Repetition = grSine);
+        Manager.GradientColorspace := ColorInterpolation;
+      end;
+      Manager.UpdateContextualToolbars;
       result := OnlyRenderChange;
     end else
     begin
@@ -246,6 +419,7 @@ begin
           FOriginalRect.Origin := (box.TopLeft+box.BottomRight)*0.5;
           FOriginalRect.XAxis := FOriginalRect.Origin+(box.TopRight-box.TopLeft)*0.5;
           FOriginalRect.YAxis := FOriginalRect.Origin+(box.BottomLeft-box.TopLeft)*0.5;
+          Manager.UpdateContextualToolbars;
         end;
         result := OnlyRenderChange;
       end;
@@ -261,10 +435,11 @@ begin
           result := OnlyRenderChange;
           UpdateOriginalMatrixFromRect;
         end else
-          StopEdit;
+          StopEdit(true);
       end;
     end;
   end;
+  FDownHandled:= handled;
 end;
 
 function TEditShapeTool.DoToolMove(toolDest: TBGRABitmap; pt: TPoint;
@@ -297,72 +472,153 @@ begin
 end;
 
 function TEditShapeTool.DoToolUpdate(toolDest: TBGRABitmap): TRect;
+var
+  doDraw, doFill: Boolean;
+  m: TAffineMatrix;
+  zoom: Single;
 begin
   if IsVectorOriginal then
   with GetVectorOriginal do
   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);
     if Assigned(SelectedShape) then
     begin
-      if (vsfBackFill in SelectedShape.Fields) and (SelectedShape.BackFill.FillType = vftGradient) then
+      if IsGradientShape(SelectedShape) then
       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
-          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 else
       begin
-        if Assigned(Manager.GetToolTexture) then
+        if SelectedShape.Fields*[vsfPenFill,vsfBackFill,vsfPenStyle] = [vsfPenFill,vsfBackFill,vsfPenStyle] then
         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
-              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;
-          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
-              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 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
-          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;
     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;
   Result := EmptyRect;
 end;
@@ -379,11 +635,11 @@ end;
 
 procedure TEditShapeTool.OnTryStop(sender: TCustomLayerAction);
 begin
-  StopEdit;
+  StopEdit(True);
   inherited OnTryStop(sender);
 end;
 
-procedure TEditShapeTool.StopEdit;
+procedure TEditShapeTool.StopEdit(AUpdateToolbars: boolean);
 var
   r: TRect;
 begin
@@ -399,6 +655,7 @@ begin
   FreeAndNil(FOriginalRectEditor);
   Cursor := crDefault;
   Manager.Image.OnImageChanged.NotifyObservers;
+  if AUpdateToolbars then Manager.UpdateContextualToolbars;
 end;
 
 function TEditShapeTool.IsVectorOriginal: boolean;
@@ -468,22 +725,49 @@ begin
   result := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal;
 end;
 
-function TEditShapeTool.FixLayerOffset: boolean;
+function TEditShapeTool.GetGradientOriginal: TBGRALayerGradientOriginal;
 begin
-  Result:= false;
+  result := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TBGRALayerGradientOriginal;
 end;
 
-constructor TEditShapeTool.Create(AManager: TToolManager);
+function TEditShapeTool.FixLayerOffset: boolean;
 begin
-  inherited Create(AManager);
+  Result:= false;
 end;
 
 destructor TEditShapeTool.Destroy;
 begin
-  StopEdit;
+  StopEdit(False);
   inherited Destroy;
 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,
   VirtualScreenHeight: integer;
   BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;
@@ -508,6 +792,7 @@ begin
       result := Manager.Image.CurrentState.LayeredBitmap.GetEditorBounds(
         rect(0,0,VirtualScreenWidth,VirtualScreenHeight),
         Manager.Image.CurrentLayerIndex, viewMatrix, DoScaleX(PointSize,OriginalDPI));
+    RetrieveLightPosition;
   end else
   begin
     result := EmptyRect;
@@ -534,6 +819,54 @@ begin
   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;
 var
   handled: boolean;
@@ -559,17 +892,21 @@ begin
     begin
       BindOriginalEvent(true);
       Manager.Image.CurrentState.LayeredBitmap.KeyDown(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
+      if handled then key := 0;
       if not handled and IsVectorOriginal then
       begin
         if (key = VK_DELETE) and Assigned(GetVectorOriginal.SelectedShape) then
+        begin
           GetVectorOriginal.RemoveShape(GetVectorOriginal.SelectedShape);
+          key := 0;
+        end;
       end;
       BindOriginalEvent(false);
     end else
     begin
       if key = VK_RETURN then
       begin
-        StopEdit;
+        StopEdit(true);
         key := 0;
       end;
     end;
@@ -585,6 +922,7 @@ begin
   begin
     BindOriginalEvent(true);
     Manager.Image.CurrentState.LayeredBitmap.KeyPress(key, handled);
+    if handled then key := #0;
     BindOriginalEvent(false);
   end;
 end;
@@ -614,6 +952,7 @@ begin
     begin
       BindOriginalEvent(true);
       Manager.Image.CurrentState.LayeredBitmap.KeyUp(FShiftState, LCLKeyToSpecialKey(key, FShiftState), handled);
+      if handled then key := 0;
       BindOriginalEvent(false);
     end;
   end;
@@ -640,7 +979,7 @@ begin
         Cursor := OriginalCursorToCursor(cur);
         result := OnlyRenderChange;
       end;
-      if not handled and IsVectorOriginal then
+      if not handled and not FDownHandled and IsVectorOriginal then
       begin
         m := AffineMatrixInverse(Manager.Image.LayerOriginalMatrix[Manager.Image.CurrentLayerIndex]);
         GetVectorOriginal.MouseClick(m*FLastPos);
@@ -934,35 +1273,35 @@ begin
   f:= FShape.Fields;
   if vsfPenFill in f then
   begin
-    if Manager.ToolOptionDrawShape then
+    if Manager.ShapeOptionDraw then
     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
       begin
         if FSwapColor then
-          FShape.PenFill.SetSolid(Manager.ToolBackColor)
+          FShape.PenFill.SetSolid(Manager.BackColor)
         else
-          FShape.PenFill.SetSolid(Manager.ToolForeColor);
+          FShape.PenFill.SetSolid(Manager.ForeColor);
       end;
     end else
       FShape.PenFill.Clear;
   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
   begin
-    if Manager.ToolOptionFillShape then
+    if Manager.ShapeOptionFill then
     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
       begin
         if FSwapColor then
-          FShape.BackFill.SetSolid(Manager.ToolForeColor)
+          FShape.BackFill.SetSolid(Manager.ForeColor)
         else
-          FShape.BackFill.SetSolid(Manager.ToolBackColor);
+          FShape.BackFill.SetSolid(Manager.BackColor);
       end;
     end else
       FShape.BackFill.Clear;
@@ -976,7 +1315,7 @@ end;
 
 function TVectorialTool.RoundCoordinate(ptF: TPointF): TPointF;
 begin
-  if not Manager.ToolOptionDrawShape or
+  if not Manager.ShapeOptionDraw or
     (Assigned(FShape) and not (vsfPenFill in FShape.Fields)) then
     result := PointF(floor(ptF.x)+0.5,floor(ptF.y)+0.5)
   else

+ 33 - 14
lazpaint/uconfig.pas

@@ -6,7 +6,7 @@ interface
 
 uses
   Classes, SysUtils, IniFiles, BGRABitmapTypes, Graphics, LCLType, uscripting,
-  Forms;
+  Forms, LCVectorRectShapes;
 
 type
   TLazPaintConfig = class;
@@ -203,7 +203,7 @@ type
     function DefaultToolTextShadow: boolean;
     procedure SetDefaultToolTextShadow(value: boolean);
     function DefaultToolTextFont: TFont;
-    procedure SetDefaultToolTextFont(value: TFont);
+    procedure SetDefaultToolTextFont(AFont: TFont);
     function DefaultToolTextBlur: single;
     procedure SetDefaultToolTextBlur(value: single);
     function DefaultToolTextShadowOffsetX: integer;
@@ -230,8 +230,8 @@ type
     procedure SetDefaultToolShapeAltitude(value: integer);
     function DefaultToolShapeBorderSize: integer;
     procedure SetDefaultToolShapeBorderSize(value: integer);
-    function DefaultToolShapeType: string;
-    procedure SetDefaultToolShapeType(value: string);
+    function DefaultToolShapeType: TPhongShapeKind;
+    procedure SetDefaultToolShapeType(value: TPhongShapeKind);
 
     function DefaultRetrieveSelectionAnswer: TModalResult;
     procedure SetDefaultRetrieveSelectionAnswer(value: TModalResult);
@@ -855,8 +855,7 @@ function TLazPaintConfig.DefaultToolTextFont: TFont;
 var fontStyle: TFontStyles;
 begin
   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 := [];
   if iniOptions.ReadBool('Tool','TextFontBold',False) then fontStyle += [fsBold];
   if iniOptions.ReadBool('Tool','TextFontItalic',False) then fontStyle += [fsItalic];
@@ -866,13 +865,13 @@ begin
   result := tempFont;
 end;
 
-procedure TLazPaintConfig.SetDefaultToolTextFont(value: TFont);
+procedure TLazPaintConfig.SetDefaultToolTextFont(AFont: TFont);
 begin
-  tempFont.Assign(value);
+  tempFont.Assign(AFont);
 
   iniOptions.WriteString('Tool','TextFontName',tempFont.Name);
   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','TextFontItalic',fsItalic in tempFont.Style);
   iniOptions.WriteBool('Tool','TextFontStrikeOut',fsStrikeOut in tempFont.Style);
@@ -1002,14 +1001,34 @@ begin
   iniOptions.WriteInteger('Filter','ShapeBorderSize',value);
 end;
 
-function TLazPaintConfig.DefaultToolShapeType: string;
+function TLazPaintConfig.DefaultToolShapeType: TPhongShapeKind;
+var
+  str: String;
 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;
 
-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;
 
 function TLazPaintConfig.DefaultRetrieveSelectionAnswer: TModalResult;

+ 2 - 2
lazpaint/ufilters.pas

@@ -175,12 +175,12 @@ begin
     pfClouds:
       begin
         filteredLayer := layer.Duplicate as TBGRABitmap;
-        RenderCloudsOn(filteredLayer,AInstance.ToolManager.ToolForeColor);
+        RenderCloudsOn(filteredLayer,AInstance.ToolManager.ForeColor);
       end;
     pfCustomWater:
     begin
       filteredLayer := layer.Duplicate as TBGRABitmap;
-      RenderWaterOn(filteredLayer,AInstance.ToolManager.ToolForeColor,AInstance.ToolManager.ToolBackColor);
+      RenderWaterOn(filteredLayer,AInstance.ToolManager.ForeColor,AInstance.ToolManager.BackColor);
     end;
     pfWater: filteredLayer := CreateWaterTexture(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
   begin
     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;
   result.rx := (br.x-tl.x)/2-0.5;
   result.ry := (br.y-tl.y)/2-0.5;
@@ -515,7 +515,7 @@ var virtualScreenPenCursorBefore: boolean;
   function UseVSPenCursor: boolean;
   begin
     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
     begin
       FPenCursorVisible := True;

+ 4 - 4
lazpaint/upalettetoolbar.pas

@@ -626,14 +626,14 @@ begin
     if (ssLeft in Shift) and not (ssRight in Shift) then
     begin
       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
     if not (ssLeft in Shift) and (ssRight in Shift) then
     begin
       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
         exit;
     LazPaintInstance.UpdateToolbar;

+ 49 - 3
lazpaintcontrols/lcvectorpolyshapes.pas

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

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff