Przeglądaj źródła

Merge pull request #36 from bgrabitmap/dev-lazpaint

Dev lazpaint 7.0.3
circular17 6 lat temu
rodzic
commit
623de59e9a
100 zmienionych plików z 998 dodań i 242 usunięć
  1. 14 0
      .gitignore
  2. 7 0
      lazpaint.logic
  3. BIN
      lazpaint/buttons/aliasing.png
  4. BIN
      lazpaint/buttons/aliasing48.png
  5. BIN
      lazpaint/buttons/editobj.png
  6. BIN
      lazpaint/buttons/editobj48.lzp
  7. BIN
      lazpaint/buttons/editobj48.png
  8. BIN
      lazpaint/buttons/movedown.png
  9. BIN
      lazpaint/buttons/movedown48.png
  10. BIN
      lazpaint/buttons/movetoback.png
  11. BIN
      lazpaint/buttons/movetoback48.png
  12. BIN
      lazpaint/buttons/movetofront.png
  13. BIN
      lazpaint/buttons/movetofront48.png
  14. BIN
      lazpaint/buttons/moveup.png
  15. BIN
      lazpaint/buttons/moveup48.png
  16. BIN
      lazpaint/buttons/nodeformation.png
  17. BIN
      lazpaint/buttons/notexture.png
  18. BIN
      lazpaint/buttons/notexture48.png
  19. BIN
      lazpaint/buttons/redo.png
  20. BIN
      lazpaint/buttons/text.png
  21. BIN
      lazpaint/buttons/text48.png
  22. BIN
      lazpaint/buttons/textfont.png
  23. BIN
      lazpaint/buttons/textfont48.png
  24. BIN
      lazpaint/buttons/textoutline.png
  25. BIN
      lazpaint/buttons/textoutline48.png
  26. BIN
      lazpaint/buttons/textshadow.png
  27. BIN
      lazpaint/buttons/textshadow48.png
  28. BIN
      lazpaint/buttons/undo.png
  29. BIN
      lazpaint/buttons/zoomoriginal.png
  30. BIN
      lazpaint/buttons/zoomoriginal48.png
  31. 0 25
      lazpaint/deb/how_to_make_deb.txt
  32. 0 12
      lazpaint/deb/lazpaint_linux32/DEBIAN/changelog
  33. 0 11
      lazpaint/deb/lazpaint_linux64/DEBIAN/changelog
  34. 0 0
      lazpaint/dialog/color/uadjustcurves.lfm
  35. 0 0
      lazpaint/dialog/color/uadjustcurves.pas
  36. 0 0
      lazpaint/dialog/color/ucolorintensity.lfm
  37. 0 0
      lazpaint/dialog/color/ucolorintensity.pas
  38. 0 0
      lazpaint/dialog/color/ucolorize.lfm
  39. 0 0
      lazpaint/dialog/color/ucolorize.pas
  40. 0 0
      lazpaint/dialog/color/ushiftcolors.lfm
  41. 0 0
      lazpaint/dialog/color/ushiftcolors.pas
  42. 0 0
      lazpaint/dialog/filter/ucustomblur.lfm
  43. 0 0
      lazpaint/dialog/filter/ucustomblur.pas
  44. 0 0
      lazpaint/dialog/filter/uemboss.lfm
  45. 0 0
      lazpaint/dialog/filter/uemboss.pas
  46. 0 0
      lazpaint/dialog/filter/ufilterfunction.lfm
  47. 0 0
      lazpaint/dialog/filter/ufilterfunction.pas
  48. 0 0
      lazpaint/dialog/filter/uformrain.lfm
  49. 0 0
      lazpaint/dialog/filter/uformrain.pas
  50. 0 0
      lazpaint/dialog/filter/umotionblur.lfm
  51. 0 0
      lazpaint/dialog/filter/umotionblur.pas
  52. 0 0
      lazpaint/dialog/filter/unoisefilter.lfm
  53. 0 0
      lazpaint/dialog/filter/unoisefilter.pas
  54. 0 0
      lazpaint/dialog/filter/uphongfilter.lfm
  55. 13 9
      lazpaint/dialog/filter/uphongfilter.pas
  56. 0 0
      lazpaint/dialog/filter/upixelate.lfm
  57. 0 0
      lazpaint/dialog/filter/upixelate.pas
  58. 0 0
      lazpaint/dialog/filter/uposterize.lfm
  59. 0 0
      lazpaint/dialog/filter/uposterize.pas
  60. 0 0
      lazpaint/dialog/filter/uradialblur.lfm
  61. 0 0
      lazpaint/dialog/filter/uradialblur.pas
  62. 0 0
      lazpaint/dialog/filter/usharpen.lfm
  63. 0 0
      lazpaint/dialog/filter/usharpen.pas
  64. 58 39
      lazpaint/dialog/filter/utwirl.lfm
  65. 1 1
      lazpaint/dialog/filter/utwirl.pas
  66. 174 0
      lazpaint/dialog/filter/uwavedisplacement.lfm
  67. 183 0
      lazpaint/dialog/filter/uwavedisplacement.pas
  68. 0 0
      lazpaint/dialog/uabout.lfm
  69. 0 0
      lazpaint/dialog/uabout.pas
  70. 0 0
      lazpaint/dialog/ublendop.lfm
  71. 0 0
      lazpaint/dialog/ublendop.pas
  72. 180 77
      lazpaint/dialog/ubrowseimages.lfm
  73. 6 5
      lazpaint/dialog/ubrowseimages.pas
  74. 0 0
      lazpaint/dialog/ucanvassize.lfm
  75. 0 0
      lazpaint/dialog/ucanvassize.pas
  76. 0 0
      lazpaint/dialog/ugeometricbrush.lfm
  77. 0 0
      lazpaint/dialog/ugeometricbrush.pas
  78. 0 0
      lazpaint/dialog/umultiimage.lfm
  79. 0 0
      lazpaint/dialog/umultiimage.pas
  80. 0 0
      lazpaint/dialog/unewimage.lfm
  81. 0 0
      lazpaint/dialog/unewimage.pas
  82. 0 0
      lazpaint/dialog/uobject3d.lfm
  83. 0 0
      lazpaint/dialog/uobject3d.pas
  84. 0 0
      lazpaint/dialog/upreviewdialog.lfm
  85. 0 0
      lazpaint/dialog/upreviewdialog.pas
  86. 0 0
      lazpaint/dialog/uprint.lfm
  87. 0 0
      lazpaint/dialog/uprint.pas
  88. 0 0
      lazpaint/dialog/uquestion.lfm
  89. 0 0
      lazpaint/dialog/uquestion.pas
  90. 0 0
      lazpaint/dialog/uresample.lfm
  91. 0 0
      lazpaint/dialog/uresample.pas
  92. 0 0
      lazpaint/dialog/usaveoption.lfm
  93. 0 0
      lazpaint/dialog/usaveoption.pas
  94. 41 1
      lazpaint/image/uimage.pas
  95. 35 26
      lazpaint/image/uimageaction.pas
  96. 243 35
      lazpaint/image/uimagediff.pas
  97. 0 0
      lazpaint/image/uimageobservation.pas
  98. 38 0
      lazpaint/image/uimagestate.pas
  99. 0 0
      lazpaint/image/uimagetype.pas
  100. 5 1
      lazpaint/image/ulayeraction.pas

+ 14 - 0
.gitignore

@@ -18,3 +18,17 @@ vectoredit/vectoredit
 vectoredit/backup/
 
 lazpaint/release/lazpaint
+
+lazpaint/test_embedded/backup/
+
+lazpaint/test_embedded/project1
+
+lazpaint/dialog/filter/backup/
+
+lazpaint/release/bin/lazpaint
+
+lazpaint/tools/backup/
+
+lazpaint/image/backup/
+
+lazpaint/dialog/backup/

+ 7 - 0
lazpaint.logic

@@ -2,4 +2,11 @@ cd ($LogicDir)/lazpaint
 project lazpaint.lpi
 package lazpaintembeddedpack.lpk
 const lazpainttype.pas LazPaintVersion
+text release/windows/lazpaint.iss "#define MyAppVersion ""$(Version)"""
+text release/debian/linux32/DEBIAN/control "Version: $(Version)"
+text release/debian/linux64/DEBIAN/control "Version: $(Version)"
+echo "Don't forget to UPDATE changelog file"
+copy release/changelog release/debian/linux32/DEBIAN/changelog
+copy release/changelog release/debian/linux64/DEBIAN/changelog
+text release/macOS/makedmg.sh "appversion=$(Version)"
 

BIN
lazpaint/buttons/aliasing.png


BIN
lazpaint/buttons/aliasing48.png


BIN
lazpaint/buttons/editobj.png


BIN
lazpaint/buttons/editobj48.lzp


BIN
lazpaint/buttons/editobj48.png


BIN
lazpaint/buttons/movedown.png


BIN
lazpaint/buttons/movedown48.png


BIN
lazpaint/buttons/movetoback.png


BIN
lazpaint/buttons/movetoback48.png


BIN
lazpaint/buttons/movetofront.png


BIN
lazpaint/buttons/movetofront48.png


BIN
lazpaint/buttons/moveup.png


BIN
lazpaint/buttons/moveup48.png


BIN
lazpaint/buttons/nodeformation.png


BIN
lazpaint/buttons/notexture.png


BIN
lazpaint/buttons/notexture48.png


BIN
lazpaint/buttons/redo.png


BIN
lazpaint/buttons/text.png


BIN
lazpaint/buttons/text48.png


BIN
lazpaint/buttons/textfont.png


BIN
lazpaint/buttons/textfont48.png


BIN
lazpaint/buttons/textoutline.png


BIN
lazpaint/buttons/textoutline48.png


BIN
lazpaint/buttons/textshadow.png


BIN
lazpaint/buttons/textshadow48.png


BIN
lazpaint/buttons/undo.png


BIN
lazpaint/buttons/zoomoriginal.png


BIN
lazpaint/buttons/zoomoriginal48.png


+ 0 - 25
lazpaint/deb/how_to_make_deb.txt

@@ -1,25 +0,0 @@
-0) Copy this folder 'deb' somewhere, maybe in your /home/lainz/Documentos/. Replace 'lainz' with your username.
-
-1) Change the version number in the file lazpaint_linux[32/64]/debian/control with a text editor, ensure that has the proper architecture (i386 / amd64 / all).
-
-2) Update the changelog with the differences with previous version
-
-3) Copy binary, models, i18n and readme in the folder /usr/share/lazpaint.
-
-4) Right click in the folder 'deb' and open terminal, then run this command:
-- A) dpkg-deb --build lazpaint_linux32
-- B) dpkg-deb --build lazpaint_linux64
-
-Note: if you have folder permissions wrong try this:
-  chmod -R 775 /home/lainz/Documentos/deb
-
-5) Change the name of the deb file to include version:
-- A) lazpaint_linux32.deb to lazpaint_6.4.1_linux32.deb
-- B) lazpaint_linux64.deb to lazpaint_6.4.1_linux64.deb
-
-6) Test the package:
-- A) sudo dpkg -i lazpaint_6.4.1_linux32.deb
-- B) sudo dpkg -i lazpaint_6.4.1_linux64.deb
-
-7) To remove the package:
-- sudo dpkg -r lazpaint

+ 0 - 12
lazpaint/deb/lazpaint_linux32/DEBIAN/changelog

