Prechádzať zdrojové kódy

added -editor parameter

Johann ELSASS 3 rokov pred
rodič
commit
94738decb3

+ 14 - 2
lazpaint/image/uimageaction.pas

@@ -8,7 +8,7 @@ interface
 uses
 uses
   Classes, SysUtils, FPimage, LazPaintType, BGRABitmap, UImage, UTool,
   Classes, SysUtils, FPimage, LazPaintType, BGRABitmap, UImage, UTool,
   UScripting, ULayerAction, UImageType, BGRABitmapTypes, BGRALayerOriginal,
   UScripting, ULayerAction, UImageType, BGRABitmapTypes, BGRALayerOriginal,
-  BGRASVGOriginal;
+  BGRASVGOriginal, BGRALayers;
 
 
 type
 type
 
 
@@ -59,6 +59,7 @@ type
     function DoEnd: boolean;
     function DoEnd: boolean;
     procedure SetCurrentBitmap(bmp: TBGRABitmap; AUndoable: boolean;
     procedure SetCurrentBitmap(bmp: TBGRABitmap; AUndoable: boolean;
       ACaption: string = ''; AOpacity: byte = 255);
       ACaption: string = ''; AOpacity: byte = 255);
+    procedure SetCurrentBitmap(bmp: TBGRACustomLayeredBitmap; AUndoable: boolean);
     procedure CropToSelectionAndLayer;
     procedure CropToSelectionAndLayer;
     procedure CropToSelection;
     procedure CropToSelection;
     procedure Flatten;
     procedure Flatten;
@@ -110,7 +111,7 @@ implementation
 uses Controls, Dialogs, UResourceStrings, UObject3D,
 uses Controls, Dialogs, UResourceStrings, UObject3D,
      ULoadImage, UGraph, UClipboard, Types, BGRAGradientOriginal,
      ULoadImage, UGraph, UClipboard, Types, BGRAGradientOriginal,
      BGRATransform, ULoading, math, LCVectorClipboard, LCVectorOriginal, LCVectorRectShapes,
      BGRATransform, ULoading, math, LCVectorClipboard, LCVectorOriginal, LCVectorRectShapes,
-     BGRALayers, BGRAUTF8, UFileSystem, Forms, UTranslation;
+     BGRAUTF8, UFileSystem, Forms, UTranslation;
 
 
 { TImageActions }
 { TImageActions }
 
 
@@ -1138,6 +1139,17 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TImageActions.SetCurrentBitmap(bmp: TBGRACustomLayeredBitmap;
+  AUndoable: boolean);
+begin
+  ToolManager.ToolCloseDontReopen;
+  try
+    image.Assign(bmp,True,AUndoable);
+  finally
+    ToolManager.ToolOpen;
+  end;
+end;
+
 function TImageActions.TryAddLayerFromFile(AFilenameUTF8: string; ALoadedImage: TBGRABitmap = nil): ArrayOfLayerId;
 function TImageActions.TryAddLayerFromFile(AFilenameUTF8: string; ALoadedImage: TBGRABitmap = nil): ArrayOfLayerId;
 
 
   function ComputeStretchMatrix(ASourceWidth, ASourceHeight: single): TAffineMatrix;
   function ComputeStretchMatrix(ASourceWidth, ASourceHeight: single): TAffineMatrix;

+ 76 - 8
lazpaint/lazpaintinstance.pas

@@ -204,7 +204,20 @@ type
     procedure RestoreMainWindowPosition; override;
     procedure RestoreMainWindowPosition; override;
     procedure UseConfig(ini: TInifile); override;
     procedure UseConfig(ini: TInifile); override;
     procedure AssignBitmap(bmp: TBGRABitmap); override;
     procedure AssignBitmap(bmp: TBGRABitmap); override;
