Răsfoiți Sursa

added -editor parameter

Johann ELSASS 3 ani în urmă
părinte
comite
94738decb3

+ 14 - 2
lazpaint/image/uimageaction.pas

@@ -8,7 +8,7 @@ interface
 uses
   Classes, SysUtils, FPimage, LazPaintType, BGRABitmap, UImage, UTool,
   UScripting, ULayerAction, UImageType, BGRABitmapTypes, BGRALayerOriginal,
-  BGRASVGOriginal;
+  BGRASVGOriginal, BGRALayers;
 
 type
 
@@ -59,6 +59,7 @@ type
     function DoEnd: boolean;
     procedure SetCurrentBitmap(bmp: TBGRABitmap; AUndoable: boolean;
       ACaption: string = ''; AOpacity: byte = 255);
+    procedure SetCurrentBitmap(bmp: TBGRACustomLayeredBitmap; AUndoable: boolean);
     procedure CropToSelectionAndLayer;
     procedure CropToSelection;
     procedure Flatten;
@@ -110,7 +111,7 @@ implementation
 uses Controls, Dialogs, UResourceStrings, UObject3D,
      ULoadImage, UGraph, UClipboard, Types, BGRAGradientOriginal,
      BGRATransform, ULoading, math, LCVectorClipboard, LCVectorOriginal, LCVectorRectShapes,
-     BGRALayers, BGRAUTF8, UFileSystem, Forms, UTranslation;
+     BGRAUTF8, UFileSystem, Forms, UTranslation;
 
 { TImageActions }
 
@@ -1138,6 +1139,17 @@ begin
   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 ComputeStretchMatrix(ASourceWidth, ASourceHeight: single): TAffineMatrix;

+ 76 - 8
lazpaint/lazpaintinstance.pas

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

+ 11 - 2
lazpaint/lazpainttype.pas

@@ -235,8 +235,17 @@ type
     procedure RestoreMainWindowPosition; virtual; abstract;
     procedure Donate; 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;
     procedure EditSelection; 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}
 {$ENDIF}
 
-const Manual: array[0..68] of string = (
+const Manual: array[0..79] of string = (
 'NAME',
 '       LazPaint - Image editor',
 '',
@@ -38,6 +38,17 @@ const Manual: array[0..68] of string = (
 '       -script FILENAME',
 '              runs the specified Python script. It must have  a  ".py"  exten‐',
 '              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',
 '              quits the program even if no output file was  provided.  Can  be',
 '              useful when only running scripts.',
@@ -88,7 +99,7 @@ function ParamStrUTF8(AIndex: integer): string;
 implementation
 
 uses
-  SysUtils, BGRAUTF8, LazFileUtils, BGRABitmap, BGRABitmapTypes, Dialogs, uparse,
+  SysUtils, BGRAUTF8, LazFileUtils, BGRABitmap, BGRABitmapTypes, BGRALayers, Dialogs, uparse,
   UImage, UImageAction, ULayerAction, UScripting, UPython, Forms, Controls,
   UFileSystem, BGRAIconCursor, UGraph
   {$IFDEF SHOW_MANUAL_IN_WINDOW},StdCtrls{$ENDIF};
@@ -282,6 +293,80 @@ var
     result := true;
   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;
   begin
     inc(i);
@@ -441,6 +526,8 @@ begin
         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 = '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
         begin
           enableScript := true;

+ 4 - 1
lazpaint/uparse.pas

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