@@ -1,12 +0,0 @@
-lazpaint (7.0.2) unstable; urgency=low
-
-  * bug fixes with tools and undo
-  * better drive detection
-  * improvements on layer stack interface
-  * layers can be rasterized and their bounds are shown when transforming them
-  * text tool stable word warp, unicode arabic ligatures and non-spacing marks
-  * polyline/curve tool is now vectorial
-  * faster rendering in draft mode (when editing)
-
--- circular <[email protected]>  Sat, 27 Jul 2019 22:23:00 +0100
-

+ 0 - 11
lazpaint/deb/lazpaint_linux64/DEBIAN/changelog

@@ -1,11 +0,0 @@
-lazpaint (7.0.2) unstable; urgency=low
-
-  * bug fixes with tools and undo
-  * better drive detection
-  * improvements on layer stack interface
-  * layers can be rasterized and their bounds are shown when transforming them
-  * text tool stable word warp, unicode arabic ligatures and non-spacing marks
-  * polyline/curve tool is now vectorial
-  * faster rendering in draft mode (when editing)
-
--- circular <[email protected]>  Sat, 27 Jul 2019 22:23:00 +0100

+ 0 - 0
lazpaint/uadjustcurves.lfm → lazpaint/dialog/color/uadjustcurves.lfm


+ 0 - 0
lazpaint/uadjustcurves.pas → lazpaint/dialog/color/uadjustcurves.pas


+ 0 - 0
lazpaint/ucolorintensity.lfm → lazpaint/dialog/color/ucolorintensity.lfm


+ 0 - 0
lazpaint/ucolorintensity.pas → lazpaint/dialog/color/ucolorintensity.pas


+ 0 - 0
lazpaint/ucolorize.lfm → lazpaint/dialog/color/ucolorize.lfm


+ 0 - 0
lazpaint/ucolorize.pas → lazpaint/dialog/color/ucolorize.pas


+ 0 - 0
lazpaint/ushiftcolors.lfm → lazpaint/dialog/color/ushiftcolors.lfm


+ 0 - 0
lazpaint/ushiftcolors.pas → lazpaint/dialog/color/ushiftcolors.pas


+ 0 - 0
lazpaint/ucustomblur.lfm → lazpaint/dialog/filter/ucustomblur.lfm


+ 0 - 0
lazpaint/ucustomblur.pas → lazpaint/dialog/filter/ucustomblur.pas


+ 0 - 0
lazpaint/uemboss.lfm → lazpaint/dialog/filter/uemboss.lfm


+ 0 - 0
lazpaint/uemboss.pas → lazpaint/dialog/filter/uemboss.pas


+ 0 - 0
lazpaint/ufilterfunction.lfm → lazpaint/dialog/filter/ufilterfunction.lfm


+ 0 - 0
lazpaint/ufilterfunction.pas → lazpaint/dialog/filter/ufilterfunction.pas


+ 0 - 0
lazpaint/uformrain.lfm → lazpaint/dialog/filter/uformrain.lfm


+ 0 - 0
lazpaint/uformrain.pas → lazpaint/dialog/filter/uformrain.pas


+ 0 - 0
lazpaint/umotionblur.lfm → lazpaint/dialog/filter/umotionblur.lfm


+ 0 - 0
lazpaint/umotionblur.pas → lazpaint/dialog/filter/umotionblur.pas


+ 0 - 0
lazpaint/unoisefilter.lfm → lazpaint/dialog/filter/unoisefilter.lfm


+ 0 - 0
lazpaint/unoisefilter.pas → lazpaint/dialog/filter/unoisefilter.pas


+ 0 - 0
lazpaint/uphongfilter.lfm → lazpaint/dialog/filter/uphongfilter.lfm


+ 13 - 9
lazpaint/uphongfilter.pas → lazpaint/dialog/filter/uphongfilter.pas

@@ -51,6 +51,7 @@ type
     FInitializing: boolean;
     FCenter: TPointF;
     FHeightMap: TBGRABitmap;
+    FWorkspaceColor: TColor;
     function GetCurrentLightPos: TPointF;
     procedure PreviewNeeded;
     function ComputeFilteredLayer: TBGRABitmap;
@@ -72,6 +73,7 @@ begin
   result := false;
   FPhongFilter:= TFPhongFilter.create(nil);
   FPhongFilter.FilterConnector := AFilterConnector as TFilterConnector;
+  FPhongFilter.FWorkspaceColor:= FPhongFilter.FilterConnector.LazPaintInstance.Config.GetWorkspaceColor;
   try
     if FPhongFilter.FilterConnector.ActiveLayer <> nil then
       result:= (FPhongFilter.showModal = mrOk)
@@ -88,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;
 
@@ -97,6 +99,7 @@ begin
   ScaleControl(Self,OriginalDPI);
   CheckOKCancelBtns(Button_OK,Button_Cancel);
   FCenter := PointF(0.5,0.5);
+  FWorkspaceColor:= clAppWorkspace;
 end;
 
 procedure TFPhongFilter.FormDestroy(Sender: TObject);
@@ -108,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;
@@ -144,9 +147,10 @@ var x,y: integer;
 begin
   x := round((FCenter.X+0.5)*PaintBox1.Width/2);
   y := round((FCenter.Y+0.5)*PaintBox1.Height/2);
-  PaintBox1.Canvas.Brush.Style := bsClear;
+  PaintBox1.Canvas.Brush.Style := bsSolid;
+  PaintBox1.Canvas.Brush.Color := FWorkspaceColor;
   PaintBox1.Canvas.Pen.Style := psSolid;
-  PaintBox1.Canvas.Pen.Color := BGRAToColor(MergeBGRA(ColorToBGRA(ColorToRGB(clBlack)),ColorToBGRA(OutsideColor)));
+  PaintBox1.Canvas.Pen.Color := MergeBGRA(ColorToBGRA(clBlack),ColorToBGRA(FWorkspaceColor));
   PaintBox1.Canvas.Rectangle(0,0,PaintBox1.Width,PaintBox1.Height);
   PaintBox1.Canvas.Pen.Style := psDot;
   PaintBox1.Canvas.Pen.Color := clBlack;
@@ -294,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
@@ -325,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;

+ 0 - 0
lazpaint/upixelate.lfm → lazpaint/dialog/filter/upixelate.lfm


+ 0 - 0
lazpaint/upixelate.pas → lazpaint/dialog/filter/upixelate.pas


+ 0 - 0
lazpaint/uposterize.lfm → lazpaint/dialog/filter/uposterize.lfm


+ 0 - 0
lazpaint/uposterize.pas → lazpaint/dialog/filter/uposterize.pas


+ 0 - 0
lazpaint/uradialblur.lfm → lazpaint/dialog/filter/uradialblur.lfm


+ 0 - 0
lazpaint/uradialblur.pas → lazpaint/dialog/filter/uradialblur.pas


+ 0 - 0
lazpaint/usharpen.lfm → lazpaint/dialog/filter/usharpen.lfm


+ 0 - 0
lazpaint/usharpen.pas → lazpaint/dialog/filter/usharpen.pas


+ 58 - 39
lazpaint/utwirl.lfm → lazpaint/dialog/filter/utwirl.lfm

@@ -1,8 +1,8 @@
 object FTwirl: TFTwirl
   Left = 631
-  Height = 217
+  Height = 288
   Top = 173
-  Width = 148
+  Width = 173
   AutoSize = True
   BorderIcons = [biSystemMenu]
   BorderStyle = bsDialog
@@ -13,113 +13,132 @@ object FTwirl: TFTwirl
   ChildSizing.VerticalSpacing = 8
   ChildSizing.Layout = cclLeftToRightThenTopToBottom
   ChildSizing.ControlsPerLine = 1
-  ClientHeight = 217
-  ClientWidth = 148
-  Font.Height = -12
+  ClientHeight = 288
+  ClientWidth = 173
+  DesignTimePPI = 120
+  Font.Height = -15
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   OnShow = FormShow
   Position = poScreenCenter
-  LCLVersion = '1.6.0.4'
+  LCLVersion = '2.0.2.0'
   object Panel1: TPanel
     Left = 8
-    Height = 54
+    Height = 76
     Top = 8
-    Width = 114
+    Width = 143
     BevelOuter = bvNone
     ChildSizing.HorizontalSpacing = 8
     ChildSizing.VerticalSpacing = 8
     ChildSizing.Layout = cclLeftToRightThenTopToBottom
     ChildSizing.ControlsPerLine = 2
-    ClientHeight = 54
-    ClientWidth = 114
+    ClientHeight = 76
+    ClientWidth = 143
+    Font.Height = -15
+    ParentFont = False
     TabOrder = 0
     object Label_Radius: TLabel
       Left = 0
-      Height = 23
+      Height = 34
       Top = 0
-      Width = 41
+      Width = 54
       Caption = 'Radius :'
+      Font.Height = -15
       Layout = tlCenter
       ParentColor = False
+      ParentFont = False
     end
     object SpinEdit_Radius: TSpinEdit
-      Left = 49
-      Height = 23
+      Left = 62
+      Height = 34
       Top = 0
-      Width = 65
-      Constraints.MinWidth = 65
+      Width = 81
+      Constraints.MinWidth = 81
+      Font.Height = -15
       Increment = 10
       MaxValue = 10000
       MinValue = 1
       OnChange = SpinEdit_RadiusChange
+      ParentFont = False
       TabOrder = 0
       Value = 100
     end
     object Label_Angle: TLabel
       Left = 0
-      Height = 23
-      Top = 31
-      Width = 41
+      Height = 34
+      Top = 42
+      Width = 54
       Caption = 'Angle :'
+      Font.Height = -15
       Layout = tlCenter
       ParentColor = False
+      ParentFont = False
     end
     object SpinEdit_Angle: TSpinEdit
-      Left = 49
-      Height = 23
-      Top = 31
-      Width = 65
-      Constraints.MinWidth = 65
+      Left = 62
+      Height = 34
+      Top = 42
+      Width = 81
+      Constraints.MinWidth = 81
+      Font.Height = -15
       Increment = 30
       MaxValue = 10000
       MinValue = 1
       OnChange = SpinEdit_AngleChange
+      ParentFont = False
       TabOrder = 1
       Value = 360
     end
   end
   object PaintBox1: TPaintBox
     Left = 8
-    Height = 105
-    Top = 70
-    Width = 114
+    Height = 131
+    Top = 92
+    Width = 143
+    Font.Height = -15
+    ParentFont = False
     OnMouseDown = PaintBox1MouseDown
     OnMouseMove = PaintBox1MouseMove
     OnPaint = PaintBox1Paint
   end
   object Panel2: TPanel
     Left = 8
-    Height = 25
-    Top = 183
-    Width = 114
+    Height = 36
+    Top = 231
+    Width = 143
     BevelOuter = bvNone
     ChildSizing.HorizontalSpacing = 8
     ChildSizing.Layout = cclLeftToRightThenTopToBottom
     ChildSizing.ControlsPerLine = 2
-    ClientHeight = 25
-    ClientWidth = 114
+    ClientHeight = 36
+    ClientWidth = 143
+    Font.Height = -15
+    ParentFont = False
     TabOrder = 1
     object Button_OK: TButton
       Left = 0
-      Height = 25
+      Height = 36
       Top = 0
-      Width = 42
+      Width = 35
       AutoSize = True
       Caption = 'OK'
       Default = True