-    procedure EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil; ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil; AOnExit: TLazPaintInstanceEvent = nil; ABlackAndWhite: boolean = false); override;
+    procedure AssignBitmap(bmp: TBGRALayeredBitmap); override;
+    function InternalEditBitmap(var bmp: TObject; ConfigStream: TStream = nil;
+      ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil;
+      AOnExit: TLazPaintInstanceEvent = nil;
+      ABlackAndWhite: boolean = false): boolean;
+    function EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil;
+      ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil;
+      AOnExit: TLazPaintInstanceEvent = nil;
+      ABlackAndWhite: boolean = false): boolean; override;
+    function EditBitmap(var bmp: TBGRALayeredBitmap;
+      ConfigStream: TStream = nil; ATitle: String = '';
+      AOnRun: TLazPaintInstanceEvent = nil;
+      AOnExit: TLazPaintInstanceEvent = nil;
+      ABlackAndWhite : boolean = false): boolean; override;
     procedure EditSelection; override;
     procedure EditSelection; override;
     function EditTexture(ASource: TBGRABitmap): TBGRABitmap; override;
     function EditTexture(ASource: TBGRABitmap): TBGRABitmap; override;
     function ProcessCommandLine: boolean; override;
     function ProcessCommandLine: boolean; override;
@@ -518,6 +531,7 @@ end;
 procedure TLazPaintInstance.UseConfig(ini: TInifile);
 procedure TLazPaintInstance.UseConfig(ini: TInifile);
 begin
 begin
   FreeAndNil(FConfig);
   FreeAndNil(FConfig);
+  BlackAndWhite := ini.ReadBool('General','BlackAndWhite',BlackAndWhite);
   FConfig := TLazPaintConfig.Create(ini,LazPaintVersionStr);
   FConfig := TLazPaintConfig.Create(ini,LazPaintVersionStr);
   ToolManager.LoadFromConfig;
   ToolManager.LoadFromConfig;
   FGridVisible := Config.DefaultGridVisible;
   FGridVisible := Config.DefaultGridVisible;
@@ -1228,16 +1242,25 @@ end;
 procedure TLazPaintInstance.AssignBitmap(bmp: TBGRABitmap);
 procedure TLazPaintInstance.AssignBitmap(bmp: TBGRABitmap);
 begin
 begin
   if Assigned(FImageAction) then
   if Assigned(FImageAction) then
-    FImageAction.SetCurrentBitmap(bmp.Duplicate as TBGRABitmap, False);
+    FImageAction.SetCurrentBitmap(bmp.Duplicate, False);
 end;
 end;
 
 
-procedure TLazPaintInstance.EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream; ATitle: String; AOnRun: TLazPaintInstanceEvent; AOnExit: TLazPaintInstanceEvent; ABlackAndWhite: boolean);
+procedure TLazPaintInstance.AssignBitmap(bmp: TBGRALayeredBitmap);
+begin
+  if Assigned(FImageAction) then
+    FImageAction.SetCurrentBitmap(bmp.Duplicate, False);
+end;
+
+function TLazPaintInstance.InternalEditBitmap(var bmp: TObject;
+  ConfigStream: TStream; ATitle: String; AOnRun: TLazPaintInstanceEvent;
+  AOnExit: TLazPaintInstanceEvent; ABlackAndWhite: boolean): boolean;
 var
 var
   subLaz: TLazPaintInstance;
   subLaz: TLazPaintInstance;
   ini : TIniFile;
   ini : TIniFile;
   topmostInfo: TTopMostInfo;
   topmostInfo: TTopMostInfo;
-
+  embeddedImageToBeFreed: boolean;
 begin
 begin
+  result := false;
   try
   try
     subLaz := TLazPaintInstance.Create(True);
     subLaz := TLazPaintInstance.Create(True);
   except
   except
@@ -1251,6 +1274,7 @@ begin
   if ATitle <> '' then subLaz.Title := ATitle;
   if ATitle <> '' then subLaz.Title := ATitle;
   if FMain <> nil then FMain.Enabled := false;
   if FMain <> nil then FMain.Enabled := false;
   topmostInfo:= HideTopmost;
   topmostInfo:= HideTopmost;
+  embeddedImageToBeFreed := false;
   try
   try
     if ConfigStream <> nil then
     if ConfigStream <> nil then
     begin
     begin
@@ -1260,9 +1284,21 @@ begin
       subLaz.UseConfig(ini);
       subLaz.UseConfig(ini);
     end;
     end;
     subLaz.FormsNeeded;
     subLaz.FormsNeeded;
