Johann ELSASS 4 gadi atpakaļ
vecāks
revīzija
3455acd51a

+ 56 - 23
lazpaint/image/uimageaction.pas

@@ -380,39 +380,72 @@ function TImageActions.ScriptLayerSaveAs(AVars: TVariableSet): TScriptResult;
 var
   name, ext: String;
   layerCopy: TBGRABitmap;
-  layerIdx: Integer;
+  layerIdx, origIdx: Integer;
   writer: TFPCustomImageWriter;
-  imgFormat: TBGRAImageFormat;
+  imgFormat, imgFormatFromName: TBGRAImageFormat;
+  streamOut: TStream;
+  layeredCopy: TBGRALayeredBitmap;
 begin
   name := AVars.Strings['FileName'];
+  imgFormatFromName := SuggestImageFormat(name);
   if AVars.Strings['Format'] = '' then
-    imgFormat := SuggestImageFormat(name)
+    imgFormat := imgFormatFromName
   else
     imgFormat := SuggestImageFormat(AVars.Strings['Format']);
-  if imgFormat = ifUnknown then imgFormat := ifPng;
   ext := UTF8LowerCase(ExtractFileExt(name));
-  if ext = '.tmp' then
+  if imgFormat = ifUnknown then
   begin
-    layerCopy := TBGRABitmap.Create(Image.Width, Image.Height);
-    writer := CreateBGRAImageWriter(imgFormat, true);
-    try
-      layerIdx := Image.CurrentLayerIndex;
-      layerCopy.PutImage(Image.LayerOffset[layerIdx].x, Image.LayerOffset[layerIdx].y,
-        Image.LayerBitmap[layerIdx], dmSet);
-      layerCopy.SaveToFileUTF8(name, writer);
-      result := srOk;
-      AVars.Strings['Result'] := name;
-    except
-      on ex: Exception do
-      begin
-        FInstance.ShowError(rsSave, ex.Message);
-        result := srException;
+    if ext = '.tmp' then
+      imgFormat := ifPng
+    else
+      exit(srInvalidParameters);
+  end;
+  //wont overwrite a file that is probably not an image
+  if FileManager.FileExists(name) and (imgFormatFromName = ifUnknown) then
+    exit(srInvalidParameters);
+  streamOut := FileManager.CreateFileStream(name, fmCreate);
+  try
+    layerIdx := Image.CurrentLayerIndex;
+    if imgFormatFromName in[ifLazPaint, ifPhoxo, ifSvg, ifOpenRaster] then
+    begin
+      layeredCopy := TBGRALayeredBitmap.Create(Image.Width,Image.Height);
+      try
+        if Image.LayerOriginalDefined[layerIdx] and Image.LayerOriginalKnown[layerIdx] then
+        begin
+          origIdx := layeredCopy.AddOriginal(Image.LayerOriginal[layerIdx], false);
+          layeredCopy.AddLayerFromOriginal(layeredCopy.Original[origIdx].Guid,
+            Image.LayerOriginalMatrix[layerIdx], Image.BlendOperation[layerIdx],
+            Image.LayerOpacity[layerIdx]);
+          layeredCopy.LayerName[0] := Image.LayerName[layerIdx];
+        end;
+        layeredCopy.RenderOriginalsIfNecessary;
+        layeredCopy.SaveToStreamAs(streamOut, SuggestImageExtension(imgFormat));
+      finally
+        layeredCopy.Free;
+      end;
+    end else
+    begin
+      layerCopy := TBGRABitmap.Create(Image.Width, Image.Height);
+      writer := CreateBGRAImageWriter(imgFormat, true);
+      try
+        layerCopy.PutImage(Image.LayerOffset[layerIdx].x, Image.LayerOffset[layerIdx].y,
+          Image.LayerBitmap[layerIdx], dmSet);
+        layerCopy.SaveToStream(streamOut, writer);
+        result := srOk;
+        AVars.Strings['Result'] := name;
+      except
+        on ex: Exception do
+        begin
+          FInstance.ShowError(rsSave, ex.Message);
+          result := srException;
+        end;
       end;
+      layerCopy.Free;
+      writer.Free;
     end;
-    layerCopy.Free;
-    writer.Free;
-  end else
-    exit(srInvalidParameters);
+  finally
+    streamOut.Free;
+  end;
 end;
 
 function TImageActions.ScriptLayerSelectId(AVars: TVariableSet): TScriptResult;

+ 2 - 1
lazpaint/lazpaintinstance.pas

@@ -580,9 +580,10 @@ begin
   FLayerStack.AddButton(FMain.LayerVerticalFlip);
   FLayerStack.AddButton(FMain.ToolLayerMapping);
 
-  FLayerStack.AddLayerMenu(FMain.LayerRemoveCurrent);
   FLayerStack.AddLayerMenu(FMain.LayerDuplicate);
+  FLayerStack.AddLayerMenu(FMain.LayerRemoveCurrent);
   FLayerStack.AddLayerMenu(FMain.LayerRasterize);
+  FLayerStack.AddLayerMenu(FMain.LayerExport);
 end;
 
 procedure TLazPaintInstance.CreateToolBox;

+ 6 - 0
lazpaint/lazpaintmainform.lfm

@@ -8633,6 +8633,12 @@ object FMain: TFMain
       OnExecute = FileExportExecute
       ShortCut = 49221
     end