+      Font.Height = -15
       OnClick = Button_OKClick
+      ParentFont = False
       TabOrder = 0
     end
     object Button_Cancel: TButton
-      Left = 50
-      Height = 25
+      Left = 43
+      Height = 36
       Top = 0
-      Width = 62
+      Width = 59
       AutoSize = True
       Cancel = True
       Caption = 'Cancel'
+      Font.Height = -15
       ModalResult = 2
+      ParentFont = False
       TabOrder = 1
     end
   end
@@ -127,7 +146,7 @@ object FTwirl: TFTwirl
     Enabled = False
     Interval = 200
     OnTimer = Timer1Timer
-    left = 40
-    top = 8
+    left = 64
+    top = 120
   end
 end

+ 1 - 1
lazpaint/utwirl.pas → lazpaint/dialog/filter/utwirl.pas

@@ -92,7 +92,7 @@ begin
   SpinEdit_Angle.Value := round(FilterConnector.LazPaintInstance.Config.DefaultTwirlTurn*360);
   FInitializing := false;
   PreviewNeeded;
-  Left := FilterConnector.LazPaintInstance.MainFormBounds.Left
+  Left := FilterConnector.LazPaintInstance.MainFormBounds.Left;
 end;
 
 procedure TFTwirl.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;

+ 174 - 0
lazpaint/dialog/filter/uwavedisplacement.lfm

@@ -0,0 +1,174 @@
+object FWaveDisplacement: TFWaveDisplacement
+  Left = 306
+  Height = 356
+  Top = 172
+  Width = 222
+  AutoSize = True
+  BorderIcons = [biSystemMenu]
+  BorderStyle = bsDialog
+  Caption = 'Wave displacement'
+  ChildSizing.LeftRightSpacing = 8
+  ChildSizing.TopBottomSpacing = 8
+  ChildSizing.HorizontalSpacing = 8
+  ChildSizing.VerticalSpacing = 8
+  ChildSizing.Layout = cclLeftToRightThenTopToBottom
+  ChildSizing.ControlsPerLine = 1
+  ClientHeight = 356
+  ClientWidth = 222
+  DesignTimePPI = 120
+  OnCreate = FormCreate
+  OnShow = FormShow
+  Position = poScreenCenter
+  LCLVersion = '2.0.2.0'
+  object Panel1: TPanel
+    Left = 8
+    Height = 118
+    Top = 8
+    Width = 191
+    AutoSize = True
+    BevelOuter = bvNone
+    ChildSizing.HorizontalSpacing = 8
+    ChildSizing.VerticalSpacing = 8
+    ChildSizing.Layout = cclLeftToRightThenTopToBottom
+    ChildSizing.ControlsPerLine = 2
+    ClientHeight = 118
+    ClientWidth = 191
+    Font.Height = -15
+    ParentFont = False
+    TabOrder = 0
+    object Label_Wavelength: TLabel
+      Left = 0
+      Height = 34
+      Top = 0
+      Width = 102
+      Caption = 'Wavelength :'
+      Font.Height = -15
+      Layout = tlCenter
+      ParentColor = False
+      ParentFont = False
+    end
+    object SpinEdit_Wavelength: TSpinEdit
+      Left = 110
+      Height = 34
+      Top = 0
+      Width = 81
+      Constraints.MinWidth = 81
+      Font.Height = -15
+      Increment = 10
+      MaxValue = 10000
+      MinValue = 1
+      OnChange = SpinEdit_WavelengthChange
+      ParentFont = False
+      TabOrder = 0
+      Value = 100
+    end
+    object Label_Displacement: TLabel
+      Left = 0
+      Height = 34
+      Top = 42
+      Width = 102
+      Caption = 'Displacement :'
+      Font.Height = -15
+      Layout = tlCenter
+      ParentColor = False
+      ParentFont = False
+    end
+    object SpinEdit_Displacement: TSpinEdit
+      Left = 110
+      Height = 34
+      Top = 42
+      Width = 81
+      Constraints.MinWidth = 81
+      Font.Height = -15
+      Increment = 5
+      MaxValue = 1000
+      OnChange = SpinEdit_DisplacementChange
+      ParentFont = False
+      TabOrder = 1
+      Value = 50
+    end
+    object Label_Phase: TLabel
+      Left = 0
+      Height = 34
+      Top = 84
+      Width = 102
+      Caption = 'Phase :'
+      Font.Height = -15
+      Layout = tlCenter
+      ParentColor = False
+      ParentFont = False
+    end
+    object SpinEdit_Phase: TSpinEdit
+      Left = 110
+      Height = 34
+      Top = 84
+      Width = 81
+      Constraints.MinWidth = 81
+      Font.Height = -15
+      Increment = 30
+      MaxValue = 360
+      OnChange = SpinEdit_PhaseChange
+      ParentFont = False
+      TabOrder = 2
+    end
+  end
+  object PaintBox1: TPaintBox
+    Left = 9
+    Height = 160
+    Top = 136
+    Width = 189
+    Font.Height = -15
+    ParentFont = False
+    OnMouseDown = PaintBox1MouseDown
+    OnMouseMove = PaintBox1MouseMove
+    OnPaint = PaintBox1Paint
+  end
+  object Panel2: TPanel
+    Left = 9
+    Height = 36
+    Top = 304
+    Width = 188
+    BevelOuter = bvNone
+    ChildSizing.HorizontalSpacing = 8
+    ChildSizing.Layout = cclLeftToRightThenTopToBottom
+    ChildSizing.ControlsPerLine = 2
+    ClientHeight = 36
+    ClientWidth = 188
+    Font.Height = -15
+    ParentFont = False
+    TabOrder = 1
+    object Button_OK: TButton
+      Left = 0
+      Height = 36
+      Top = 0
+      Width = 35
+      AutoSize = True
+      Caption = 'OK'
+      Default = True
+      Font.Height = -15
+      OnClick = Button_OKClick
+      ParentFont = False
+      TabOrder = 0
+    end
+    object Button_Cancel: TButton
+      Left = 43
+      Height = 36
+      Top = 0
+      Width = 59
+      AutoSize = True
+      Cancel = True
+      Caption = 'Cancel'
+      Font.Height = -15
+      ModalResult = 2
+      ParentFont = False
+      TabOrder = 1
+    end
+  end
+  object Timer1: TTimer
+    Enabled = False
+    Interval = 200
+    OnTimer = Timer1Timer
+    left = 48
+    top = 184
+  end
+end

+ 183 - 0
lazpaint/dialog/filter/uwavedisplacement.pas

@@ -0,0 +1,183 @@
+unit UWaveDisplacement;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
+  Spin, UFilterConnector, BGRABitmap, BGRABitmapTypes, LazPaintType;
+
+type
+
+  { TFWaveDisplacement }
+
+  TFWaveDisplacement = class(TForm)
+    Button_Cancel: TButton;
+    Button_OK: TButton;
+    Label_Displacement: TLabel;
+    Label_Phase: TLabel;
+    Label_Wavelength: TLabel;
+    PaintBox1: TPaintBox;
+    Panel1: TPanel;
+    Panel2: TPanel;
+    SpinEdit_Displacement: TSpinEdit;
+    SpinEdit_Phase: TSpinEdit;
+    SpinEdit_Wavelength: TSpinEdit;
+    Timer1: TTimer;
+    procedure Button_OKClick(Sender: TObject);
+    procedure FormCreate(Sender: TObject);
+    procedure FormShow(Sender: TObject);
+    procedure PaintBox1MouseDown(Sender: TObject; {%H-}Button: TMouseButton;
+      {%H-}Shift: TShiftState; X, Y: Integer);
+    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
+      Y: Integer);
+    procedure PaintBox1Paint(Sender: TObject);
+    procedure SpinEdit_DisplacementChange(Sender: TObject);
+    procedure SpinEdit_PhaseChange(Sender: TObject);
+    procedure SpinEdit_WavelengthChange(Sender: TObject);
+    procedure Timer1Timer(Sender: TObject);
+  private
+    { private declarations }
+    FInitializing: boolean;
+    FCenter: TPointF;
+    procedure PreviewNeeded;
+    function ComputeFilteredLayer: TBGRABitmap;
+  public
+    FilterConnector: TFilterConnector;
+  end;
+
+var
+  FWaveDisplacement: TFWaveDisplacement;
+
+function ShowWaveDisplacementDlg(AFilterConnector: TObject):boolean;
+
+implementation
+
+uses umac, ugraph, LCScaleDPI;
+
+function ShowWaveDisplacementDlg(AFilterConnector: TObject):boolean;
+var
+  FWaveDisplacement: TFWaveDisplacement;
+begin
+  result := false;
+  FWaveDisplacement:= TFWaveDisplacement.create(nil);
+  FWaveDisplacement.FilterConnector := AFilterConnector as TFilterConnector;
+  try
+    if FWaveDisplacement.FilterConnector.ActiveLayer <> nil then
+      result:= (FWaveDisplacement.showModal = mrOk)
+    else
+      result := false;
+  finally
+    FWaveDisplacement.free;
+  end;
+end;
+
+{ TFWaveDisplacement }
+
+procedure TFWaveDisplacement.FormCreate(Sender: TObject);
+begin
+  ScaleControl(Self,OriginalDPI);
+
+  CheckSpinEdit(SpinEdit_Wavelength);
+  CheckSpinEdit(SpinEdit_Displacement);
+  CheckSpinEdit(SpinEdit_Phase);
+  CheckOKCancelBtns(Button_OK{,Button_Cancel});
+
+  FCenter := PointF(0.5,0.5);
+end;
+
+procedure TFWaveDisplacement.FormShow(Sender: TObject);
+begin
+  FInitializing:= true;
+  SpinEdit_Wavelength.Value := round(FilterConnector.LazPaintInstance.Config.DefaultWaveDisplacementWavelength);
+  SpinEdit_Displacement.Value := round(FilterConnector.LazPaintInstance.Config.DefaultWaveDisplacementAmount);
+  SpinEdit_Phase.Value := round(FilterConnector.LazPaintInstance.Config.DefaultWaveDisplacementPhase);
+  FInitializing := false;
+  PreviewNeeded;
+  Left := FilterConnector.LazPaintInstance.MainFormBounds.Left;
+end;
+
+procedure TFWaveDisplacement.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+begin
+  FCenter := PointF(X/PaintBox1.Width,Y/PaintBox1.Height);
+  PaintBox1.Invalidate;
+  PreviewNeeded;
+end;
+
+procedure TFWaveDisplacement.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
+  Y: Integer);
+begin
+  if ssLeft in Shift then
+  begin
+    FCenter := PointF(X/PaintBox1.Width,Y/PaintBox1.Height);
+    PaintBox1.Invalidate;
+    PreviewNeeded;
+  end;
+end;
+
+procedure TFWaveDisplacement.PaintBox1Paint(Sender: TObject);
+var x,y: integer;
+begin
+  x := round(FCenter.X*PaintBox1.Width);
+  y := round(FCenter.Y*PaintBox1.Height);
+  PaintBox1.Canvas.Brush.Style := bsClear;
+  PaintBox1.Canvas.Pen.Style := psSolid;
+  PaintBox1.Canvas.Pen.Color := clWindowText;
+  PaintBox1.Canvas.Rectangle(0,0,PaintBox1.Width,PaintBox1.Height);
+  PaintBox1.Canvas.Pen.Color := clBlack;
+  PaintBox1.Canvas.Brush.Style := bsSolid;
+  PaintBox1.Canvas.Brush.Color := clWhite;
+  PaintBox1.Canvas.Ellipse(x-3,y-3,x+4,y+4);
+end;
+
+procedure TFWaveDisplacement.SpinEdit_WavelengthChange(Sender: TObject);
+begin
+  if not FInitializing then PreviewNeeded;
+end;
+
+procedure TFWaveDisplacement.SpinEdit_DisplacementChange(Sender: TObject);
+begin
+  if not FInitializing then PreviewNeeded;
+end;
+
+procedure TFWaveDisplacement.SpinEdit_PhaseChange(Sender: TObject);
+begin
+  if not FInitializing then PreviewNeeded;
+end;
+
+procedure TFWaveDisplacement.Timer1Timer(Sender: TObject);
+begin
+  Timer1.Enabled := false;
+  FilterConnector.PutImage(ComputeFilteredLayer,False,true);
+  Button_OK.Enabled := true;
+end;
+
+procedure TFWaveDisplacement.PreviewNeeded;
+begin
+  Timer1.Enabled := false;
+  Timer1.Enabled := True;
+  Button_OK.Enabled := false;
+end;
+
+function TFWaveDisplacement.ComputeFilteredLayer: TBGRABitmap;
+begin
+  result := ugraph.WaveDisplacementFilter(FilterConnector.BackupLayer,FilterConnector.WorkArea,
+      PointF(FCenter.X*FilterConnector.ActiveLayer.Width,FCenter.Y*FilterConnector.ActiveLayer.Height),
+      SpinEdit_Wavelength.Value,SpinEdit_Displacement.Value,SpinEdit_Phase.Value) as TBGRABitmap;
+end;
+
+procedure TFWaveDisplacement.Button_OKClick(Sender: TObject);
+begin
+  FilterConnector.ValidateAction;
+  FilterConnector.LazPaintInstance.Config.SetDefaultWaveDisplacementWavelength(SpinEdit_Wavelength.Value);
+  FilterConnector.LazPaintInstance.Config.SetDefaultWaveDisplacementAmount(SpinEdit_Displacement.Value);
+  FilterConnector.LazPaintInstance.Config.SetDefaultWaveDisplacementPhase(SpinEdit_Phase.Value);
+  ModalResult := mrOK;
+end;
+
+{$R *.lfm}
+
+end.
+

