Bläddra i källkod

merge vector layers

circular17 6 år sedan
förälder
incheckning
899e0947df

+ 1 - 0
lazpaint/image/uimageaction.pas

@@ -1074,6 +1074,7 @@ procedure TImageActions.MergeLayerOver;
 begin
   if (Image.CurrentLayerIndex <> -1) and (image.NbLayers > 1) then
   begin
+    ChooseTool(ptHand);
     Image.MergeLayerOver;
     FInstance.ScrollLayerStackOnItem(Image.CurrentLayerIndex);
   end;

+ 51 - 0
lazpaint/image/uimagediff.pas

@@ -483,6 +483,7 @@ type
     layerOverIndex: integer;
     layerOverCompressedBackup: TStoredLayer;
     layerUnderCompressedBackup: TStoredLayer;
+    mergeVectorial: boolean;
     constructor Create(ADestination: TState; ALayerOverIndex: integer);
     function UsedMemory: int64; override;
     function TryCompress: boolean; override;
@@ -929,6 +930,22 @@ begin
     shape.BackFill.Transform(imgState.LayeredBitmap.LayerOriginalMatrix[ALayerIndex]);
     orig.AddShape(shape);
   end else
+  if imgState.LayeredBitmap.LayerOriginalClass[ALayerIndex]=TBGRALayerImageOriginal then
+  begin
+    temp := (imgState.LayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerImageOriginal).GetImageCopy;
+    if temp <> nil then
+    begin
+      shape := TRectShape.Create(orig);
+      shape.QuickDefine(PointF(-0.5,-0.5),PointF(temp.Width-0.5,temp.Height-0.5));
+      shape.PenStyle := ClearPenStyle;
+      shape.BackFill.SetTexture(temp,AffineMatrixIdentity,255,trNone);
+      temp.FreeReference;
+      shape.Transform(imgState.LayeredBitmap.LayerOriginalMatrix[ALayerIndex]);
+      with imgState.LayeredBitmap.LayerOffset[ALayerIndex] do
+        shape.Transform(AffineMatrixTranslation(-X-FSourceBounds.Left,-Y-FSourceBounds.Top));
+      orig.AddShape(shape);
+    end;
+  end else
   begin
     source := imgState.LayeredBitmap.LayerBitmap[ALayerIndex];
     if not source.Empty then
@@ -2107,6 +2124,12 @@ begin
     previousActiveLayerId:= LayerUniqueId[imgDest.SelectedImageLayerIndex];
     layerOverCompressedBackup := TStoredLayer.Create(imgDest.LayeredBitmap, ALayerOverIndex, true);
     layerUnderCompressedBackup := TStoredLayer.Create(imgDest.LayeredBitmap, ALayerOverIndex-1, true);
+    mergeVectorial := (LayerOriginalClass[ALayerOverIndex] = TVectorOriginal) and
+       (LayerOriginalClass[ALayerOverIndex-1] = TVectorOriginal) and
+       (TVectorOriginal(LayerOriginal[ALayerOverIndex]).GetShapesCost +
+        TVectorOriginal(LayerOriginal[ALayerOverIndex-1]).GetShapesCost <= MediumShapeCost) and
+        (BlendOperation[ALayerOverIndex] = boTransparent) and
+        (BlendOperation[ALayerOverIndex-1] = boTransparent);
   end;
 
   //select layer under and merge
@@ -2128,6 +2151,10 @@ end;
 procedure TMergeLayerOverStateDifference.ApplyTo(AState: TState);
 var
   merged: TBGRABitmap;
+  origOver, origUnder, mergedOriginal: TVectorOriginal;
+  i: Integer;
+  mOver, mUnder: TAffineMatrix;
+  s: TVectorShape;
 begin
   inherited ApplyTo(AState);
   with AState as TImageState do
@@ -2135,6 +2162,30 @@ begin
     if layerOverIndex >= NbLayers then exit;
 
      SelectedImageLayerIndex := layerOverIndex-1;