-    if bmp <> nil then subLaz.AssignBitmap(bmp);
+    if bmp <> nil then
+    begin
+      if bmp is TBGRABitmap then
+      begin
+        subLaz.AssignBitmap(TBGRABitmap(bmp));
+        subLaz.EmbeddedImageBackup := TBGRABitmap(bmp);
+      end else
+      if bmp is TBGRALayeredBitmap then
+      begin
+        subLaz.AssignBitmap(TBGRALayeredBitmap(bmp));
+        subLaz.EmbeddedImageBackup := TBGRALayeredBitmap(bmp).ComputeFlatImage;
+        embeddedImageToBeFreed := true;
+      end;
+    end;
     subLaz.AboutText := AboutText;
     subLaz.AboutText := AboutText;
-    subLaz.EmbeddedImageBackup := bmp;
     subLaz.FMain.BorderIcons := subLaz.FMain.BorderIcons - [biMinimize];
     subLaz.FMain.BorderIcons := subLaz.FMain.BorderIcons - [biMinimize];
     if AOnRun <> nil then
     if AOnRun <> nil then
       AOnRun(subLaz);
       AOnRun(subLaz);
@@ -1271,8 +1307,17 @@ begin
       AOnExit(subLaz);
       AOnExit(subLaz);
     if subLaz.EmbeddedResult = mrOk then
     if subLaz.EmbeddedResult = mrOk then
     begin
     begin
-      FreeAndNil(bmp);
-      bmp := subLaz.Image.RenderedImage.Duplicate as TBGRABitmap;
+      if bmp is TBGRALayeredBitmap then
+      begin
+        FreeAndNil(bmp);
+        bmp := subLaz.Image.CurrentState.GetLayeredBitmapCopy;
+      end
+      else if bmp is TBGRABitmap then
+      begin
+        FreeAndNil(bmp);
+        bmp := subLaz.Image.RenderedImage.Duplicate;
+      end;
+      result := true;
     end;
     end;
     if ConfigStream <> nil then
     if ConfigStream <> nil then
     begin
     begin
@@ -1289,9 +1334,32 @@ begin
     FMain.Enabled := true;
     FMain.Enabled := true;
     FMain.BringToFront;
     FMain.BringToFront;
   end;
   end;
+  if embeddedImageToBeFreed then
+    subLaz.EmbeddedImageBackup.Free
+    else subLaz.EmbeddedImageBackup := nil;
   subLaz.Free;
   subLaz.Free;
 end;
 end;
 
 
+function TLazPaintInstance.EditBitmap(var bmp: TBGRABitmap;
+  ConfigStream: TStream; ATitle: String; AOnRun: TLazPaintInstanceEvent;
+  AOnExit: TLazPaintInstanceEvent; ABlackAndWhite: boolean): boolean;
+var bmpObj: TObject;
+begin
+  bmpObj := bmp;
+  result := InternalEditBitmap(bmpObj, ConfigStream, ATitle, AOnRun, AOnExit, ABlackAndWhite);
+  bmp := bmpObj as TBGRABitmap;
+end;
+
+function TLazPaintInstance.EditBitmap(var bmp: TBGRALayeredBitmap;
+  ConfigStream: TStream; ATitle: String; AOnRun: TLazPaintInstanceEvent;
+  AOnExit: TLazPaintInstanceEvent; ABlackAndWhite: boolean): boolean;
+var bmpObj: TObject;
+begin
+  bmpObj := bmp;
+  result := InternalEditBitmap(bmpObj, ConfigStream, ATitle, AOnRun, AOnExit, ABlackAndWhite);
+  bmp := bmpObj as TBGRALayeredBitmap;
+end;
+
 procedure TLazPaintInstance.EditSelection;
 procedure TLazPaintInstance.EditSelection;
 begin
 begin
   try
   try

+ 11 - 2
lazpaint/lazpainttype.pas

@@ -235,8 +235,17 @@ type
     procedure RestoreMainWindowPosition; virtual; abstract;
     procedure RestoreMainWindowPosition; virtual; abstract;
     procedure Donate; virtual; abstract;
     procedure Donate; virtual; abstract;
     procedure UseConfig(ini: TInifile); virtual; abstract;
     procedure UseConfig(ini: TInifile); virtual; abstract;