+ 0 - 0
lazpaint/uabout.lfm → lazpaint/dialog/uabout.lfm


+ 0 - 0
lazpaint/uabout.pas → lazpaint/dialog/uabout.pas


+ 0 - 0
lazpaint/ublendop.lfm → lazpaint/dialog/ublendop.lfm


+ 0 - 0
lazpaint/ublendop.pas → lazpaint/dialog/ublendop.pas


+ 180 - 77
lazpaint/ubrowseimages.lfm → lazpaint/dialog/ubrowseimages.lfm

@@ -1,11 +1,12 @@
 object FBrowseImages: TFBrowseImages
   Left = 376
-  Height = 300
+  Height = 375
   Top = 101
-  Width = 684
+  Width = 855
   Caption = 'Browse images'
-  ClientHeight = 300
-  ClientWidth = 684
+  ClientHeight = 375
+  ClientWidth = 855
+  DesignTimePPI = 120
   KeyPreview = True
   OnCloseQuery = FormCloseQuery
   OnCreate = FormCreate
@@ -17,112 +18,120 @@ object FBrowseImages: TFBrowseImages
   OnUTF8KeyPress = FormUTF8KeyPress
   Position = poScreenCenter
   ShowInTaskBar = stAlways
-  LCLVersion = '2.0.0.4'
+  LCLVersion = '2.0.2.0'
   object Panel1: TPanel
-    Left = 464
-    Height = 300
+    Left = 580
+    Height = 375
     Top = 0
-    Width = 220
+    Width = 275
     Align = alClient
-    ClientHeight = 300
-    ClientWidth = 220
+    ClientHeight = 375
+    ClientWidth = 275
+    ParentFont = False
     TabOrder = 0
     object Label_Status: TLabel
-      Left = 3
-      Height = 17
-      Top = 5
-      Width = 3
+      Left = 4
+      Height = 22
+      Top = 6
+      Width = 4
       Caption = '.'
       ParentColor = False
+      ParentFont = False
     end
     object vsPreview: TBGRAVirtualScreen
-      Left = 3
-      Height = 270
-      Top = 26
-      Width = 214
+      Left = 4
+      Height = 338
+      Top = 32
+      Width = 267
       Alignment = taLeftJustify
       Anchors = [akTop, akLeft, akRight, akBottom]
       Color = clGray
       ParentColor = False
+      ParentFont = False
       TabOrder = 0
     end
     object ListBox_RecentDirs: TListBox
-      Left = 3
-      Height = 269
-      Top = 26
-      Width = 212
+      Left = 4
+      Height = 337
+      Top = 32
+      Width = 265
       Anchors = [akTop, akLeft, akRight, akBottom]
       ItemHeight = 0
       OnClick = ListBox_RecentDirsClick
-      ScrollWidth = 210
+      ParentFont = False
+      ScrollWidth = 263
       TabOrder = 1
       TopIndex = -1
     end
     object CheckBox_UseDirectoryOnStartup: TCheckBox
-      Left = 56
-      Height = 22
-      Top = 3
-      Width = 182
+      Left = 70
+      Height = 26
+      Top = 4
+      Width = 222
       Caption = 'Use this directory on startup'
       OnChange = CheckBox_UseDirectoryOnStartupChange
+      ParentFont = False
       TabOrder = 2
       Visible = False
     end
   end
   object Splitter1: TSplitter
-    Left = 458
-    Height = 300
+    Left = 572
+    Height = 375
     Top = 0
-    Width = 6
+    Width = 8
     MinSize = 64
   end
   object Panel2: TPanel
     Left = 0
-    Height = 300
+    Height = 375
     Top = 0
-    Width = 458
+    Width = 572
     Align = alLeft
-    ClientHeight = 300
-    ClientWidth = 458
+    ClientHeight = 375
+    ClientWidth = 572
+    ParentFont = False
     TabOrder = 2
     object Panel3: TPanel
       Left = 1
-      Height = 73
+      Height = 91
       Top = 1
-      Width = 456
+      Width = 570
       Align = alTop
-      ClientHeight = 73
-      ClientWidth = 456
+      ClientHeight = 91
+      ClientWidth = 570
+      ParentFont = False
       TabOrder = 0
       object ToolBar1: TToolBar
         Left = 1
-        Height = 33
+        Height = 41
         Top = 2
-        Width = 225
+        Width = 281
         Align = alNone
-        ButtonHeight = 32
-        ButtonWidth = 32
+        ButtonHeight = 40
+        ButtonWidth = 40
         EdgeBorders = []
         Images = ImageListToolbar
+        ParentFont = False
         ParentShowHint = False
         ShowHint = True
         TabOrder = 0
         object ToolButton_GoUp: TToolButton
-          Left = 145
+          Left = 161
           Hint = 'Go one directory up'
           Top = 0
           ImageIndex = 0
           OnClick = ToolButton_GoUpClick
         end
         object ToolButton_ViewBigIcon: TToolButton
-          Left = 73
+          Left = 81
           Hint = 'Show big icons'
           Top = 0
           ImageIndex = 2
           OnClick = ToolButton_ViewBigIconClick
         end
         object ToolButton_ViewDetails: TToolButton
-          Left = 37
+          Left = 41
           Hint = 'Show details and preview'
           Top = 0
           ImageIndex = 3
@@ -137,7 +146,7 @@ object FBrowseImages: TFBrowseImages
           OnClick = ToolButton_OpenSelectedFilesClick
         end
         object Tool_SelectDrive: TToolButton
-          Left = 109
+          Left = 121
           Hint = 'Select drive'
           Top = 0
           ImageIndex = 6
@@ -145,52 +154,146 @@ object FBrowseImages: TFBrowseImages
           Visible = False
         end
         object ToolButton_CreateFolderOrContainer: TToolButton
-          Left = 181
+          Left = 201
           Hint = 'Create folder or container'
           Top = 0
           ImageIndex = 8
           OnClick = ToolButton_CreateFolderOrContainerClick
         end
       end
-      object ComboBox_FileExtension: TComboBox
-        Left = 5
-        Height = 31
-        Top = 40
-        Width = 211
-        ItemHeight = 0
-        OnChange = ComboBox_FileExtensionChange
-        Style = csDropDownList
-        TabOrder = 1
-        TabStop = False
-      end
       object Edit_Filename: TEdit
-        Left = 224
-        Height = 27
-        Top = 40
-        Width = 224
+        Left = 280
+        Height = 34
+        Top = 50
+        Width = 280
         Anchors = [akTop, akLeft, akRight]
         OnChange = Edit_FilenameChange
-        TabOrder = 2
+        ParentFont = False
+        TabOrder = 1
       end
       object DirectoryEdit1: TEdit
-        Left = 224
-        Height = 27
-        Top = 5
-        Width = 224
+        Left = 280
+        Height = 34
+        Top = 6
+        Width = 280
         Anchors = [akTop, akLeft, akRight]
         OnChange = DirectoryEdit1Change