+    object LayerExport: TAction
+      Category = 'Layer'
+      Hint = 'Export...'
+      ImageIndex = 3
+      OnExecute = LayerExportExecute
+    end
   end
   object ColorDialog1: TColorDialog
     Title = 'Choose color'

+ 72 - 0
lazpaint/lazpaintmainform.pas

@@ -23,6 +23,7 @@ type
   { TFMain }
 
   TFMain = class(TForm)
+    LayerExport: TAction;
     FileExport: TAction;
     ExportPictureDialog: TSaveDialog;
     Label_Donate: TLabel;
@@ -481,6 +482,7 @@ type
     procedure ItemDockLayersAndColorsClick(Sender: TObject);
     procedure ItemFullscreenClick(Sender: TObject);
     procedure ItemViewDockToolboxClick(Sender: TObject);
+    procedure LayerExportExecute(Sender: TObject);
     procedure LayerRasterizeUpdate(Sender: TObject);
     procedure LayerZoomExecute(Sender: TObject);
     procedure LayerZoomUpdate(Sender: TObject);
@@ -3608,6 +3610,76 @@ begin
     Layout.ToolBoxDocking := twWindow;
 end;
 
+procedure TFMain.LayerExportExecute(Sender: TObject);
+var
+  topMost: TTopMostInfo;
+  saveDlg: TSaveDialog;
+  layerIdx, mr: Integer;
+  defaultExt, filename: String;
+
+  procedure DoExportLayer(AFilename: string);
+  var
+    vars: TVariableSet;
+  begin
+    FExportInitialDir := extractFilePath(AFilename);
+    if Config.DefaultRememberStartupExportDirectory then
+      Config.SetStartupExportDirectory(FExportInitialDir);
+
+    vars := TVariableSet.Create('LayerSaveAs');
+    vars.Strings['FileName'] := AFilename;
+    CallScriptFunction(vars);
+    vars.Free;
+  end;
+
+begin
+  layerIdx := Image.CurrentLayerIndex;
+  if not Image.LayerOriginalDefined[layerIdx] then
+    defaultExt := '.png' else
+  if Image.LayerOriginalClass[layerIdx] = TBGRALayerSVGOriginal then
+    defaultExt := '.svg'
+  else
+    defaultExt := '.lzp';
+  filename := FileManager.GetValidFilename(Image.LayerName[layerIdx]) + defaultExt;
+  topMost := LazPaintInstance.HideTopmost;
+  saveDlg := ExportPictureDialog;
+  if UseImageBrowser then
+  begin
+    if not assigned(FSaveImage) then
+    begin
+      FSaveImage := TFBrowseImages.Create(self);
+      FSaveImage.LazPaintInstance := LazPaintInstance;
+      FSaveImage.IsSaveDialog := true;
+      FSaveImage.ShowRememberStartupDirectory:= true;
+      if Config.DefaultRememberSaveFormat then
+        FSaveImage.DefaultExtensions:= Config.DefaultSaveExtensions;
+    end;
+    FSaveImage.Filter := saveDlg.Filter;
+    FSaveImage.Caption := saveDlg.Title;
+    FSaveImage.InitialFilename := filename;
+    FSaveImage.DefaultExtension := defaultExt;
+    FSaveImage.InitialDirectory:= FExportInitialDir;
+    FSaveImage.RememberStartDirectory:= FLazPaintInstance.Config.DefaultRememberStartupExportDirectory;
+    FSaveImage.FilterIndex := saveDlg.FilterIndex;
+    mr := FSaveImage.ShowModal;
+    LazPaintInstance.Config.SetRememberStartupExportDirectory(FSaveImage.RememberStartDirectory);
+    if mr = mrOK then
+    begin
+      saveDlg.FilterIndex := FSaveImage.FilterIndex;
+      DoExportLayer(FSaveImage.FileName);
+    end;
+  end else
+  begin
+    saveDlg.FileName := filename;
+    saveDlg.DefaultExt := defaultExt;
+    saveDlg.InitialDir:= FExportInitialDir;
+    if saveDlg.Execute then
+    begin
+      DoExportLayer(saveDlg.FileName);
+    end;
+  end;
+  LazPaintInstance.ShowTopmost(topMost);
+end;
+
 procedure TFMain.LayerRasterizeUpdate(Sender: TObject);
 begin
   LayerRasterize.Enabled := Image.LayerOriginalDefined[Image.CurrentLayerIndex];

+ 16 - 0
lazpaint/ufilesystem.pas

@@ -92,6 +92,7 @@ type
     function DeleteDirectory(APathUTF8: string): boolean;
     function FileExists(AFilenameUTF8: string): boolean;
     procedure DeleteFile(AFilenameUTF8: string);
+    function GetValidFilename(ASuggested: string): string;
   end;
 
 var
@@ -1189,6 +1190,21 @@ begin
   end;
 end;
 
+function TFileManager.GetValidFilename(ASuggested: string): string;
+var
+  i: Integer;
+begin
+  result := ASuggested;
+  for i := 1 to length(result) do
+    case result[i] of
+    '/','\',':','|': result[i] := '-';
+    '?','%','*': result[i] := '_';
+    '"': result[i] := '''';
+    '<': result[i] := '(';
+    '>': result[i] := ')';
+    end;
+end;
+
 initialization
 
   FileManager := TFileManager.Create;