-    procedure AssignBitmap(bmp: TBGRABitmap); virtual; abstract;
-    procedure EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil; ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil; AOnExit: TLazPaintInstanceEvent = nil; ABlackAndWhite : boolean = false); virtual; abstract;
+    procedure AssignBitmap(bmp: TBGRABitmap); virtual; abstract; overload;
+    procedure AssignBitmap(bmp: TBGRALayeredBitmap); virtual; abstract; overload;
+    function EditBitmap(var bmp: TBGRABitmap; ConfigStream: TStream = nil;
+      ATitle: String = ''; AOnRun: TLazPaintInstanceEvent = nil;
+      AOnExit: TLazPaintInstanceEvent = nil;
+      ABlackAndWhite : boolean = false): boolean; virtual; abstract;
+    function EditBitmap(var bmp: TBGRALayeredBitmap;
+      ConfigStream: TStream = nil; ATitle: String = '';
+      AOnRun: TLazPaintInstanceEvent = nil;
+      AOnExit: TLazPaintInstanceEvent = nil;
+      ABlackAndWhite : boolean = false): boolean; virtual; abstract;
     function EditTexture(ASource: TBGRABitmap): TBGRABitmap; virtual; abstract;
     function EditTexture(ASource: TBGRABitmap): TBGRABitmap; virtual; abstract;
     procedure EditSelection; virtual; abstract;
     procedure EditSelection; virtual; abstract;
     function ProcessCommandLine: boolean; virtual; abstract;
     function ProcessCommandLine: boolean; virtual; abstract;

+ 89 - 2
lazpaint/ucommandline.pas

@@ -11,7 +11,7 @@ uses classes, LazpaintType, uresourcestrings, LCLStrConsts;
   {$DEFINE SHOW_MANUAL_IN_WINDOW}
   {$DEFINE SHOW_MANUAL_IN_WINDOW}
 {$ENDIF}
 {$ENDIF}
 
 