-        TabOrder = 3
+        ParentFont = False
+        TabOrder = 2
+      end
+      object ComboBox_FileExtension: TBCComboBox
+        Left = 8
+        Height = 34
+        Top = 50
+        Width = 262
+        ItemIndex = -1
+        ArrowSize = 8
+        ArrowWidth = 16
+        GlobalOpacity = 255
+        MemoryUsage = bmuHigh
+        Rounding.RoundX = 3
+        Rounding.RoundY = 3
+        StateClicked.Background.Gradient1.StartColor = clBtnShadow
+        StateClicked.Background.Gradient1.EndColor = clBtnFace
+        StateClicked.Background.Gradient1.GradientType = gtLinear
+        StateClicked.Background.Gradient1.Point1XPercent = 0
+        StateClicked.Background.Gradient1.Point1YPercent = 0
+        StateClicked.Background.Gradient1.Point2XPercent = 0
+        StateClicked.Background.Gradient1.Point2YPercent = 250
+        StateClicked.Background.Gradient2.StartColor = clBtnShadow
+        StateClicked.Background.Gradient2.EndColor = clBtnText
+        StateClicked.Background.Gradient2.GradientType = gtLinear
+        StateClicked.Background.Gradient2.Point1XPercent = 0
+        StateClicked.Background.Gradient2.Point1YPercent = 0
+        StateClicked.Background.Gradient2.Point2XPercent = 0
+        StateClicked.Background.Gradient2.Point2YPercent = 100
+        StateClicked.Background.Gradient1EndPercent = 70
+        StateClicked.Background.Style = bbsGradient
+        StateClicked.Border.Color = clBtnShadow
+        StateClicked.Border.LightOpacity = 100
+        StateClicked.Border.LightWidth = 1
+        StateClicked.Border.Style = bboSolid
+        StateClicked.FontEx.Color = clBtnText
+        StateClicked.FontEx.FontQuality = fqFineAntialiasing
+        StateClicked.FontEx.Shadow = False
+        StateClicked.FontEx.ShadowRadius = 5
+        StateClicked.FontEx.ShadowOffsetX = 5
+        StateClicked.FontEx.ShadowOffsetY = 5
+        StateClicked.FontEx.Style = []
+        StateClicked.FontEx.TextAlignment = bcaLeftCenter
+        StateClicked.FontEx.PaddingLeft = 3
+        StateHover.Background.Gradient1.StartColor = clBtnFace
+        StateHover.Background.Gradient1.EndColor = clBtnHighlight
+        StateHover.Background.Gradient1.GradientType = gtLinear
+        StateHover.Background.Gradient1.Point1XPercent = 0
+        StateHover.Background.Gradient1.Point1YPercent = 0
+        StateHover.Background.Gradient1.Point2XPercent = 0
+        StateHover.Background.Gradient1.Point2YPercent = 150
+        StateHover.Background.Gradient2.StartColor = clBtnFace
+        StateHover.Background.Gradient2.EndColor = clBtnShadow
+        StateHover.Background.Gradient2.GradientType = gtLinear
+        StateHover.Background.Gradient2.Point1XPercent = 0
+        StateHover.Background.Gradient2.Point1YPercent = 0
+        StateHover.Background.Gradient2.Point2XPercent = 0
+        StateHover.Background.Gradient2.Point2YPercent = 100
+        StateHover.Background.Gradient1EndPercent = 85
+        StateHover.Background.Style = bbsGradient
+        StateHover.Border.Color = clBtnShadow
+        StateHover.Border.LightOpacity = 200
+        StateHover.Border.LightWidth = 1
+        StateHover.Border.Style = bboSolid
+        StateHover.FontEx.Color = clBtnText
+        StateHover.FontEx.FontQuality = fqFineAntialiasing
+        StateHover.FontEx.Shadow = False
+        StateHover.FontEx.ShadowRadius = 5
+        StateHover.FontEx.ShadowOffsetX = 5
+        StateHover.FontEx.ShadowOffsetY = 5
+        StateHover.FontEx.Style = []
+        StateHover.FontEx.TextAlignment = bcaLeftCenter
+        StateHover.FontEx.PaddingLeft = 3
+        StateNormal.Background.Gradient1.StartColor = clBtnFace
+        StateNormal.Background.Gradient1.EndColor = clBtnHighlight
+        StateNormal.Background.Gradient1.GradientType = gtLinear
+        StateNormal.Background.Gradient1.Point1XPercent = 0
+        StateNormal.Background.Gradient1.Point1YPercent = 0
+        StateNormal.Background.Gradient1.Point2XPercent = 0
+        StateNormal.Background.Gradient1.Point2YPercent = 150
+        StateNormal.Background.Gradient2.StartColor = clBtnFace
+        StateNormal.Background.Gradient2.EndColor = clBtnShadow
+        StateNormal.Background.Gradient2.GradientType = gtLinear
+        StateNormal.Background.Gradient2.Point1XPercent = 0
+        StateNormal.Background.Gradient2.Point1YPercent = 0
+        StateNormal.Background.Gradient2.Point2XPercent = 0
+        StateNormal.Background.Gradient2.Point2YPercent = 100
+        StateNormal.Background.Gradient1EndPercent = 70
+        StateNormal.Background.Style = bbsGradient
+        StateNormal.Border.Color = clBtnShadow
+        StateNormal.Border.LightOpacity = 200
+        StateNormal.Border.LightWidth = 1
+        StateNormal.Border.Style = bboSolid
+        StateNormal.FontEx.Color = clBtnText
+        StateNormal.FontEx.FontQuality = fqFineAntialiasing
+        StateNormal.FontEx.Shadow = False
+        StateNormal.FontEx.ShadowRadius = 5
+        StateNormal.FontEx.ShadowOffsetX = 5
+        StateNormal.FontEx.ShadowOffsetY = 5
+        StateNormal.FontEx.Style = []
+        StateNormal.FontEx.TextAlignment = bcaLeftCenter
+        StateNormal.FontEx.PaddingLeft = 3
+        StaticButton = False
+        OnChange = ComboBox_FileExtensionChange
       end
     end
     object vsList: TBGRAVirtualScreen
       Left = 1
-      Height = 225
-      Top = 74
-      Width = 456
+      Height = 282
+      Top = 92
+      Width = 570
       Align = alClient
       Alignment = taLeftJustify
       Color = clWindow
       ParentColor = False
+      ParentFont = False
       TabOrder = 1
       TabStop = True
     end
@@ -198,8 +301,8 @@ object FBrowseImages: TFBrowseImages
   object ImageList128: TImageList
     Height = 128
     Width = 128