+     if mergeVectorial then
+     begin
+       mergedOriginal := TVectorOriginal.Create;
+       origOver := LayerOriginal[layerOverIndex] as TVectorOriginal;
+       mOver := LayeredBitmap.LayerOriginalMatrix[layerOverIndex];
+       origUnder := LayerOriginal[layerOverIndex-1] as TVectorOriginal;
+       mUnder := LayeredBitmap.LayerOriginalMatrix[layerOverIndex-1];
+       for i := 0 to origUnder.ShapeCount-1 do
+       begin
+         s := origUnder.Shape[i].Duplicate;
+         s.Transform(mUnder);
+         mergedOriginal.AddShape(s);
+       end;
+       for i := 0 to origOver.ShapeCount-1 do
+       begin
+         s := origOver.Shape[i].Duplicate;
+         s.Transform(mOver);
+         mergedOriginal.AddShape(s);
+       end;
+       LayeredBitmap.AddOriginal(mergedOriginal);
+       LayeredBitmap.LayerOriginalGuid[layerOverIndex-1] := mergedOriginal.Guid;
+       LayeredBitmap.LayerOriginalMatrix[layerOverIndex-1] := AffineMatrixIdentity;
+       LayeredBitmap.RenderLayerFromOriginal(layerOverIndex-1);
+     end else
      if (LayerBitmap[layerOverIndex-1].Width <> Width) or
         (LayerBitmap[layerOverIndex-1].Height <> Height) or
         (LayerOffset[layerOverIndex-1].X <> 0) or

+ 1 - 18
lazpaint/tools/utoolvectorial.pas

@@ -36,7 +36,6 @@ type
     FLastPos: TPointF;
     FLastShapeTransform: TAffineMatrix;
     FUseOriginal: boolean;
-    function GetShapesCost(AOriginal: TVectorOriginal): integer;
     function AlwaysRasterizeShape: boolean; virtual;
     function CreateShape: TVectorShape; virtual; abstract;
     function UseOriginal: boolean; virtual;
@@ -1479,22 +1478,6 @@ begin
   result := FShape = nil;
 end;
 
-function TVectorialTool.GetShapesCost(AOriginal: TVectorOriginal): integer;
-var
-  i: Integer;
-begin
-  result := 0;
-  for i := 0 to AOriginal.ShapeCount-1 do
-    if (AOriginal.Shape[i] is TPhongShape) or
-       (AOriginal.Shape[i] is TTextShape) then
-       inc(result, 5)
-    else if ((vsfBackFill in AOriginal.Shape[i].Fields) and
-       (AOriginal.Shape[i].BackFill.FillType = vftGradient)) then
-       inc(result,15)
-    else
-      inc(result,2);
-end;
-
 function TVectorialTool.AlwaysRasterizeShape: boolean;
 begin
   result := false;
@@ -1647,7 +1630,7 @@ begin
   if FShape=nil then
   begin
     if UseOriginal and
-      (GetShapesCost(Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal) >= 50) then
+      ((Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal).GetShapesCost >= MediumShapeCost) then
     begin
       MessagePopup(rsTooManyShapesInLayer, 3000);
     end

+ 34 - 0
lazpaintcontrols/lcvectororiginal.pas

@@ -15,6 +15,7 @@ const
   InfiniteRect : TRect = (Left: -MaxLongInt; Top: -MaxLongInt; Right: MaxLongInt; Bottom: MaxLongInt);
   EmptyTextureId = 0;
   DefaultShapeOutlineWidth = 2;
+  MediumShapeCost = 100;
 
 type
   TVectorOriginal = class;
@@ -224,6 +225,7 @@ type
     function Duplicate: TVectorShape;
     class function StorageClassName: RawByteString; virtual; abstract;
     function GetIsSlow(const {%H-}AMatrix: TAffineMatrix): boolean; virtual;
+    function GetGenericCost: integer; virtual;
     function GetUsedTextures: ArrayOfBGRABitmap; virtual;
     procedure Transform(const AMatrix: TAffineMatrix); virtual;
     class function Fields: TVectorShapeFields; virtual;