-const Manual: array[0..68] of string = (
+const Manual: array[0..79] of string = (
 'NAME',
 'NAME',
 '       LazPaint - Image editor',
 '       LazPaint - Image editor',
 '',
 '',
@@ -38,6 +38,17 @@ const Manual: array[0..68] of string = (
 '       -script FILENAME',
 '       -script FILENAME',
 '              runs the specified Python script. It must have  a  ".py"  exten‐',
 '              runs the specified Python script. It must have  a  ".py"  exten‐',
 '              sion.',
 '              sion.',
+'',
+'       -editor default|CONFIGFILE|OPTION1,OPTION2...',
+'              shows the image editor with validate and cancel buttons.  If the',
+'              validate button is used,  the rest of the commands are executed.',
+'              Otherwise the program stops.',
+'',
+'              Examples:',
+'              -editor default',
+'              -editor /Users/me/lazpaintCustom.cfg',
+'              -editor [Window]ColorWindowVisible=0,LayerWindowVisible=0',
+'',
 '       -quit',
 '       -quit',
 '              quits the program even if no output file was  provided.  Can  be',
 '              quits the program even if no output file was  provided.  Can  be',
 '              useful when only running scripts.',
 '              useful when only running scripts.',
@@ -88,7 +99,7 @@ function ParamStrUTF8(AIndex: integer): string;
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, BGRAUTF8, LazFileUtils, BGRABitmap, BGRABitmapTypes, Dialogs, uparse,
+  SysUtils, BGRAUTF8, LazFileUtils, BGRABitmap, BGRABitmapTypes, BGRALayers, Dialogs, uparse,
   UImage, UImageAction, ULayerAction, UScripting, UPython, Forms, Controls,
   UImage, UImageAction, ULayerAction, UScripting, UPython, Forms, Controls,
   UFileSystem, BGRAIconCursor, UGraph
   UFileSystem, BGRAIconCursor, UGraph
   {$IFDEF SHOW_MANUAL_IN_WINDOW},StdCtrls{$ENDIF};
   {$IFDEF SHOW_MANUAL_IN_WINDOW},StdCtrls{$ENDIF};
@@ -282,6 +293,80 @@ var
     result := true;
     result := true;
   end;
   end;
 
 
+  function MakeConfigFromFuncParam: string;
+  var
+    cfg: TStringList;
+    curSection, newSection, p, param: string;
+  begin
+    cfg := TStringList.Create;
+    curSection := '[General]';
+    cfg.Add(curSection);
+    try
+      for p in funcParams do
+      begin
+        param := p;
+        if param.StartsWith('[') then
+        begin
+          if param.IndexOf(']') <> -1 then
+          begin
+            newSection := param.Substring(0, param.IndexOf(']')+1);
+            param := param.Substring(length(newSection));
+          end else
+          begin
+            newSection := param;
+            param := '';
+          end;
+          if newSection <> curSection then
+          begin
+            curSection := newSection;
+            cfg.Add(curSection);
+          end;
+        end;
+        if param<>'' then
+        begin
+          if param.IndexOf('=') = -1 then
+            raise Exception.Create(SParExpected.Replace('%s', '"="'));
+          cfg.Add(param);
+        end;
+      end;
+    finally
+      result := cfg.Text;
+      cfg.Free;
+    end;
+  end;
+
+  function DoEditor: boolean;
+  var
+    iniStream: TStream;
+    bmp: TBGRALayeredBitmap;
+  begin
+    result := false;
+    funcParams := SimpleParseFuncParam(CommandStr);
+    if (length(funcParams) = 1) and
+       ((ExtractFileExt(funcParams[0])='.ini') or (ExtractFileExt(funcParams[0])='.cfg')) then
+      iniStream := FileManager.CreateFileStream(funcParams[0], fmOpenRead)
+    else if (length(funcParams) = 1) and (funcParams[0] = 'default') then
+      iniStream := TMemoryStream.Create
+    else
+      iniStream := TStringStream.Create(MakeConfigFromFuncParam);
+
+    bmp := instance.Image.CurrentState.GetLayeredBitmapCopy;
+    try
+      if instance.EditBitmap(bmp, iniStream) then
+      begin
+        instance.Image.CurrentState.Assign(bmp, true);
+        result := true;
+      end
+      else
+      begin
+        bmp.Free;
+        quitQuery := true;
+      end;
+    finally
+      FileManager.CancelStreamAndFree(iniStream);
+    end;
+  end;
+
   function NextAsFuncParam: boolean;
   function NextAsFuncParam: boolean;
   begin
   begin
     inc(i);
     inc(i);
@@ -441,6 +526,8 @@ begin
         if lowerCmd = 'new' then begin if not NextAsFuncParam or not DoNew then exit end else
         if lowerCmd = 'new' then begin if not NextAsFuncParam or not DoNew then exit end else
         if lowerCmd.StartsWith('screenshot(') then begin if not DoScreenShot then exit end else
         if lowerCmd.StartsWith('screenshot(') then begin if not DoScreenShot then exit end else
         if lowerCmd = 'screenshot' then begin if not NextAsFuncParam or not DoScreenShot then exit end else
         if lowerCmd = 'screenshot' then begin if not NextAsFuncParam or not DoScreenShot then exit end else
+        if lowerCmd.StartsWith('editor(') then begin if not DoEditor then exit end else
+        if lowerCmd = 'editor' then begin if not NextAsFuncParam or not DoEditor then exit end else
         if lowerCmd = 'script' then
         if lowerCmd = 'script' then
         begin
         begin
           enableScript := true;
           enableScript := true;

+ 4 - 1
lazpaint/uparse.pas

@@ -18,7 +18,7 @@ function SimpleParseFuncParam(str: string): arrayOfString;
 implementation
 implementation
 
 
 function SimpleParseFuncParam(str: string): arrayOfString;
 function SimpleParseFuncParam(str: string): arrayOfString;
-var idxOpen,start,cur: integer;
+var idxOpen,start,cur,bracketDepth: integer;
 begin
 begin
     result := nil;
     result := nil;
     idxOpen := pos('(',str);
     idxOpen := pos('(',str);
@@ -27,8 +27,11 @@ begin
     else
     else
       start := idxOpen+1;
       start := idxOpen+1;
     cur := start;
     cur := start;
+    bracketDepth := 0;
     while cur <= length(str) do
     while cur <= length(str) do
     begin
     begin
+       if str[cur] = '(' then inc(bracketDepth) else
+       if (str[cur] = ')') and (bracketDepth > 0) then dec(bracketDepth) else
        if str[cur] in[',',')'] then
        if str[cur] in[',',')'] then
        begin
        begin
          setlength(result,length(result)+1);
          setlength(result,length(result)+1);