-    left = 40
-    top = 176
+    left = 50
+    top = 220
     Bitmap = {
       4C69080000008000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
       FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
@@ -16592,14 +16695,14 @@ object FBrowseImages: TFBrowseImages
     Enabled = False
     Interval = 30
     OnTimer = Timer1Timer
-    left = 256
-    top = 176
+    left = 320
+    top = 220
   end
   object ImageListToolbar: TImageList
     Height = 32
     Width = 32
-    left = 187
-    top = 177
+    left = 234
+    top = 221
     Bitmap = {
       4C69090000002000000020000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000

+ 6 - 5
lazpaint/ubrowseimages.pas → lazpaint/dialog/ubrowseimages.pas

@@ -5,10 +5,10 @@ unit ubrowseimages;
 interface
 
 uses
-  Classes, SysUtils, Forms, Controls, Graphics, Dialogs,
-  ComCtrls, ExtCtrls, Buttons, StdCtrls, BGRAVirtualScreen, BGRABitmap,
-  BGRABitmapTypes, BGRAAnimatedGif, UMySLV, LazPaintType, Masks, LCLType,
-  UFileSystem, UImagePreview;
+  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
+  Buttons, StdCtrls, BGRAVirtualScreen, BCComboBox, BGRABitmap, BGRABitmapTypes,
+  BGRAAnimatedGif, UMySLV, LazPaintType, Masks, LCLType, UFileSystem,
+  UImagePreview;
 
 const
   MaxIconCacheCount = 512;
@@ -18,6 +18,7 @@ type
   { TFBrowseImages }
 
   TFBrowseImages = class(TForm)
+    ComboBox_FileExtension: TBCComboBox;
     CheckBox_UseDirectoryOnStartup: TCheckBox;
     DirectoryEdit1: TEdit;
     ToolButton_CreateFolderOrContainer: TToolButton;
@@ -25,7 +26,6 @@ type
     ToolButtonSeparator: TToolButton;
     ToolButton_OpenSelectedFiles: TToolButton;
     vsList: TBGRAVirtualScreen;
-    ComboBox_FileExtension: TComboBox;
     Edit_Filename: TEdit;
     ListBox_RecentDirs: TListBox;
     Panel3: TPanel;
@@ -262,6 +262,7 @@ begin
   FPreview.OnValidate:= @PreviewValidate;
   FChosenImage := TImageEntry.Empty;
 
+  BCAssignSystemStyle(ComboBox_FileExtension, False);
   InitComboExt;
 
   bmp := TBitmap.Create;

+ 0 - 0
lazpaint/ucanvassize.lfm → lazpaint/dialog/ucanvassize.lfm


+ 0 - 0
lazpaint/ucanvassize.pas → lazpaint/dialog/ucanvassize.pas


+ 0 - 0
lazpaint/ugeometricbrush.lfm → lazpaint/dialog/ugeometricbrush.lfm


+ 0 - 0
lazpaint/ugeometricbrush.pas → lazpaint/dialog/ugeometricbrush.pas


+ 0 - 0
lazpaint/umultiimage.lfm → lazpaint/dialog/umultiimage.lfm


+ 0 - 0
lazpaint/umultiimage.pas → lazpaint/dialog/umultiimage.pas


+ 0 - 0
lazpaint/unewimage.lfm → lazpaint/dialog/unewimage.lfm


+ 0 - 0
lazpaint/unewimage.pas → lazpaint/dialog/unewimage.pas


+ 0 - 0
lazpaint/uobject3d.lfm → lazpaint/dialog/uobject3d.lfm


+ 0 - 0
lazpaint/uobject3d.pas → lazpaint/dialog/uobject3d.pas


+ 0 - 0
lazpaint/upreviewdialog.lfm → lazpaint/dialog/upreviewdialog.lfm


+ 0 - 0
lazpaint/upreviewdialog.pas → lazpaint/dialog/upreviewdialog.pas


+ 0 - 0
lazpaint/uprint.lfm → lazpaint/dialog/uprint.lfm


+ 0 - 0
lazpaint/uprint.pas → lazpaint/dialog/uprint.pas


+ 0 - 0
lazpaint/uquestion.lfm → lazpaint/dialog/uquestion.lfm


+ 0 - 0
lazpaint/uquestion.pas → lazpaint/dialog/uquestion.pas


+ 0 - 0
lazpaint/uresample.lfm → lazpaint/dialog/uresample.lfm


+ 0 - 0
lazpaint/uresample.pas → lazpaint/dialog/uresample.pas


+ 0 - 0
lazpaint/usaveoption.lfm → lazpaint/dialog/usaveoption.lfm


+ 0 - 0
lazpaint/usaveoption.pas → lazpaint/dialog/usaveoption.pas


+ 41 - 1
lazpaint/uimage.pas → lazpaint/image/uimage.pas

@@ -58,6 +58,8 @@ type
     FDraftOriginal: boolean;
 
     procedure DiscardSelectionLayerAfterMask;
+    function GetDPI: integer;
+    function GetIsCursor: boolean;
     function GetIsIconCursor: boolean;
     function GetIsTiff: boolean;
     function GetIsGif: boolean;
@@ -93,6 +95,10 @@ type
     function GetWidth: integer;
     function GetZoomFactor: single;
     procedure InvalidateImageDifference(ADiff: TCustomImageDifference);
+    procedure OriginalChange({%H-}ASender: TObject;
+      AOriginal: TBGRALayerCustomOriginal; var ADiff: TBGRAOriginalDiff);
+    procedure OriginalEditingChange({%H-}ASender: TObject;
+      {%H-}AOriginal: TBGRALayerCustomOriginal);
     procedure SetBlendOperation(AIndex: integer; AValue: TBlendOperation);
     procedure SetCurrentFilenameUTF8(AValue: string);
     procedure LayeredBitmapReplaced;
@@ -257,8 +263,10 @@ type
     property ZoomFactor: single read GetZoomFactor;
     property DraftOriginal: boolean read FDraftOriginal write SetDraftOriginal;
     property IsIconCursor: boolean read GetIsIconCursor;
+    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;
@@ -708,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;
@@ -961,6 +969,26 @@ begin
   end;
 end;
 
+procedure TLazPaintImage.OriginalChange(ASender: TObject;
+  AOriginal: TBGRALayerCustomOriginal; var ADiff: TBGRAOriginalDiff);
+var
+  r: TRect;
+begin
+  r := FCurrentState.LayeredBitmap.RenderOriginalIfNecessary(AOriginal.Guid, FDraftOriginal);
+  ImageMayChange(r, false);
+  if Assigned(ADiff) then
+  begin
+    AddUndo(TVectorOriginalEmbeddedDifference.Create(CurrentState,AOriginal.Guid,ADiff,r));
+    ADiff := nil;
+  end;
+end;
+
+procedure TLazPaintImage.OriginalEditingChange(ASender: TObject;
+  AOriginal: TBGRALayerCustomOriginal);
+begin
+  OnImageChanged.NotifyObservers;
+end;
+
 procedure TLazPaintImage.Redo;
 var diff: TCustomImageDifference;
 begin
@@ -1191,6 +1219,16 @@ begin
   end;
 end;
 
+function TLazPaintImage.GetDPI: integer;
+begin
+  result := ScreenInfo.PixelsPerInchY;
+end;
+
+function TLazPaintImage.GetIsCursor: boolean;
+begin
+  result := UTF8CompareText(ExtractFileExt(currentFilenameUTF8),'.cur')=0;
+end;
+
 function TLazPaintImage.GetIsIconCursor: boolean;
 begin
   result := SuggestImageFormat(currentFilenameUTF8) in [ifIco,ifCur];
@@ -2043,6 +2081,8 @@ end;
 constructor TLazPaintImage.Create;
 begin
   FCurrentState := TImageState.Create;
+  FCurrentState.OnOriginalChange:=@OriginalChange;
+  FCurrentState.OnOriginalEditingChange:=@OriginalEditingChange;
   FRenderUpdateRectInPicCoord := rect(0,0,0,0);
   FRenderUpdateRectInVSCoord := rect(0,0,0,0);
   FOnSelectionMaskChanged := nil;

+ 35 - 26
lazpaint/uimageaction.pas → lazpaint/image/uimageaction.pas

@@ -74,7 +74,7 @@ implementation
 
 uses Controls, Dialogs, UResourceStrings, UObject3D,
      ULoadImage, UGraph, UClipboard, Types, BGRAGradientOriginal,
-     BGRATransform, ULoading, math;
+     BGRATransform, ULoading, math, LCVectorClipboard;
 
 { TImageActions }
 
@@ -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);
@@ -501,7 +501,8 @@ var
 begin
   if (ABitmap <> nil) and (ABitmap.Width > 0) and (ABitmap.Height > 0) then
   begin
-    if CurrentTool in [ptDeformation,ptRotateSelection,ptMoveSelection,ptTextureMapping,ptLayerMapping] then
+    if CurrentTool in [ptDeformation,ptRotateSelection,ptMoveSelection,ptTextureMapping,
+         ptLayerMapping,ptEditShape] then
       ChooseTool(ptHand);
     if image.CheckNoAction then
     begin
@@ -557,7 +558,8 @@ function TImageActions.AddLayerFromOriginal(AOriginal: TBGRALayerCustomOriginal;
 begin
   if AOriginal <> nil then
   begin
-    if CurrentTool in [ptDeformation,ptRotateSelection,ptMoveSelection,ptTextureMapping,ptLayerMapping] then
+    if CurrentTool in [ptDeformation,ptRotateSelection,ptMoveSelection,ptTextureMapping,
+         ptLayerMapping,ptEditShape] then
       ChooseTool(ptHand);
     if image.CheckNoAction then
     begin
@@ -822,30 +824,37 @@ var partial: TBGRABitmap;
     pastePos: TPoint;
 begin
   try
-    partial := GetBitmapFromClipboard;
-    if partial<>nil then
+    if ClipboardHasShapes then
     begin
-      if partial.NbPixels <> 0 then
+      ChooseTool(ptEditShape);
+      ToolManager.ToolCommand(tcPaste);
+    end else
+    begin
+      partial := GetBitmapFromClipboard;
+      if partial<>nil then
       begin
-        ToolManager.ToolCloseDontReopen;
-        layeraction := Image.CreateAction(true, true);
-        layeraction.ReleaseSelection;
-        layeraction.QuerySelection;
-        pastePos := Point((image.Width - partial.Width) div 2 - image.ImageOffset.X,
-           (image.Height - partial.Height) div 2 - image.ImageOffset.Y);
-        if pastePos.x+partial.width > image.width then pastePos.x := image.width-partial.width;
-        if pastePos.y+partial.Height > image.Height then pastePos.y := image.Height-partial.Height;
-        if pastePos.x < 0 then pastePos.x := 0;
-        if pastePos.y < 0 then pastePos.y := 0;
-        layeraction.GetOrCreateSelectionLayer.PutImage(pastePos.x,pastePos.y,partial,dmFastBlend);
-        ComputeSelectionMask(layeraction.GetOrCreateSelectionLayer,layeraction.currentSelection,
-          rect(pastePos.x,pastePos.y,pastePos.x+partial.Width,pastePos.y+partial.Height));
-        Image.SelectionMaskMayChange(rect(pastePos.x,pastePos.y,pastePos.x+partial.Width,pastePos.y+partial.Height));
-        layeraction.Validate;
-        layeraction.Free;
-        ChooseTool(ptMoveSelection);
+        if partial.NbPixels <> 0 then
+        begin
+          ToolManager.ToolCloseDontReopen;
+          layeraction := Image.CreateAction(true, true);
+          layeraction.ReleaseSelection;
+          layeraction.QuerySelection;
+          pastePos := Point((image.Width - partial.Width) div 2 - image.ImageOffset.X,
+             (image.Height - partial.Height) div 2 - image.ImageOffset.Y);
+          if pastePos.x+partial.width > image.width then pastePos.x := image.width-partial.width;
+          if pastePos.y+partial.Height > image.Height then pastePos.y := image.Height-partial.Height;
+          if pastePos.x < 0 then pastePos.x := 0;
+          if pastePos.y < 0 then pastePos.y := 0;
+          layeraction.GetOrCreateSelectionLayer.PutImage(pastePos.x,pastePos.y,partial,dmFastBlend);
+          ComputeSelectionMask(layeraction.GetOrCreateSelectionLayer,layeraction.currentSelection,
+            rect(pastePos.x,pastePos.y,pastePos.x+partial.Width,pastePos.y+partial.Height));
+          Image.SelectionMaskMayChange(rect(pastePos.x,pastePos.y,pastePos.x+partial.Width,pastePos.y+partial.Height));
+          layeraction.Validate;
+          layeraction.Free;
+          ChooseTool(ptMoveSelection);
+        end;
+        partial.Free;
       end;
-      partial.Free;
     end;
   except
     on ex:Exception do

+ 243 - 35
lazpaint/uimagediff.pas → lazpaint/image/uimagediff.pas

@@ -6,7 +6,7 @@ interface
 
 uses
   Classes, SysUtils, UStateType, BGRABitmap, BGRABitmapTypes, BGRALayers,
-  BGRALayerOriginal, LCVectorOriginal;
+  BGRALayerOriginal, LCVectorOriginal, UImageState;
 
 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
 function TryCombineImageDiff(ANewDiff, APrevDiff: TCustomImageDifference): boolean;
@@ -55,12 +55,14 @@ type
     function GetIsIdentity: boolean; override;
     function GetChangingBoundsDefined: boolean; override;
     function GetChangingBounds: TRect; override;
+    function GetLayerRect(AState: TImageState; AIndex: integer): TRect;
+    procedure EnsureLayerRect(AState: TImageState; AIndex: integer);
     procedure Init(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
         APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
         APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect);
   public
     layerId: integer;
-    imageOfs: TPoint;
+    layerRect: TRect;
     imageDiff, selectionLayerDiff: TImageDiff;
     selectionMaskDiff: TGrayscaleImageDiff;
     function TryCompress: boolean; override;
@@ -165,7 +167,6 @@ type
     useOriginal: boolean;
     previousOriginalRenderStatus: TOriginalRenderStatus;
     layerId: integer;
-    FDestination: TState;
     previousLayerOffset: TPoint;
   protected
     function GetImageDifferenceKind: TImageDifferenceKind; override;
@@ -292,8 +293,10 @@ type
     FPreviousLayerContent: TStoredLayer;
     FPrevMatrix,FNextMatrix: TAffineMatrix;
     FSourceBounds: TRect;
+    FOriginalGuid: TGUID;
     function GetImageDifferenceKind: TImageDifferenceKind; override;
     function CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal; virtual; abstract;
+    function ShouldRenderOriginal: boolean; virtual;
   public
     constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
     function UsedMemory: int64; override;
@@ -340,7 +343,23 @@ type
 
   TReplaceLayerByVectorOriginalDifference = class(TReplaceLayerByOriginalDifference)
   protected
+    FShouldRenderOriginal: boolean;
+    function ShouldRenderOriginal: boolean; override;
     function CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal; override;
+  public
+    constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
+  end;
+
+  { TReplaceLayerByCustomOriginalDifference }
+
+  TReplaceLayerByCustomOriginalDifference = class(TReplaceLayerByOriginalDifference)
+  protected
+    FOriginal: TBGRALayerCustomOriginal;
+    function CreateOriginal({%H-}AState: TState; {%H-}ALayerIndex: integer): TBGRALayerCustomOriginal; override;
+    function ShouldRenderOriginal: boolean; override;
+  public
+    constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean; AOriginal: TBGRALayerCustomOriginal);
+    destructor Destroy; override;
   end;
 
   { TAddShapeToVectorOriginalDifference }
@@ -349,7 +368,7 @@ type
   private
     FShapeIndex, FShapeId: integer;
     FLayerId: integer;
-    FShapeData: TBGRAMemOriginalStorage;
+    FShapeCopy: TVectorShape;
     FShapeBounds: TRect;
   protected
     function GetImageDifferenceKind: TImageDifferenceKind; override;
@@ -362,6 +381,26 @@ type
     procedure UnapplyTo(AState: TState); override;
   end;
 
+  { TVectorOriginalEmbeddedDifference }
+
+  TVectorOriginalEmbeddedDifference = class(TCustomImageDifference)
+  private
+    FDate: TDateTime;
+    FOriginalGuid: TGuid;
+    FDiff: TBGRAOriginalDiff;
+    FBounds: TRect;
+  protected
+    function GetImageDifferenceKind: TImageDifferenceKind; override;
+    function GetChangingBounds: TRect; override;
+    function GetChangingBoundsDefined: boolean; override;
+    function GetIsIdentity: boolean; override;
+  public
+    constructor Create({%H-}ADestination: TState; AOriginalGuid: TGuid; ADiff: TBGRAOriginalDiff; ABounds: TRect);
+    destructor Destroy; override;
+    procedure ApplyTo(AState: TState); override;
+    procedure UnapplyTo(AState: TState); override;
+  end;
+
   { TDiscardOriginalStateDifference }
 
   TDiscardOriginalStateDifference = class(TCustomImageDifference)
@@ -451,8 +490,9 @@ type
 
 implementation
 
-uses BGRAWriteLzp, BGRAReadLzp, UImageState, BGRAStreamLayers, BGRALzpCommon, ugraph, Types,
-  BGRATransform, zstream, LCVectorRectShapes, BGRAPen, math;
+uses BGRAWriteLzp, BGRAReadLzp, BGRAStreamLayers, BGRALzpCommon, ugraph, Types,
+  BGRATransform, zstream, LCVectorRectShapes, BGRAPen, LCVectorialFill,
+  BGRAGradientOriginal;
 
 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
 begin
@@ -488,6 +528,7 @@ begin
 end;
 
 function TryCombineImageDiff(ANewDiff, APrevDiff: TCustomImageDifference): boolean;
+const VectorDiffMinTime = 2000/(1000*60*60*24);
 var
   combined: TInversibleAction;
 begin
@@ -572,9 +613,109 @@ begin
     else result := false;
   end
   else
+  if (APrevDiff is TVectorOriginalEmbeddedDifference) and (ANewDiff is TVectorOriginalEmbeddedDifference) then
+  begin
+    if (TVectorOriginalEmbeddedDifference(ANewDiff).FDate <
+       TVectorOriginalEmbeddedDifference(APrevDiff).FDate+VectorDiffMinTime) and
+      TVectorOriginalEmbeddedDifference(APrevDiff).FDiff.CanAppend(
+      TVectorOriginalEmbeddedDifference(ANewDiff).FDiff) then
+    begin
+      TVectorOriginalEmbeddedDifference(APrevDiff).FDiff.Append(
+        TVectorOriginalEmbeddedDifference(ANewDiff).FDiff);
+      result := true;
+    end else
+      result := false;
+  end else
     result := false;
 end;
 
+{ TReplaceLayerByCustomOriginalDifference }
+
+function TReplaceLayerByCustomOriginalDifference.CreateOriginal(AState: TState;
+  ALayerIndex: integer): TBGRALayerCustomOriginal;
+begin
+  result := FOriginal.Duplicate;
+end;
+
+function TReplaceLayerByCustomOriginalDifference.ShouldRenderOriginal: boolean;
+begin
+  result := true;
+end;
+
+constructor TReplaceLayerByCustomOriginalDifference.Create(AFromState: TState;
+  AIndex: integer; AAlwaysStoreBitmap: boolean; AOriginal: TBGRALayerCustomOriginal);
+begin
+  FOriginal := AOriginal;
+  inherited Create(AFromState,AIndex,AAlwaysStoreBitmap);
+end;
+
+destructor TReplaceLayerByCustomOriginalDifference.Destroy;
+begin
+  FOriginal.Free;
+  inherited Destroy;
+end;
+
+{ TVectorOriginalEmbeddedDifference }
+
+function TVectorOriginalEmbeddedDifference.GetImageDifferenceKind: TImageDifferenceKind;
+begin
+  Result:= idkChangeImage;
+end;
+
+function TVectorOriginalEmbeddedDifference.GetChangingBounds: TRect;
+begin
+  Result:= FBounds;
+end;
+
+function TVectorOriginalEmbeddedDifference.GetChangingBoundsDefined: boolean;
+begin
+  Result:= true;
+end;
+
+function TVectorOriginalEmbeddedDifference.GetIsIdentity: boolean;
+begin
+  Result:= FDiff.IsIdentity;
+end;
+
+constructor TVectorOriginalEmbeddedDifference.Create(ADestination: TState;
+  AOriginalGuid: TGuid; ADiff: TBGRAOriginalDiff; ABounds: TRect);
+begin
+  FDate := Now;
+  FOriginalGuid:= AOriginalGuid;
+  FDiff := ADiff;
+  FBounds := ABounds;
+end;
+
+destructor TVectorOriginalEmbeddedDifference.Destroy;
+begin
+  FDiff.Free;
+  inherited Destroy;
+end;
+
+procedure TVectorOriginalEmbeddedDifference.ApplyTo(AState: TState);
+var
+  img: TImageState;
+  idxOrig: Integer;
+begin
+  inherited ApplyTo(AState);
+  img := AState as TImageState;
+  idxOrig := img.LayeredBitmap.IndexOfOriginal(FOriginalGuid);
+  if idxOrig<>-1 then
+    FDiff.Apply(img.LayeredBitmap.Original[idxOrig]);
+end;
+
+procedure TVectorOriginalEmbeddedDifference.UnapplyTo(AState: TState);
+var
+  img: TImageState;
+  idxOrig: Integer;
+begin
+  inherited UnapplyTo(AState);
+  img := AState as TImageState;
+  idxOrig := img.LayeredBitmap.IndexOfOriginal(FOriginalGuid);
+  if idxOrig<>-1 then
+    FDiff.Unapply(img.LayeredBitmap.Original[idxOrig]);
+end;
+
 { TDiscardOriginalDifference }
 
 function TDiscardOriginalDifference.GetLayerId: integer;
@@ -692,7 +833,7 @@ constructor TAddShapeToVectorOriginalDifference.Create(ADestination: TState;
   ALayerId: integer; AShape: TVectorShape; AShapeIndex: integer);
 var
   imgState: TImageState;
-  layerIdx, idxShapeAdd: Integer;
+  layerIdx: Integer;
   orig: TBGRALayerCustomOriginal;
 begin
   FLayerId := ALayerId;
@@ -706,27 +847,25 @@ begin
   end;
   if AShapeIndex = -1 then AShapeIndex := TVectorOriginal(orig).ShapeCount;
   FShapeIndex:= AShapeIndex;
-  FShapeData := TBGRAMemOriginalStorage.Create;
-  AShape.SaveToStorage(FShapeData);
-  FShapeData.RawString['class'] := AShape.StorageClassName;
+  FShapeCopy := AShape.Duplicate;
 
   inherited ApplyTo(ADestination);
-  idxShapeAdd := TVectorOriginal(orig).AddShape(AShape);
-  FShapeId := TVectorOriginal(orig).Shape[idxShapeAdd].Id;
-  TVectorOriginal(orig).MoveShapeToIndex(idxShapeAdd, FShapeIndex);
+  TVectorOriginal(orig).InsertShape(AShape, FShapeIndex);
+  FShapeId := TVectorOriginal(orig).Shape[FShapeIndex].Id;
+  TVectorOriginal(orig).SelectShape(FShapeIndex);
   FShapeBounds := imgState.LayeredBitmap.RenderOriginalIfNecessary(orig.Guid);
 end;
 
 destructor TAddShapeToVectorOriginalDifference.Destroy;
 begin
-  FShapeData.Free;
+  FShapeCopy.Free;
   inherited Destroy;
 end;
 
 procedure TAddShapeToVectorOriginalDifference.ApplyTo(AState: TState);
 var
   imgState: TImageState;
-  layerIdx, idxShapeAdd: Integer;
+  layerIdx: Integer;
   orig: TBGRALayerCustomOriginal;
   shape: TVectorShape;
 begin
@@ -737,10 +876,10 @@ begin
   if not (orig is TVectorOriginal) then
     raise exception.Create('Vector original expected');
 
-  shape := TVectorShape.CreateFromStorage(FShapeData,nil);
-  idxShapeAdd := TVectorOriginal(orig).AddShape(shape);
-  TVectorOriginal(orig).Shape[idxShapeAdd].Id := FShapeId;
-  TVectorOriginal(orig).MoveShapeToIndex(idxShapeAdd, FShapeIndex);
+  shape := FShapeCopy.Duplicate;
+  TVectorOriginal(orig).InsertShape(shape, FShapeIndex);
+  TVectorOriginal(orig).Shape[FShapeIndex].Id := FShapeId;
+  TVectorOriginal(orig).SelectShape(FShapeIndex);
   imgState.LayeredBitmap.RenderLayerFromOriginal(layerIdx);
 end;
 
@@ -761,6 +900,11 @@ end;
 
 { TReplaceLayerByVectorOriginalDifference }
 
+function TReplaceLayerByVectorOriginalDifference.ShouldRenderOriginal: boolean;
+begin
+  Result:= FShouldRenderOriginal;
+end;
+
 function TReplaceLayerByVectorOriginalDifference.CreateOriginal(AState: TState;
   ALayerIndex: integer): TBGRALayerCustomOriginal;
 var
@@ -772,20 +916,42 @@ var
 begin
   imgState := TImageState(AState);
   orig := TVectorOriginal.Create;
-  source := imgState.LayeredBitmap.LayerBitmap[ALayerIndex];
-  if not source.Empty then
+  if imgState.LayeredBitmap.LayerOriginalClass[ALayerIndex]=TBGRALayerGradientOriginal then
   begin
     shape := TRectShape.Create(orig);
-    shape.QuickDefine(PointF(0,0),PointF(FSourceBounds.Width,FSourceBounds.Height));
+    shape.QuickDefine(PointF(-0.5,-0.5),PointF(FSourceBounds.Width-0.5,FSourceBounds.Height-0.5));
     shape.PenStyle := ClearPenStyle;
-    temp := source.GetPart(FSourceBounds) as TBGRABitmap;
-    shape.BackFill.SetTexture(temp,AffineMatrixIdentity);
-    temp.FreeReference;
+    shape.BackFill.SetGradient(
+      imgState.LayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerGradientOriginal,false);
+    shape.BackFill.Transform(imgState.LayeredBitmap.LayerOriginalMatrix[ALayerIndex]);
     orig.AddShape(shape);
+  end else
+  begin
+    source := imgState.LayeredBitmap.LayerBitmap[ALayerIndex];
+    if not source.Empty then
+    begin
+      shape := TRectShape.Create(orig);
+      shape.QuickDefine(PointF(-0.5,-0.5),PointF(FSourceBounds.Width-0.5,FSourceBounds.Height-0.5));
+      shape.PenStyle := ClearPenStyle;
+      temp := source.GetPart(FSourceBounds) as TBGRABitmap;
+      shape.BackFill.SetTexture(temp,AffineMatrixIdentity,255,trNone);
+      temp.FreeReference;
+      orig.AddShape(shape);
+    end;
   end;
   result := orig;
 end;
 
+constructor TReplaceLayerByVectorOriginalDifference.Create(AFromState: TState;
+  AIndex: integer; AAlwaysStoreBitmap: boolean);
+var
+  imgState: TImageState;
+begin
+  imgState := AFromState as TImageState;
+  FShouldRenderOriginal:= imgState.LayeredBitmap.LayerOriginalClass[AIndex]=TBGRALayerGradientOriginal;
+  inherited Create(AFromState, AIndex, AAlwaysStoreBitmap);
+end;
+
 { TReplaceLayerByImageOriginalDifference }
 
 function TReplaceLayerByImageOriginalDifference.CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal;
@@ -923,6 +1089,11 @@ begin
   Result:= idkChangeImage;
 end;
 
+function TReplaceLayerByOriginalDifference.ShouldRenderOriginal: boolean;
+begin
+  result := false;
+end;
+
 constructor TReplaceLayerByOriginalDifference.Create(
   AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
 var
@@ -957,10 +1128,12 @@ begin
   imgState := AState as TImageState;
   layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FPreviousLayerContent.LayerId);
   orig := CreateOriginal(imgState, layerIdx);
+  if FOriginalGuid <> GUID_NULL then orig.Guid := FOriginalGuid;
   origIndex := imgState.LayeredBitmap.AddOriginal(orig, true);
+  if FOriginalGuid = GUID_NULL then FOriginalGuid := orig.Guid;
   imgState.LayeredBitmap.LayerOriginalGuid[layerIdx] := imgState.LayeredBitmap.OriginalGuid[origIndex];
   imgState.LayeredBitmap.LayerOriginalMatrix[layerIdx] := FNextMatrix;
-  if FNextMatrix = FPrevMatrix then
+  if (FNextMatrix = FPrevMatrix) and not ShouldRenderOriginal then
     imgState.LayeredBitmap.LayerOriginalRenderStatus[layerIdx] := orsProof
   else
   begin
@@ -1327,9 +1500,8 @@ var idx: integer;
   clippedImage: TBGRABitmap;
 begin
   inherited Create(ADestination);
-  FDestination := ADestination;
   layerId:= ALayerId;
-  layers := (FDestination as TImageState).LayeredBitmap;
+  layers := (ADestination as TImageState).LayeredBitmap;
   idx := layers.GetLayerIndexFromId(ALayerId);
   if idx = -1 then raise exception.Create('Invalid layer Id');
   nextBounds := rect(0,0,layers.Width,layers.Height);
@@ -2233,13 +2405,41 @@ begin
   if ChangeImageLayer then
   begin
     r := imageDiff.ChangeRect;
-    OffsetRect(r, imageOfs.x, imageOfs.y);
+    OffsetRect(r, layerRect.Left, layerRect.Top);
     result := RectUnion(result, r);
   end;
   if ChangeSelectionLayer then result := RectUnion(result, selectionLayerDiff.ChangeRect);
   if ChangeSelectionMask then result := RectUnion(result, selectionMaskDiff.ChangeRect);
 end;
 
+function TImageLayerStateDifference.GetLayerRect(AState: TImageState;
+  AIndex: integer): TRect;
+begin
+  result.TopLeft := AState.LayerOffset[AIndex];
+  result.Width:= AState.LayerBitmap[AIndex].Width;
+  result.Height:= AState.LayerBitmap[AIndex].Height;
+end;
+
+procedure TImageLayerStateDifference.EnsureLayerRect(AState: TImageState;
+  AIndex: integer);
+var
+  curRect: TRect;
+  newBmp: TBGRABitmap;
+begin
+  curRect := GetLayerRect(AState, AIndex);
+  if (layerRect.Left<>curRect.Left) or
+     (layerRect.Top<>curRect.Top) or
+     (layerRect.Width<>curRect.Width) or
+     (layerRect.Height<>curRect.Height) then
+  begin
+    newBmp := TBGRABitmap.Create(layerRect.Width,layerRect.Height);
+    newBmp.PutImage(curRect.Left-layerRect.Left,curRect.Top-layerRect.Top,
+      AState.LayerBitmap[AIndex], dmSet);
+    AState.SetLayerBitmap(AIndex, newBmp, true);
+    AState.LayeredBitmap.LayerOffset[AIndex] := layerRect.TopLeft;
+  end;
+end;
+
 procedure TImageLayerStateDifference.Init(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
         APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
         APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect);
@@ -2250,7 +2450,7 @@ begin
   inherited Create((AToState as TImageState).saved,false);
   layerId := -1;
   imageDiff := nil;
-  imageOfs := Point(0,0);
+  layerRect := EmptyRect;
   selectionMaskDiff := nil;
   selectionLayerDiff := nil;
 
@@ -2264,7 +2464,7 @@ begin
     if not IsRectEmpty(APreviousImageChangeRect) then
     begin
       imageDiff := TImageDiff.Create(APreviousImage,next.LayerBitmap[curIdx],APreviousImageChangeRect);
-      imageOfs := next.LayerOffset[curIdx];
+      layerRect := GetLayerRect(next,curIdx);
     end;
     if not IsRectEmpty(APreviousSelectionChangeRect) then
       selectionMaskDiff := TGrayscaleImageDiff.Create(APreviousSelection,next.SelectionMask,APreviousSelectionChangeRect);
@@ -2294,7 +2494,11 @@ begin
     idx := lState.LayeredBitmap.GetLayerIndexFromId(layerId);
     if idx = -1 then raise exception.Create('Layer not found');
     if ChangeImageLayer and (lState.LayeredBitmap.LayerOriginalGuid[idx] <> GUID_NULL) then raise exception.Create('Does not apply to originals');
-    if ChangeImageLayer then lState.LayeredBitmap.SetLayerBitmap(idx, imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx],False), True);
+    if ChangeImageLayer then
+    begin
+      EnsureLayerRect(lState,idx);
+      lState.LayeredBitmap.SetLayerBitmap(idx, imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx],False), True);
+    end;
     if ChangeSelectionMask then newSelectionMask := selectionMaskDiff.ApplyCanCreateNew(lState.SelectionMask,False) else newSelectionMask := lState.SelectionMask;
     if ChangeSelectionLayer then newSelectionLayer := selectionLayerDiff.ApplyCanCreateNew(lState.SelectionLayer,False) else newSelectionLayer := lState.SelectionLayer;
     lState.ReplaceSelection(newSelectionMask, newSelectionLayer);