@@ -359,6 +361,7 @@ type
     procedure SelectShape(AIndex: integer); overload;
     procedure SelectShape(AShape: TVectorShape); overload;
     procedure DeselectShape;
+    function GetShapesCost: integer;
     procedure MouseClick(APoint: TPointF);
     procedure Render(ADest: TBGRABitmap; ARenderOffset: TPoint; AMatrix: TAffineMatrix; ADraft: boolean); override;
     procedure ConfigureEditor(AEditor: TBGRAOriginalEditor); override;
@@ -1204,6 +1207,28 @@ begin
   result := false;
 end;
 
+function TVectorShape.GetGenericCost: integer;
+begin
+  if vsfBackFill in Fields then
+  begin
+    case BackFill.FillType of
+    vftGradient: result := 25;
+    vftTexture: result := 10;
+    vftSolid: result := 4;
+    else {vftNone} result := 1;
+    end
+  end else
+  if vsfPenStyle in Fields then
+  begin
+    if PenStyleEqual(PenStyle, SolidPenStyle) or
+       PenStyleEqual(PenStyle, ClearPenStyle) then
+       result := 1
+    else
+      result := 2;
+  end else
+    result := 1;
+end;
+
 function TVectorShape.GetUsedTextures: ArrayOfBGRABitmap;
 var
   f: TVectorShapeFields;
@@ -2575,6 +2600,15 @@ begin
   SelectShape(nil);
 end;
 
+function TVectorOriginal.GetShapesCost: integer;
+var
+  i: Integer;
+begin
+  result := 0;
+  for i := 0 to ShapeCount-1 do
+    inc(result, Shape[i].GetGenericCost);
+end;
+
 procedure TVectorOriginal.MouseClick(APoint: TPointF);
 var
   i: LongInt;

+ 6 - 0
lazpaintcontrols/lcvectorrectshapes.pas

@@ -179,6 +179,7 @@ type
     function GetRenderBounds({%H-}ADestRect: TRect; AMatrix: TAffineMatrix; AOptions: TRenderBoundsOptions = []): TRectF; override;
     function PointInShape(APoint: TPointF): boolean; override;
     function GetIsSlow(const AMatrix: TAffineMatrix): boolean; override;
+    function GetGenericCost: integer; override;
     procedure Transform(const AMatrix: TAffineMatrix); override;
     class function StorageClassName: RawByteString; override;
     property ShapeKind: TPhongShapeKind read FShapeKind write SetShapeKind;
@@ -1655,6 +1656,11 @@ begin
   result := ab.Surface > 320*240;
 end;
 
+function TPhongShape.GetGenericCost: integer;
+begin
+  Result:= 10;
+end;
+
 procedure TPhongShape.Transform(const AMatrix: TAffineMatrix);
 begin
   BeginUpdate(TPhongShapeDiff);

+ 6 - 0
lazpaintcontrols/lcvectortextshapes.pas

@@ -153,6 +153,7 @@ type
     function GetRenderBounds({%H-}ADestRect: TRect; AMatrix: TAffineMatrix; AOptions: TRenderBoundsOptions = []): TRectF; override;
     function PointInShape(APoint: TPointF): boolean; override;
     function GetIsSlow(const {%H-}AMatrix: TAffineMatrix): boolean; override;
+    function GetGenericCost: integer; override;
     procedure MouseMove({%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); override;
     procedure MouseDown({%H-}RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); override;
     procedure MouseUp({%H-}RightButton: boolean; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: single; var {%H-}ACursor: TOriginalEditorCursor; var {%H-}AHandled: boolean); override;
@@ -1472,6 +1473,11 @@ begin
   Result:= true;
 end;
 
+function TTextShape.GetGenericCost: integer;
+begin
+  Result:= 10;
+end;
+
 procedure TTextShape.MouseMove(Shift: TShiftState; X, Y: single;
   var ACursor: TOriginalEditorCursor; var AHandled: boolean);
 begin