@@ -2314,7 +2518,11 @@ begin
     idx := lState.LayeredBitmap.GetLayerIndexFromId(layerId);
     if idx = -1 then raise exception.Create('Layer not found');
     if ChangeImageLayer and (lState.LayeredBitmap.LayerOriginalGuid[idx] <> GUID_NULL) then raise exception.Create('Does not apply to originals');
-    if ChangeImageLayer then lState.LayeredBitmap.SetLayerBitmap(idx, imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx],True), True);
+    if ChangeImageLayer then
+    begin
+      EnsureLayerRect(lState,idx);
+      lState.LayeredBitmap.SetLayerBitmap(idx, imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx],True), True);
+    end;
     if ChangeSelectionMask then newSelectionMask := selectionMaskDiff.ApplyCanCreateNew(lState.SelectionMask,True) else newSelectionMask := lState.SelectionMask;
     if ChangeSelectionLayer then newSelectionLayer := selectionLayerDiff.ApplyCanCreateNew(lState.SelectionLayer,True) else newSelectionLayer := lState.SelectionLayer;
     lState.ReplaceSelection(newSelectionMask, newSelectionLayer);
@@ -2337,7 +2545,7 @@ begin
   inherited Create(AFromState,AToState);
   layerId := -1;
   imageDiff := nil;
-  imageOfs := Point(0,0);
+  layerRect := EmptyRect;
   selectionMaskDiff := nil;
   selectionLayerDiff := nil;
 
@@ -2353,7 +2561,7 @@ begin
   else
   begin
     imageDiff := TImageDiff.Create(prev.LayerBitmap[prevIdx],next.LayerBitmap[curIdx]);
-    imageOfs := next.LayerOffset[curIdx];
+    layerRect := GetLayerRect(next,curIdx);
     selectionMaskDiff := TGrayscaleImageDiff.Create(prev.SelectionMask,next.SelectionMask);
     selectionLayerDiff := TImageDiff.Create(prev.SelectionLayer,next.SelectionLayer);
   end;

+ 0 - 0
lazpaint/uimageobservation.pas → lazpaint/image/uimageobservation.pas


+ 38 - 0
lazpaint/uimagestate.pas → lazpaint/image/uimagestate.pas

@@ -14,6 +14,8 @@ type
   TImageState = class(TState)
   private
     FLayeredBitmap: TBGRALayeredBitmap;
+    FOnOriginalChange: TEmbeddedOriginalChangeEvent;
+    FOnOriginalEditingChange: TEmbeddedOriginalEditingChangeEvent;
     FSelectionMask: TBGRABitmap;
     FLastSelectionMaskBoundsIsDefined,
     FLastSelectionLayerBoundsIsDefined: boolean;
@@ -40,6 +42,10 @@ type
     function GetLinearBlend: boolean;
     function GetNbLayers: integer;
     function GetWidth: integer;
+    procedure OriginalChange({%H-}ASender: TObject;
+      AOriginal: TBGRALayerCustomOriginal; var ADiff: TBGRAOriginalDiff);
+    procedure OriginalEditingChange({%H-}ASender: TObject;
+      AOriginal: TBGRALayerCustomOriginal);
     procedure SelectImageLayer(AValue: TBGRABitmap);
     procedure SelectImageLayerByIndex(AValue: integer);
     procedure SetLayeredBitmap(AValue: TBGRALayeredBitmap);
@@ -49,6 +55,7 @@ type
     SelectionLayer: TBGRABitmap;
     selectedLayerId: integer;
     filenameUTF8: string;
+    DiscardOriginalDiff: boolean;
 
     // generic state functions
     constructor Create;
@@ -158,6 +165,8 @@ type
     property SelectionMask: TBGRABitmap read GetSelectionMask write SetSelectionMask;
     property LayeredBitmap: TBGRALayeredBitmap read FLayeredBitmap;
     property SelectionTransform: TAffineMatrix read FSelectionTransform write FSelectionTransform;
+    property OnOriginalChange: TEmbeddedOriginalChangeEvent read FOnOriginalChange write FOnOriginalChange;
+    property OnOriginalEditingChange: TEmbeddedOriginalEditingChangeEvent read FOnOriginalEditingChange write FOnOriginalEditingChange;
   end;
 
 implementation
@@ -347,6 +356,23 @@ begin
     result := LayeredBitmap.Width;
 end;
 
+procedure TImageState.OriginalChange(ASender: TObject;
+  AOriginal: TBGRALayerCustomOriginal; var ADiff: TBGRAOriginalDiff);
+begin
+  If Assigned(FOnOriginalChange) then
+  begin
+    if DiscardOriginalDiff then FreeAndNil(ADiff);
+    FOnOriginalChange(self, AOriginal, ADiff);
+  end;
+end;
+
+procedure TImageState.OriginalEditingChange(ASender: TObject;
+  AOriginal: TBGRALayerCustomOriginal);
+begin
+  If Assigned(FOnOriginalEditingChange) then
+    FOnOriginalEditingChange(self, AOriginal);
+end;
+
 procedure TImageState.SelectImageLayer(AValue: TBGRABitmap);
 var
   i: Integer;
@@ -377,7 +403,18 @@ end;
 procedure TImageState.SetLayeredBitmap(AValue: TBGRALayeredBitmap);
 begin
   if FLayeredBitmap=AValue then Exit;
+
+  if Assigned(FLayeredBitmap) then
+  begin
+    FLayeredBitmap.OnOriginalChange:= nil;
+    FLayeredBitmap.OnOriginalEditingChange:= nil;
+  end;
   FLayeredBitmap:=AValue;
+  if Assigned(FLayeredBitmap) then
+  begin
+    FLayeredBitmap.OnOriginalChange:=@OriginalChange;
+    FLayeredBitmap.OnOriginalEditingChange:=@OriginalEditingChange;
+  end;
 end;
 
 function TImageState.SetLayerName(Index: integer; AValue: string): TCustomImageDifference;
@@ -1077,6 +1114,7 @@ begin
   FLastSelectionMaskBoundsIsDefined := false;
   FLastSelectionLayerBoundsIsDefined := false;
   FSelectionTransform := AffineMatrixIdentity;
+  DiscardOriginalDiff := true;
 end;
 
 destructor TImageState.Destroy;

+ 0 - 0
lazpaint/uimagetype.pas → lazpaint/image/uimagetype.pas


+ 5 - 1
lazpaint/ulayeraction.pas → lazpaint/image/ulayeraction.pas

@@ -184,6 +184,9 @@ begin
   if Assigned(FPrediff) then
   begin
     FPrediff.UnapplyTo(CurrentState);
+    if (FPrediff.Kind in [idkChangeImageAndSelection,idkChangeSelection]) and
+       Assigned(FImageState.SelectionMask) then
+      NotifyChange(FImageState.SelectionMask, rect(0,0,FImageState.SelectionMask.Width,FImageState.SelectionMask.Height));
     FreeAndNil(FPrediff);
   end;
   FDone := true;
@@ -665,7 +668,8 @@ begin
         if Assigned(FPrediff) then
         begin
           composedDiff.AddRange(FPrediff);
-          FPrediff := nil;
+          FPrediff.ReleaseDiffs;
+          FreeAndNil(FPrediff);
         end;
         if rasterizeOriginal then
           composedDiff.Add(TDiscardOriginalDifference.Create(CurrentState,

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