1 // SPDX-License-Identifier: GPL-3.0-only
2 unit UImageDiff;
3
4 {$mode objfpc}
5
6 interface
7
8 uses
9 Classes, SysUtils, UStateType, BGRABitmap, BGRABitmapTypes, BGRALayers,
10 BGRALayerOriginal, LCVectorOriginal, UImageState;
11
IsInverseImageDiffnull12 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
TryCombineImageDiffnull13 function TryCombineImageDiff(ANewDiff, APrevDiff: TCustomImageDifference): boolean;
14
15 type
16 { TInversibleStateDifference }
17
18 TInversibleStateDifference = class(TCustomImageDifference)
19 private
20 FAction: TInversibleAction;
21 FLayerIndex: integer;
22 public
23 constructor Create(AState: TState; AAction: TInversibleAction; ALayerIndex : integer = -1);
24 procedure ApplyTo(AState: TState); override;
25 procedure UnApplyTo(AState: TState); override;
26 procedure ApplyAction(AState: TState; AAction: TInversibleAction; AInverse: boolean);
ToStringnull27 function ToString: ansistring; override;
28 property Action: TInversibleAction read FAction write FAction;
29 property LayerIndex: integer read FLayerIndex;
30 end;
31
32 { TSelectCurrentLayer }
33
34 TSelectCurrentLayer = class(TCustomImageDifference)
35 private
36 FPrevLayerIndex, FNewLayerIndex: integer;
37 protected
GetImageDifferenceKindnull38 function GetImageDifferenceKind: TImageDifferenceKind; override;
39 public
40 constructor Create(AState: TState; ANewLayerIndex: integer);
41 procedure ApplyTo(AState: TState); override;
42 procedure UnApplyTo(AState: TState); override;
ToStringnull43 function ToString: ansistring; override;
44 end;
45
46 type
47 { TImageLayerStateDifference }
48
49 TImageLayerStateDifference = class(TCustomImageDifference)
50 private
GetChangeImageLayernull51 function GetChangeImageLayer: boolean;
GetChangeSelectionLayernull52 function GetChangeSelectionLayer: boolean;
GetChangeSelectionMasknull53 function GetChangeSelectionMask: boolean;
54 protected
GetImageDifferenceKindnull55 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull56 function GetIsIdentity: boolean; override;
GetChangingBoundsDefinednull57 function GetChangingBoundsDefined: boolean; override;
GetChangingBoundsnull58 function GetChangingBounds: TRect; override;
GetLayerRectnull59 function GetLayerRect(AState: TImageState; AIndex: integer): TRect;
60 procedure EnsureLayerRect(AState: TImageState; AIndex: integer);
61 procedure Init(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
62 APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
63 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect);
64 public
65 layerId: integer;
66 layerRect: TRect;
67 imageDiff, selectionLayerDiff: TImageDiff;
68 selectionMaskDiff: TImageDiff;
TryCompressnull69 function TryCompress: boolean; override;
70 procedure ApplyTo(AState: TState); override;
71 procedure UnapplyTo(AState: TState); override;
UsedMemorynull72 function UsedMemory: int64; override;
73 constructor Create(AFromState, AToState: TState);
74 constructor Create(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageDefined: boolean;
75 APreviousSelection: TBGRABitmap; APreviousSelectionDefined: boolean;
76 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerDefined: boolean); overload;
77 constructor Create(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
78 APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
79 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect); overload;
ToStringnull80 function ToString: ansistring; override;
81 destructor Destroy; override;
82 property ChangeImageLayer: boolean read GetChangeImageLayer;
83 property ChangeSelectionMask: boolean read GetChangeSelectionMask;
84 property ChangeSelectionLayer: boolean read GetChangeSelectionLayer;
85 end;
86
87 { TSetLayerNameStateDifference }
88
89 TSetLayerNameStateDifference = class(TCustomImageDifference)
90 private
91 previousName,nextName: ansistring;
92 layerId: integer;
93 protected
GetImageDifferenceKindnull94 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull95 function GetIsIdentity: boolean; override;
96 public
97 constructor Create(ADestination: TState; ALayerId: integer; ANewName: ansistring);
98 procedure ApplyTo(AState: TState); override;
99 procedure UnapplyTo(AState: TState); override;
ToStringnull100 function ToString: ansistring; override;
101 end;
102
103 { TSetLayerOpacityStateDifference }
104
105 TSetLayerOpacityStateDifference = class(TCustomImageDifference)
106 private
107 previousOpacity,nextOpacity: byte;
108 layerId: integer;
109 layerBounds: TRect;
110 protected
GetImageDifferenceKindnull111 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetChangingBoundsnull112 function GetChangingBounds: TRect; override;
GetChangingBoundsDefinednull113 function GetChangingBoundsDefined: boolean; override;
GetIsIdentitynull114 function GetIsIdentity: boolean; override;
115 public
116 constructor Create(ADestination: TState; ALayerId: integer; ANewOpacity: byte);
117 procedure ApplyTo(AState: TState); override;
118 procedure UnapplyTo(AState: TState); override;
119 end;
120
121 { TSetLayerOffsetStateDifference }
122
123 TSetLayerOffsetStateDifference = class(TCustomImageDifference)
124 private
125 previousOffset,nextOffset: TPoint;
126 layerId: integer;
127 protected
GetImageDifferenceKindnull128 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull129 function GetIsIdentity: boolean; override;
130 public
131 constructor Create(ADestination: TState; ALayerId: integer; ANewOffset: TPoint);
132 procedure ApplyTo(AState: TState); override;
133 procedure UnapplyTo(AState: TState); override;
134 end;
135
136 { TSetLayerMatrixDifference }
137
138 TSetLayerMatrixDifference = class(TCustomImageDifference)
139 private
140 previousMatrix,nextMatrix: TAffineMatrix;
141 layerId: integer;
142 protected
GetImageDifferenceKindnull143 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull144 function GetIsIdentity: boolean; override;
145 public
146 constructor Create({%H-}ADestination: TState; ALayerId: integer; APreviousMatrix, ANextMatrix: TAffineMatrix);
147 procedure ApplyTo(AState: TState); override;
148 procedure UnapplyTo(AState: TState); override;
149 end;
150
151 { TSetLayerRegistryDifference }
152
153 TSetLayerRegistryDifference = class(TCustomImageDifference)
154 private
155 identifier: string;
156 previousValue,nextValue: RawByteString;
157 layerId: integer;
158 protected
GetImageDifferenceKindnull159 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull160 function GetIsIdentity: boolean; override;
GetCostnull161 function GetCost: integer; override;
162 public
163 constructor Create(ADestination: TState; ALayerId: integer; AIdentifier: string; ANewValue: RawByteString; AApplyNow: boolean);
164 procedure ApplyTo(AState: TState); override;
165 procedure UnapplyTo(AState: TState); override;
166 end;
167
168 { TSetImageRegistryDifference }
169
170 TSetImageRegistryDifference = class(TCustomImageDifference)
171 private
172 identifier: string;
173 previousValue,nextValue: RawByteString;
174 protected
GetImageDifferenceKindnull175 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull176 function GetIsIdentity: boolean; override;
GetCostnull177 function GetCost: integer; override;
178 public
179 constructor Create(ADestination: TState; AIdentifier: string; ANewValue: RawByteString; AApplyNow: boolean);
180 procedure ApplyTo(AState: TState); override;
181 procedure UnapplyTo(AState: TState); override;
182 end;
183
184 { TSetSelectionTransformDifference }
185
186 TSetSelectionTransformDifference = class(TCustomImageDifference)
187 private
188 previousMatrix,nextMatrix: TAffineMatrix;
189 protected
GetImageDifferenceKindnull190 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull191 function GetIsIdentity: boolean; override;
192 public
193 constructor Create({%H-}ADestination: TState; ANextMatrix: TAffineMatrix);
194 procedure ApplyTo(AState: TState); override;
195 procedure UnapplyTo(AState: TState); override;
196 end;
197
198 { TApplyLayerOffsetStateDifference }
199
200 TApplyLayerOffsetStateDifference = class(TCustomImageDifference)
201 private
202 previousBounds,nextBounds,unchangedBounds: TRect;
203 clippedData: TMemoryStream;
204 useOriginal: boolean;
205 previousOriginalRenderStatus: TOriginalRenderStatus;
206 layerId: integer;
207 previousLayerOffset: TPoint;
208 protected
GetImageDifferenceKindnull209 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull210 function GetIsIdentity: boolean; override;
GetChangingBoundsDefinednull211 function GetChangingBoundsDefined: boolean; override;
GetChangingBoundsnull212 function GetChangingBounds: TRect; override;
213 public
214 constructor Create(ADestination: TState; ALayerId: integer; AOffsetX, AOffsetY: integer; AApplyNow: boolean);
215 destructor Destroy; override;
216 procedure ApplyTo(AState: TState); override;
217 procedure UnapplyTo(AState: TState); override;
218 end;
219
220 { TSelectionTransformDifference }
221
222 TSelectionTransformDifference = class(TCustomImageDifference)
223 FPrevTransform: TAffineMatrix;
224 FPrevSelectionMask, FPrevSelectionLayer: TStoredImage;
225 protected
GetImageDifferenceKindnull226 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetIsIdentitynull227 function GetIsIdentity: boolean; override;
228 public
229 constructor Create(ADestination: TState; AApplyNow: boolean);
TryCompressnull230 function TryCompress: boolean; override;
231 destructor Destroy; override;
232 procedure ApplyTo(AState: TState); override;
233 procedure UnapplyTo(AState: TState); override;
234 end;
235
236 { TSetLayerVisibleStateDifference }
237
238 TSetLayerVisibleStateDifference = class(TCustomImageDifference)
239 private
240 previousVisible,nextVisible: boolean;
241 layerId: integer;
242 layerBounds: TRect;
243 protected
GetImageDifferenceKindnull244 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetChangingBoundsnull245 function GetChangingBounds: TRect; override;
GetChangingBoundsDefinednull246 function GetChangingBoundsDefined: boolean; override;
GetIsIdentitynull247 function GetIsIdentity: boolean; override;
248 public
249 constructor Create(ADestination: TState; ALayerId: integer; ANewVisible: boolean);
250 procedure ApplyTo(AState: TState); override;
251 procedure UnapplyTo(AState: TState); override;
252 end;
253
254 { TSetLayerBlendOpStateDifference }
255
256 TSetLayerBlendOpStateDifference = class(TCustomImageDifference)
257 private
258 previousBlendOp,nextBlendOp: TBlendOperation;
259 layerId: integer;
260 layerBounds: TRect;
261 protected
GetImageDifferenceKindnull262 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetChangingBoundsnull263 function GetChangingBounds: TRect; override;
GetChangingBoundsDefinednull264 function GetChangingBoundsDefined: boolean; override;
GetIsIdentitynull265 function GetIsIdentity: boolean; override;
266 public
267 constructor Create(ADestination: TState; ALayerId: integer; ANewBlendOp: TBlendOperation);
268 procedure ApplyTo(AState: TState); override;
269 procedure UnapplyTo(AState: TState); override;
270 end;
271
272 { TAddLayerStateDifference }
273
274 TAddLayerStateDifference = class(TCustomImageDifference)
275 protected
GetImageDifferenceKindnull276 function GetImageDifferenceKind: TImageDifferenceKind; override;
277 public
278 layerId: integer;
279 content: TStoredImage;
280 previousActiveLayerId: integer;
281 name: ansistring;
282 offset: TPoint;
283 blendOp: TBlendOperation;
284 opacity: byte;
UsedMemorynull285 function UsedMemory: int64; override;
TryCompressnull286 function TryCompress: boolean; override;
287 procedure ApplyTo(AState: TState); override;
288 procedure UnapplyTo(AState: TState); override;
289 constructor Create(ADestination: TState; AContent: TBGRABitmap; AName: ansistring;
290 AOffset: TPoint; ABlendOp: TBlendOperation; AOpacity: byte);
291 destructor Destroy; override;
292 end;
293
294 { TAddLayerFromOwnedOriginalStateDifference }
295
296 TAddLayerFromOwnedOriginalStateDifference = class(TCustomImageDifference)
297 protected
GetImageDifferenceKindnull298 function GetImageDifferenceKind: TImageDifferenceKind; override;
299 procedure Uncompress;
300 public
301 layerId: integer;
302 originalData: TStream;
303 compressedData: TStream;
304 previousActiveLayerId: integer;
305 name: ansistring;
306 blendOp: TBlendOperation;
307 opacity: byte;
308 matrix: TAffineMatrix;
UsedMemorynull309 function UsedMemory: int64; override;
TryCompressnull310 function TryCompress: boolean; override;
311 procedure ApplyTo(AState: TState); override;
312 procedure UnapplyTo(AState: TState); override;
313 constructor Create(ADestination: TState; AOriginal: TBGRALayerCustomOriginal;
314 AName: ansistring; ABlendOp: TBlendOperation; AMatrix: TAffineMatrix; AOpacity: Byte = 255);
315 destructor Destroy; override;
316 end;
317
318 { TRemoveLayerStateDifference }
319
320 TRemoveLayerStateDifference = class(TCustomImageDifference)
321 protected
322 FContent: TStoredLayer;
323 FNextActiveLayerId: integer;
GetImageDifferenceKindnull324 function GetImageDifferenceKind: TImageDifferenceKind; override;
325 public
UsedMemorynull326 function UsedMemory: int64; override;
TryCompressnull327 function TryCompress: boolean; override;
328 procedure ApplyTo(AState: TState); override;
329 procedure UnapplyTo(AState: TState); override;
330 constructor Create(AState: TState; AApplyNow: boolean);
331 destructor Destroy; override;
332 property nextActiveLayerId: integer read FNextActiveLayerId write FNextActiveLayerId;
333 end;
334
335 { TReplaceLayerByOriginalDifference }
336
337 TReplaceLayerByOriginalDifference = class(TCustomImageDifference)
338 private
GetLayerIdnull339 function GetLayerId: integer;
340 protected
341 FPreviousLayerContent: TStoredLayer;
342 FPrevMatrix,FNextMatrix: TAffineMatrix;
343 FSourceBounds: TRect;
344 FSourceLayerId: integer;
345 FOriginalGuid: TGUID;
GetImageDifferenceKindnull346 function GetImageDifferenceKind: TImageDifferenceKind; override;
CreateOriginalnull347 function CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal; virtual; abstract;
ShouldRenderOriginalnull348 function ShouldRenderOriginal: boolean; virtual;
349 procedure StorePreviousLayer(AImgState: TImageState; ALayerIndex: integer;
350 AAlwaysStoreBitmap: boolean); virtual;
351 procedure CustomUnapplyto(AState: TState);
352 public
353 constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
UsedMemorynull354 function UsedMemory: int64; override;
TryCompressnull355 function TryCompress: boolean; override;
356 procedure ApplyTo(AState: TState); override;
357 procedure UnapplyTo(AState: TState); override;
358 property LayerId: integer read GetLayerId;
359 property prevMatrix: TAffineMatrix read FPrevMatrix;
360 property nextMatrix: TAffineMatrix read FNextMatrix write FNextMatrix;
361 destructor Destroy; override;
362 end;
363
364 { TDiscardOriginalDifference }
365
366 TDiscardOriginalDifference = class(TCustomImageDifference)
367 private
GetLayerIdnull368 function GetLayerId: integer;
369 protected
370 FPreviousOriginalData: TStream;
371 FPreviousOriginalGuid: TGuid;
372 FOriginalUsedInOtherLayer: boolean;
373 FPreviousOriginalMatrix: TAffineMatrix;
374 FPreviousOriginalRenderStatus: TOriginalRenderStatus;
375 FLayerId: integer;
GetImageDifferenceKindnull376 function GetImageDifferenceKind: TImageDifferenceKind; override;
377 public
378 constructor Create(AFromState: TState; AIndex: integer; AApplyNow: boolean);
UsedMemorynull379 function UsedMemory: int64; override;
TryCompressnull380 function TryCompress: boolean; override;
381 procedure ApplyTo(AState: TState); override;
382 procedure UnapplyTo(AState: TState); override;
383 property LayerId: integer read GetLayerId;
384 destructor Destroy; override;
385 end;
386
387 { TReplaceLayerByImageOriginalDifference }
388
389 TReplaceLayerByImageOriginalDifference = class(TReplaceLayerByOriginalDifference)
390 protected
391 FSourceStoredInOriginal: boolean;
392 procedure StorePreviousLayer(AImgState: TImageState; ALayerIndex: integer;
393 AAlwaysStoreBitmap: boolean); override;
CreateOriginalnull394 function CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal; override;
395 public
UsedMemorynull396 function UsedMemory: int64; override;
TryCompressnull397 function TryCompress: boolean; override;
398 procedure UnapplyTo(AState: TState); override;
399 end;
400
401 { TReplaceLayerByVectorOriginalDifference }
402
403 TReplaceLayerByVectorOriginalDifference = class(TReplaceLayerByOriginalDifference)
404 protected
405 FShouldRenderOriginal: boolean;
ShouldRenderOriginalnull406 function ShouldRenderOriginal: boolean; override;
CreateOriginalnull407 function CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal; override;
408 public
409 constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
410 end;
411
412 { TReplaceLayerByCustomOriginalDifference }
413
414 TReplaceLayerByCustomOriginalDifference = class(TReplaceLayerByOriginalDifference)
415 protected
416 FOriginal: TBGRALayerCustomOriginal;
CreateOriginalnull417 function CreateOriginal({%H-}AState: TState; {%H-}ALayerIndex: integer): TBGRALayerCustomOriginal; override;
ShouldRenderOriginalnull418 function ShouldRenderOriginal: boolean; override;
419 public
420 constructor Create(AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean; AOriginal: TBGRALayerCustomOriginal);
421 destructor Destroy; override;
422 end;
423
424 { TAddShapeToVectorOriginalDifference }
425
426 TAddShapeToVectorOriginalDifference = class(TCustomImageDifference)
427 private
428 FShapeIndex, FShapeId: integer;
429 FLayerId: integer;
430 FShapeCopy: TVectorShape;
431 FShapeBounds: TRect;
432 protected
GetImageDifferenceKindnull433 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetChangingBoundsnull434 function GetChangingBounds: TRect; override;
GetChangingBoundsDefinednull435 function GetChangingBoundsDefined: boolean; override;
436 public
437 constructor Create(ADestination: TState; ALayerId: integer; AShape: TVectorShape; AShapeIndex: integer = -1);
438 destructor Destroy; override;
439 procedure ApplyTo(AState: TState); override;
440 procedure UnapplyTo(AState: TState); override;
441 end;
442
443 { TVectorOriginalEmbeddedDifference }
444
445 TVectorOriginalEmbeddedDifference = class(TCustomImageDifference)
446 private
447 FDate: TDateTime;
448 FOriginalGuid: TGuid;
449 FDiff: TBGRAOriginalDiff;
450 FBounds: TRect;
451 protected
GetImageDifferenceKindnull452 function GetImageDifferenceKind: TImageDifferenceKind; override;
GetChangingBoundsnull453 function GetChangingBounds: TRect; override;
GetChangingBoundsDefinednull454 function GetChangingBoundsDefined: boolean; override;
GetIsIdentitynull455 function GetIsIdentity: boolean; override;
456 public
457 constructor Create({%H-}ADestination: TState; AOriginalGuid: TGuid; ADiff: TBGRAOriginalDiff; ABounds: TRect);
458 destructor Destroy; override;
459 procedure ApplyTo(AState: TState); override;
460 procedure UnapplyTo(AState: TState); override;
461 end;
462
463 { TDiscardOriginalStateDifference }
464
465 TDiscardOriginalStateDifference = class(TCustomImageDifference)
466 protected
467 origData: TStream;
468 origMatrix: TAffineMatrix;
469 origRenderStatus: TOriginalRenderStatus;
470 layerId: integer;
GetImageDifferenceKindnull471 function GetImageDifferenceKind: TImageDifferenceKind; override;
472 public
UsedMemorynull473 function UsedMemory: int64; override;
TryCompressnull474 function TryCompress: boolean; override;
475 procedure ApplyTo(AState: TState); override;
476 procedure UnapplyTo(AState: TState); override;
477 constructor Create(AState: TState; AIndex: integer);
478 destructor Destroy; override;
479 end;
480
481 { TAssignStateDifference }
482
483 TAssignStateDifference = class(TCustomImageDifference)
484 protected
485 FStreamBefore, FStreamAfter: TMemoryStream;
486 FSelectionDiff,FSelectionLayerDiff: TImageDiff;
487 procedure Init(AState: TState; AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer);
488 public
489 constructor Create(AState: TState; AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer);
490 constructor Create(AState: TState; AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer; ACurrentSelection: TBGRABitmap; ASelectionLayer: TBGRABitmap);
UsedMemorynull491 function UsedMemory: int64; override;
TryCompressnull492 function TryCompress: boolean; override;
493 procedure ApplyTo(AState: TState); override;
494 procedure UnApplyTo(AState: TState); override;
495 destructor Destroy; override;
496 end;
497
498 { TAssignStateDifferenceAfter }
499
500 TAssignStateDifferenceAfter = class(TAssignStateDifference)
501 public
502 constructor Create(AState: TState; ABackup: TState);
503 end;
504
505 { TDuplicateLayerStateDifference }
506
507 TDuplicateLayerStateDifference = class(TCustomImageDifference)
508 protected
GetImageDifferenceKindnull509 function GetImageDifferenceKind: TImageDifferenceKind; override;
510 public
511 sourceLayerId: integer;
512 duplicateId: integer;
513 useOriginal: boolean;
514 duplicateOriginal: boolean;
515 duplicateGuid: TGuid;
516 procedure ApplyTo(AState: TState); override;
517 procedure UnapplyTo(AState: TState); override;
518 constructor Create(ADestination: TState; AUseOriginal: boolean);
519 end;
520
521 { TMoveLayerStateDifference }
522
523 TMoveLayerStateDifference = class(TCustomImageDifference)
524 protected
GetIsIdentitynull525 function GetIsIdentity: boolean; override;
GetImageDifferenceKindnull526 function GetImageDifferenceKind: TImageDifferenceKind; override;
527 public
528 sourceIndex,destIndex: integer;
529 procedure ApplyTo(AState: TState); override;
530 procedure UnapplyTo(AState: TState); override;
531 constructor Create(ADestination: TState; AFromIndex, AToIndex: integer);
532 end;
533
534 { TMergeLayerOverStateDifference }
535
536 TMergeLayerOverStateDifference = class(TCustomImageDifference)
537 protected
GetImageDifferenceKindnull538 function GetImageDifferenceKind: TImageDifferenceKind; override;
539 public
540 previousActiveLayerId: integer;
541 layerOverIndex: integer;
542 layerOverCompressedBackup: TStoredLayer;
543 layerUnderCompressedBackup: TStoredLayer;
544 mergeVectorial: boolean;
545 mergeVectorialGuid: TGuid;
546 constructor Create(ADestination: TState; ALayerOverIndex: integer);
UsedMemorynull547 function UsedMemory: int64; override;
TryCompressnull548 function TryCompress: boolean; override;
549 procedure ApplyTo(AState: TState); override;
550 procedure UnapplyTo(AState: TState); override;
551 destructor Destroy; override;
552 end;
553
554 implementation
555
556 uses BGRAWriteLzp, BGRAReadLzp, BGRAStreamLayers, BGRALzpCommon, ugraph, Types,
557 BGRATransform, zstream, LCVectorRectShapes, BGRAPen, LCVectorialFill,
558 BGRAGradientOriginal;
559
IsInverseImageDiffnull560 function IsInverseImageDiff(ADiff1, ADiff2: TCustomImageDifference): boolean;
561 begin
562 if (ADiff1 is TInversibleStateDifference) and (ADiff2 is TInversibleStateDifference) then
563 result := ((ADiff1 as TInversibleStateDifference).Action = GetInverseAction( (ADiff2 as TInversibleStateDifference).Action ))
564 and ((ADiff1 as TInversibleStateDifference).LayerIndex = (ADiff2 as TInversibleStateDifference).LayerIndex)
565 else
566 if (ADiff1 is TSetLayerNameStateDifference) and (ADiff2 is TSetLayerNameStateDifference) then
567 begin
568 result := ((ADiff1 as TSetLayerNameStateDifference).nextName = (ADiff2 as TSetLayerNameStateDifference).previousName) and
569 ((ADiff1 as TSetLayerNameStateDifference).previousName = (ADiff2 as TSetLayerNameStateDifference).nextName);
570 end
571 else
572 if (ADiff1 is TSetLayerVisibleStateDifference) and (ADiff2 is TSetLayerVisibleStateDifference) then
573 begin
574 result := ((ADiff1 as TSetLayerVisibleStateDifference).nextVisible = (ADiff2 as TSetLayerVisibleStateDifference).previousVisible) and
575 ((ADiff1 as TSetLayerVisibleStateDifference).previousVisible = (ADiff2 as TSetLayerVisibleStateDifference).nextVisible);
576 end
577 else
578 if (ADiff1 is TSetLayerOpacityStateDifference) and (ADiff2 is TSetLayerOpacityStateDifference) then
579 begin
580 result := ((ADiff1 as TSetLayerOpacityStateDifference).nextOpacity = (ADiff2 as TSetLayerOpacityStateDifference).previousOpacity) and
581 ((ADiff1 as TSetLayerOpacityStateDifference).previousOpacity = (ADiff2 as TSetLayerOpacityStateDifference).nextOpacity);
582 end
583 else
584 if (ADiff1 is TSetLayerBlendOpStateDifference) and (ADiff2 is TSetLayerBlendOpStateDifference) then
585 begin
586 result := ((ADiff1 as TSetLayerBlendOpStateDifference).nextBlendOp = (ADiff2 as TSetLayerBlendOpStateDifference).previousBlendOp) and
587 ((ADiff1 as TSetLayerBlendOpStateDifference).previousBlendOp = (ADiff2 as TSetLayerBlendOpStateDifference).nextBlendOp);
588 end
589 else
590 result := false;
591 end;
592
TryCombineImageDiffnull593 function TryCombineImageDiff(ANewDiff, APrevDiff: TCustomImageDifference): boolean;
594 const VectorDiffMinTime = 2000/(1000*60*60*24);
595 var
596 combined: TInversibleAction;
597 begin
598 if (APrevDiff is TInversibleStateDifference) and (ANewDiff is TInversibleStateDifference) then
599 begin
600 if CanCombineInversibleAction((APrevDiff as TInversibleStateDifference).Action, (ANewDiff as TInversibleStateDifference).Action, combined) then
601 begin
602 (APrevDiff as TInversibleStateDifference).Action := combined;
603 result := true;
604 end
605 else result := false;
606 end
607 else
608 if (APrevDiff is TSetLayerNameStateDifference) and (ANewDiff is TSetLayerNameStateDifference) then
609 begin
610 if (APrevDiff as TSetLayerNameStateDifference).nextName = (ANewDiff as TSetLayerNameStateDifference).previousName then
611 begin
612 (APrevDiff as TSetLayerNameStateDifference).nextName := (ANewDiff as TSetLayerNameStateDifference).nextName;
613 result := true;
614 end
615 else result := false;
616 end
617 else
618 if (APrevDiff is TSetLayerOpacityStateDifference) and (ANewDiff is TSetLayerOpacityStateDifference) then
619 begin
620 if (APrevDiff as TSetLayerOpacityStateDifference).nextOpacity = (ANewDiff as TSetLayerOpacityStateDifference).previousOpacity then
621 begin
622 (APrevDiff as TSetLayerOpacityStateDifference).nextOpacity := (ANewDiff as TSetLayerOpacityStateDifference).nextOpacity;
623 result := true;
624 end
625 else result := false;
626 end
627 else
628 if (APrevDiff is TSetLayerOffsetStateDifference) and (ANewDiff is TSetLayerOffsetStateDifference) then
629 begin
630 if ((APrevDiff as TSetLayerOffsetStateDifference).nextOffset.x = (ANewDiff as TSetLayerOffsetStateDifference).previousOffset.x)
631 and ((APrevDiff as TSetLayerOffsetStateDifference).nextOffset.y = (ANewDiff as TSetLayerOffsetStateDifference).previousOffset.y) then
632 begin
633 (APrevDiff as TSetLayerOffsetStateDifference).nextOffset := (ANewDiff as TSetLayerOffsetStateDifference).nextOffset;
634 result := true;
635 end
636 else result := false;
637 end
638 else
639 if (APrevDiff is TSetLayerMatrixDifference) and (ANewDiff is TSetLayerMatrixDifference) then
640 begin
641 if (APrevDiff as TSetLayerMatrixDifference).nextMatrix = (ANewDiff as TSetLayerMatrixDifference).previousMatrix then
642 begin
643 (APrevDiff as TSetLayerMatrixDifference).nextMatrix := (ANewDiff as TSetLayerMatrixDifference).nextMatrix;
644 result := true;
645 end
646 else result := false;
647 end
648 else
649 if (APrevDiff is TReplaceLayerByOriginalDifference) and (ANewDiff is TSetLayerMatrixDifference) then
650 begin
651 if (APrevDiff as TReplaceLayerByOriginalDifference).nextMatrix = (ANewDiff as TSetLayerMatrixDifference).previousMatrix then
652 begin
653 (APrevDiff as TReplaceLayerByOriginalDifference).nextMatrix := (ANewDiff as TSetLayerMatrixDifference).nextMatrix;
654 result := true;
655 end
656 else result := false;
657 end
658 else
659 if (APrevDiff is TSetSelectionTransformDifference) and (ANewDiff is TSetSelectionTransformDifference) then
660 begin
661 if (APrevDiff as TSetSelectionTransformDifference).nextMatrix = (ANewDiff as TSetSelectionTransformDifference).previousMatrix then
662 begin
663 (APrevDiff as TSetSelectionTransformDifference).nextMatrix := (ANewDiff as TSetSelectionTransformDifference).nextMatrix;
664 result := true;
665 end
666 else result := false;
667 end
668 else
669 if (APrevDiff is TSetLayerBlendOpStateDifference) and (ANewDiff is TSetLayerBlendOpStateDifference) then
670 begin
671 if (APrevDiff as TSetLayerBlendOpStateDifference).nextBlendOp = (ANewDiff as TSetLayerBlendOpStateDifference).previousBlendOp then
672 begin
673 (APrevDiff as TSetLayerBlendOpStateDifference).nextBlendOp := (ANewDiff as TSetLayerBlendOpStateDifference).nextBlendOp;
674 result := true;
675 end
676 else result := false;
677 end
678 else
679 if (APrevDiff is TVectorOriginalEmbeddedDifference) and (ANewDiff is TVectorOriginalEmbeddedDifference) then
680 begin
681 if (TVectorOriginalEmbeddedDifference(ANewDiff).FDate <
682 TVectorOriginalEmbeddedDifference(APrevDiff).FDate+VectorDiffMinTime) and
683 TVectorOriginalEmbeddedDifference(APrevDiff).FDiff.CanAppend(
684 TVectorOriginalEmbeddedDifference(ANewDiff).FDiff) then
685 begin
686 TVectorOriginalEmbeddedDifference(APrevDiff).FDiff.Append(
687 TVectorOriginalEmbeddedDifference(ANewDiff).FDiff);
688 result := true;
689 end else
690 result := false;
691 end else
692 result := false;
693 end;
694
695 { TSetImageRegistryDifference }
696
GetImageDifferenceKindnull697 function TSetImageRegistryDifference.GetImageDifferenceKind: TImageDifferenceKind;
698 begin
699 Result:= idkChangeStack;
700 end;
701
GetIsIdentitynull702 function TSetImageRegistryDifference.GetIsIdentity: boolean;
703 begin
704 Result:= previousValue = nextValue;
705 end;
706
GetCostnull707 function TSetImageRegistryDifference.GetCost: integer;
708 begin
709 Result:= 0;
710 end;
711
712 constructor TSetImageRegistryDifference.Create(ADestination: TState;
713 AIdentifier: string; ANewValue: RawByteString; AApplyNow: boolean);
714 var
715 imgState: TImageState;
716 begin
717 inherited Create(ADestination);
718 identifier := AIdentifier;
719 nextValue := ANewValue;
720 imgState := ADestination as TImageState;
721 previousValue:= imgState.LayeredBitmap.GetGlobalRegistry(identifier);
722 if AApplyNow then ApplyTo(ADestination);
723 end;
724
725 procedure TSetImageRegistryDifference.ApplyTo(AState: TState);
726 var
727 imgState: TImageState;
728 begin
729 inherited ApplyTo(AState);
730 imgState := AState as TImageState;
731 imgState.LayeredBitmap.SetGlobalRegistry(identifier, nextValue);
732 end;
733
734 procedure TSetImageRegistryDifference.UnapplyTo(AState: TState);
735 var
736 imgState: TImageState;
737 begin
738 inherited UnapplyTo(AState);
739 imgState := AState as TImageState;
740 imgState.LayeredBitmap.SetGlobalRegistry(identifier, previousValue);
741 end;
742
743 { TSetLayerRegistryDifference }
744
GetImageDifferenceKindnull745 function TSetLayerRegistryDifference.GetImageDifferenceKind: TImageDifferenceKind;
746 begin
747 Result:= idkChangeStack;
748 end;
749
GetIsIdentitynull750 function TSetLayerRegistryDifference.GetIsIdentity: boolean;
751 begin
752 Result:= previousValue = nextValue;
753 end;
754
TSetLayerRegistryDifference.GetCostnull755 function TSetLayerRegistryDifference.GetCost: integer;
756 begin
757 Result:= 0;
758 end;
759
760 constructor TSetLayerRegistryDifference.Create(ADestination: TState;
761 ALayerId: integer; AIdentifier: string; ANewValue: RawByteString;
762 AApplyNow: boolean);
763 var
764 imgState: TImageState;
765 begin
766 inherited Create(ADestination);
767 layerId := ALayerId;
768 identifier := AIdentifier;
769 nextValue := ANewValue;
770 imgState := ADestination as TImageState;
771 previousValue:= imgState.LayeredBitmap.GetLayerRegistry(imgState.LayeredBitmap.GetLayerIndexFromId(layerId), identifier);
772 if AApplyNow then ApplyTo(ADestination);
773 end;
774
775 procedure TSetLayerRegistryDifference.ApplyTo(AState: TState);
776 var
777 imgState: TImageState;
778 begin
779 inherited ApplyTo(AState);
780 imgState := AState as TImageState;
781 imgState.LayeredBitmap.SetLayerRegistry(imgState.LayeredBitmap.GetLayerIndexFromId(layerId), identifier, nextValue);
782 end;
783
784 procedure TSetLayerRegistryDifference.UnapplyTo(AState: TState);
785 var
786 imgState: TImageState;
787 begin
788 inherited UnapplyTo(AState);
789 imgState := AState as TImageState;
790 imgState.LayeredBitmap.SetLayerRegistry(imgState.LayeredBitmap.GetLayerIndexFromId(layerId), identifier, previousValue);
791 end;
792
793 { TReplaceLayerByCustomOriginalDifference }
794
TReplaceLayerByCustomOriginalDifference.CreateOriginalnull795 function TReplaceLayerByCustomOriginalDifference.CreateOriginal(AState: TState;
796 ALayerIndex: integer): TBGRALayerCustomOriginal;
797 begin
798 result := FOriginal.Duplicate;
799 end;
800
ShouldRenderOriginalnull801 function TReplaceLayerByCustomOriginalDifference.ShouldRenderOriginal: boolean;
802 begin
803 result := true;
804 end;
805
806 constructor TReplaceLayerByCustomOriginalDifference.Create(AFromState: TState;
807 AIndex: integer; AAlwaysStoreBitmap: boolean; AOriginal: TBGRALayerCustomOriginal);
808 begin
809 FOriginal := AOriginal;
810 inherited Create(AFromState,AIndex,AAlwaysStoreBitmap);
811 end;
812
813 destructor TReplaceLayerByCustomOriginalDifference.Destroy;
814 begin
815 FOriginal.Free;
816 inherited Destroy;
817 end;
818
819 { TVectorOriginalEmbeddedDifference }
820
GetImageDifferenceKindnull821 function TVectorOriginalEmbeddedDifference.GetImageDifferenceKind: TImageDifferenceKind;
822 begin
823 Result:= idkChangeImage;
824 end;
825
TVectorOriginalEmbeddedDifference.GetChangingBoundsnull826 function TVectorOriginalEmbeddedDifference.GetChangingBounds: TRect;
827 begin
828 Result:= FBounds;
829 end;
830
GetChangingBoundsDefinednull831 function TVectorOriginalEmbeddedDifference.GetChangingBoundsDefined: boolean;
832 begin
833 Result:= true;
834 end;
835
GetIsIdentitynull836 function TVectorOriginalEmbeddedDifference.GetIsIdentity: boolean;
837 begin
838 Result:= FDiff.IsIdentity;
839 end;
840
841 constructor TVectorOriginalEmbeddedDifference.Create(ADestination: TState;
842 AOriginalGuid: TGuid; ADiff: TBGRAOriginalDiff; ABounds: TRect);
843 begin
844 FDate := Now;
845 FOriginalGuid:= AOriginalGuid;
846 FDiff := ADiff;
847 FBounds := ABounds;
848 end;
849
850 destructor TVectorOriginalEmbeddedDifference.Destroy;
851 begin
852 FDiff.Free;
853 inherited Destroy;
854 end;
855
856 procedure TVectorOriginalEmbeddedDifference.ApplyTo(AState: TState);
857 var
858 img: TImageState;
859 idxOrig: Integer;
860 begin
861 inherited ApplyTo(AState);
862 img := AState as TImageState;
863 idxOrig := img.LayeredBitmap.IndexOfOriginal(FOriginalGuid);
864 if idxOrig<>-1 then
865 FDiff.Apply(img.LayeredBitmap.Original[idxOrig])
866 else
867 raise exception.Create('Cannot find original');
868 end;
869
870 procedure TVectorOriginalEmbeddedDifference.UnapplyTo(AState: TState);
871 var
872 img: TImageState;
873 idxOrig: Integer;
874 begin
875 inherited UnapplyTo(AState);
876 img := AState as TImageState;
877 idxOrig := img.LayeredBitmap.IndexOfOriginal(FOriginalGuid);
878 if idxOrig<>-1 then
879 FDiff.Unapply(img.LayeredBitmap.Original[idxOrig])
880 else
881 raise exception.Create('Cannot find original');
882 end;
883
884 { TDiscardOriginalDifference }
885
TDiscardOriginalDifference.GetLayerIdnull886 function TDiscardOriginalDifference.GetLayerId: integer;
887 begin
888 result := FLayerId;
889 end;
890
TDiscardOriginalDifference.GetImageDifferenceKindnull891 function TDiscardOriginalDifference.GetImageDifferenceKind: TImageDifferenceKind;
892 begin
893 Result:= idkChangeStack;
894 end;
895
896 constructor TDiscardOriginalDifference.Create(AFromState: TState;
897 AIndex: integer; AApplyNow: boolean);
898 var
899 imgState: TImageState;
900 i: Integer;
901 begin
902 imgState := AFromState as TImageState;
903 FLayerId := imgState.LayerId[AIndex];
904 if not imgState.LayerOriginalDefined[AIndex] then
905 raise exception.Create('Layer original is not defined');
906 FPreviousOriginalGuid := imgState.LayeredBitmap.LayerOriginalGuid[AIndex];
907 FOriginalUsedInOtherLayer := false;
908 for i := 0 to imgState.NbLayers-1 do
909 if (i <> AIndex) and (imgState.LayeredBitmap.LayerOriginalGuid[i] = FPreviousOriginalGuid) then
910 begin
911 FOriginalUsedInOtherLayer:= true;
912 break;
913 end;
914 if not FOriginalUsedInOtherLayer then
915 begin
916 FPreviousOriginalData := TMemoryStream.Create;
917 imgState.LayeredBitmap.SaveOriginalToStream(
918 imgState.LayeredBitmap.LayerOriginalGuid[AIndex],
919 FPreviousOriginalData);
920 end;
921 FPreviousOriginalMatrix := imgState.LayerOriginalMatrix[AIndex];
922 FPreviousOriginalRenderStatus:= imgState.layeredBitmap.LayerOriginalRenderStatus[AIndex];
923 if AApplyNow then ApplyTo(AFromState)
924 end;
925
UsedMemorynull926 function TDiscardOriginalDifference.UsedMemory: int64;
927 begin
928 if Assigned(FPreviousOriginalData) then
929 Result:= FPreviousOriginalData.Size
930 else
931 result:= 0;
932 end;
933
TryCompressnull934 function TDiscardOriginalDifference.TryCompress: boolean;
935 begin
936 Result:= false;
937 end;
938
939 procedure TDiscardOriginalDifference.ApplyTo(AState: TState);
940 var
941 imgState: TImageState;
942 layerIdx: Integer;
943 begin
944 imgState := AState as TImageState;
945 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FLayerId);
946 imgState.LayeredBitmap.LayerOriginalGuid[layerIdx] := GUID_NULL;
947 imgState.LayeredBitmap.LayerOriginalMatrix[layerIdx] := AffineMatrixIdentity;
948 if not FOriginalUsedInOtherLayer then
949 imgState.LayeredBitmap.RemoveUnusedOriginals;
950 inherited ApplyTo(AState);
951 end;
952
953 procedure TDiscardOriginalDifference.UnapplyTo(AState: TState);
954 var
955 imgState: TImageState;
956 layerIdx, origIdx: Integer;
957 begin
958 imgState := AState as TImageState;
959 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FLayerId);
960 if FOriginalUsedInOtherLayer then
961 begin
962 imgState.LayeredBitmap.LayerOriginalGuid[layerIdx] := FPreviousOriginalGuid;
963 end else
964 begin
965 FPreviousOriginalData.Position := 0;
966 origIdx := imgState.LayeredBitmap.AddOriginalFromStream(FPreviousOriginalData, FPreviousOriginalGuid, true);
967 imgState.LayeredBitmap.LayerOriginalGuid[layerIdx] := imgState.LayeredBitmap.OriginalGuid[origIdx];
968 end;
969 imgState.LayeredBitmap.LayerOriginalMatrix[layerIdx] := FPreviousOriginalMatrix;
970 imgState.LayeredBitmap.LayerOriginalRenderStatus[layerIdx] := FPreviousOriginalRenderStatus;
971 inherited UnapplyTo(AState);
972 end;
973
974 destructor TDiscardOriginalDifference.Destroy;
975 begin
976 FPreviousOriginalData.Free;
977 inherited Destroy;
978 end;
979
980 { TAddShapeToVectorOriginalDifference }
981
GetImageDifferenceKindnull982 function TAddShapeToVectorOriginalDifference.GetImageDifferenceKind: TImageDifferenceKind;
983 begin
984 Result:= idkChangeImage;
985 end;
986
GetChangingBoundsnull987 function TAddShapeToVectorOriginalDifference.GetChangingBounds: TRect;
988 begin
989 Result:= FShapeBounds;
990 end;
991
GetChangingBoundsDefinednull992 function TAddShapeToVectorOriginalDifference.GetChangingBoundsDefined: boolean;
993 begin
994 Result:= true;
995 end;
996
997 constructor TAddShapeToVectorOriginalDifference.Create(ADestination: TState;
998 ALayerId: integer; AShape: TVectorShape; AShapeIndex: integer);
999 var
1000 imgState: TImageState;
1001 layerIdx: Integer;
1002 orig: TBGRALayerCustomOriginal;
1003 begin
1004 FLayerId := ALayerId;
1005 imgState := ADestination as TImageState;
1006 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FLayerId);
1007 orig := imgState.LayerOriginal[layerIdx];
1008 if not (orig is TVectorOriginal) then
1009 begin
1010 AShape.Free;
1011 raise exception.Create('Vector original expected');
1012 end;
1013 if AShapeIndex = -1 then AShapeIndex := TVectorOriginal(orig).ShapeCount;
1014 FShapeIndex:= AShapeIndex;
1015 FShapeCopy := AShape.Duplicate;
1016
1017 inherited ApplyTo(ADestination);
1018 TVectorOriginal(orig).InsertShape(AShape, FShapeIndex);
1019 FShapeId := TVectorOriginal(orig).Shape[FShapeIndex].Id;
1020 TVectorOriginal(orig).SelectShape(FShapeIndex);
1021 FShapeBounds := imgState.LayeredBitmap.RenderOriginalIfNecessary(orig.Guid);
1022 end;
1023
1024 destructor TAddShapeToVectorOriginalDifference.Destroy;
1025 begin
1026 FShapeCopy.Free;
1027 inherited Destroy;
1028 end;
1029
1030 procedure TAddShapeToVectorOriginalDifference.ApplyTo(AState: TState);
1031 var
1032 imgState: TImageState;
1033 layerIdx: Integer;
1034 orig: TBGRALayerCustomOriginal;
1035 shape: TVectorShape;
1036 begin
1037 inherited ApplyTo(AState);
1038 imgState := AState as TImageState;
1039 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FLayerId);
1040 orig := imgState.LayerOriginal[layerIdx];
1041 if not (orig is TVectorOriginal) then
1042 raise exception.Create('Vector original expected');
1043
1044 shape := FShapeCopy.Duplicate;
1045 TVectorOriginal(orig).InsertShape(shape, FShapeIndex);
1046 TVectorOriginal(orig).Shape[FShapeIndex].Id := FShapeId;
1047 TVectorOriginal(orig).SelectShape(FShapeIndex);
1048 imgState.LayeredBitmap.RenderLayerFromOriginal(layerIdx);
1049 end;
1050
1051 procedure TAddShapeToVectorOriginalDifference.UnapplyTo(AState: TState);
1052 var
1053 imgState: TImageState;
1054 layerIdx: Integer;
1055 orig: TBGRALayerCustomOriginal;
1056 begin
1057 inherited UnapplyTo(AState);
1058 imgState := AState as TImageState;
1059 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FLayerId);
1060 orig := imgState.LayerOriginal[layerIdx];
1061 if not (orig is TVectorOriginal) then
1062 raise exception.Create('Vector original expected');
1063 TVectorOriginal(orig).RemoveShape(TVectorOriginal(orig).Shape[FShapeIndex]);
1064 end;
1065
1066 { TReplaceLayerByVectorOriginalDifference }
1067
TReplaceLayerByVectorOriginalDifference.ShouldRenderOriginalnull1068 function TReplaceLayerByVectorOriginalDifference.ShouldRenderOriginal: boolean;
1069 begin
1070 Result:= FShouldRenderOriginal;
1071 end;
1072
CreateOriginalnull1073 function TReplaceLayerByVectorOriginalDifference.CreateOriginal(AState: TState;
1074 ALayerIndex: integer): TBGRALayerCustomOriginal;
1075 var
1076 source: TBGRABitmap;
1077 temp: TBGRABitmap;
1078 imgState: TImageState;
1079 orig: TVectorOriginal;
1080 shape: TRectShape;
1081 begin
1082 imgState := TImageState(AState);
1083 orig := TVectorOriginal.Create;
1084 if imgState.LayeredBitmap.LayerOriginalClass[ALayerIndex]=TBGRALayerGradientOriginal then
1085 begin
1086 shape := TRectShape.Create(orig);
1087 shape.QuickDefine(PointF(-0.5,-0.5),PointF(FSourceBounds.Width-0.5,FSourceBounds.Height-0.5));
1088 shape.PenStyle := ClearPenStyle;
1089 shape.BackFill.SetGradient(
1090 imgState.LayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerGradientOriginal,false);
1091 shape.BackFill.Transform(imgState.LayeredBitmap.LayerOriginalMatrix[ALayerIndex]);
1092 orig.AddShape(shape);
1093 end else
1094 if imgState.LayeredBitmap.LayerOriginalClass[ALayerIndex]=TBGRALayerImageOriginal then
1095 begin
1096 temp := (imgState.LayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerImageOriginal).GetImageCopy;
1097 if temp <> nil then
1098 begin
1099 if not temp.Empty then
1100 begin
1101 shape := TRectShape.Create(orig);
1102 shape.QuickDefine(PointF(-0.5,-0.5),PointF(temp.Width-0.5,temp.Height-0.5));
1103 shape.PenStyle := ClearPenStyle;
1104 if temp.Equals(temp.GetPixel(0,0)) then
1105 shape.BackFill.SetSolid(temp.GetPixel(0,0))
1106 else shape.BackFill.SetTexture(temp,AffineMatrixIdentity,255,trNone);
1107 shape.Transform(imgState.LayeredBitmap.LayerOriginalMatrix[ALayerIndex]);
1108 with imgState.LayeredBitmap.LayerOffset[ALayerIndex] do
1109 shape.Transform(AffineMatrixTranslation(-X-FSourceBounds.Left,-Y-FSourceBounds.Top));
1110 orig.AddShape(shape);
1111 end;
1112 temp.FreeReference;
1113 end;
1114 end else
1115 begin
1116 source := imgState.LayeredBitmap.LayerBitmap[ALayerIndex];
1117 if not source.Empty and not FSourceBounds.IsEmpty then
1118 begin
1119 temp := source.GetPart(FSourceBounds) as TBGRABitmap;
1120 shape := TRectShape.Create(orig);
1121 shape.QuickDefine(PointF(-0.5,-0.5),PointF(FSourceBounds.Width-0.5,FSourceBounds.Height-0.5));
1122 shape.PenStyle := ClearPenStyle;
1123 if temp.Equals(temp.GetPixel(0,0)) then
1124 shape.BackFill.SetSolid(temp.GetPixel(0,0))
1125 else shape.BackFill.SetTexture(temp,AffineMatrixIdentity,255,trNone);
1126 orig.AddShape(shape);
1127 temp.FreeReference;
1128 end;
1129 end;
1130 result := orig;
1131 end;
1132
1133 constructor TReplaceLayerByVectorOriginalDifference.Create(AFromState: TState;
1134 AIndex: integer; AAlwaysStoreBitmap: boolean);
1135 var
1136 imgState: TImageState;
1137 begin
1138 imgState := AFromState as TImageState;
1139 FShouldRenderOriginal:= imgState.LayeredBitmap.LayerOriginalClass[AIndex]=TBGRALayerGradientOriginal;
1140 inherited Create(AFromState, AIndex, AAlwaysStoreBitmap);
1141 end;
1142
1143 { TReplaceLayerByImageOriginalDifference }
1144
1145 procedure TReplaceLayerByImageOriginalDifference.StorePreviousLayer(
1146 AImgState: TImageState; ALayerIndex: integer; AAlwaysStoreBitmap: boolean);
1147 begin
1148 if not AImgState.LayerOriginalDefined[ALayerIndex] then
1149 FSourceStoredInOriginal:= true
1150 else
1151 inherited StorePreviousLayer(AImgState, ALayerIndex, AAlwaysStoreBitmap);
1152 end;
1153
TReplaceLayerByImageOriginalDifference.CreateOriginalnull1154 function TReplaceLayerByImageOriginalDifference.CreateOriginal(AState: TState; ALayerIndex: integer): TBGRALayerCustomOriginal;
1155 var
1156 source: TBGRABitmap;
1157 temp: TBGRACustomBitmap;
1158 imgState: TImageState;
1159 orig: TBGRALayerImageOriginal;
1160 begin
1161 imgState := TImageState(AState);
1162 orig := TBGRALayerImageOriginal.Create;
1163 source := imgState.LayeredBitmap.LayerBitmap[ALayerIndex];
1164 if (FSourceBounds.Width <> source.Width) or (FSourceBounds.Height <> source.Height) then
1165 begin
1166 temp := source.GetPart(FSourceBounds);
1167 orig.AssignImage(temp);
1168 temp.Free;
1169 end else
1170 orig.AssignImage(source);
1171 result := orig;
1172 end;
1173
UsedMemorynull1174 function TReplaceLayerByImageOriginalDifference.UsedMemory: int64;
1175 begin
1176 if FSourceStoredInOriginal then
1177 result := 0
1178 else
1179 Result:=inherited UsedMemory;
1180 end;
1181
TReplaceLayerByImageOriginalDifference.TryCompressnull1182 function TReplaceLayerByImageOriginalDifference.TryCompress: boolean;
1183 begin
1184 if FSourceStoredInOriginal then
1185 result := false
1186 else Result:=inherited TryCompress;
1187 end;
1188
1189 procedure TReplaceLayerByImageOriginalDifference.UnapplyTo(AState: TState);
1190 var
1191 imgState: TImageState;
1192 layerIdx: Integer;
1193 bmp: TBGRABitmap;
1194 begin
1195 if FSourceStoredInOriginal then
1196 begin
1197 CustomUnapplyto(AState);
1198 imgState := AState as TImageState;
1199 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(LayerId);
1200 bmp := (imgState.LayeredBitmap.LayerOriginal[layerIdx] as TBGRALayerImageOriginal).GetImageCopy;
1201 imgState.LayeredBitmap.SetLayerBitmap(layerIdx, bmp, True);
1202 imgState.LayeredBitmap.LayerOffset[layerIdx] := Point(round(FPrevMatrix[1,3]), round(FPrevMatrix[2,3]));
1203 imgState.LayeredBitmap.RemoveUnusedOriginals;
1204 end else
1205 inherited UnapplyTo(AState);
1206 end;
1207
1208 { TSelectionTransformDifference }
1209
GetImageDifferenceKindnull1210 function TSelectionTransformDifference.GetImageDifferenceKind: TImageDifferenceKind;
1211 begin
1212 if Assigned(FPrevSelectionMask) then
1213 begin
1214 if Assigned(FPrevSelectionLayer) then
1215 Result:= idkChangeImageAndSelection
1216 else
1217 Result:= idkChangeSelection;
1218 end else
1219 if Assigned(FPrevSelectionLayer) then
1220 Result:= idkChangeImage;
1221 end;
1222
GetIsIdentitynull1223 function TSelectionTransformDifference.GetIsIdentity: boolean;
1224 begin
1225 Result:= IsAffineMatrixIdentity(FPrevTransform);
1226 end;
1227
TSelectionTransformDifference.TryCompressnull1228 function TSelectionTransformDifference.TryCompress: boolean;
1229 begin
1230 Result:= (Assigned(FPrevSelectionMask) and FPrevSelectionMask.Compress) or
1231 (Assigned(FPrevSelectionLayer) and FPrevSelectionLayer.Compress);
1232 end;
1233
1234 constructor TSelectionTransformDifference.Create(ADestination: TState;
1235 AApplyNow: boolean);
1236 var
1237 ImgState: TImageState;
1238 begin
1239 inherited Create(ADestination);
1240 ImgState := ADestination as TImageState;
1241 FPrevTransform := ImgState.SelectionTransform;
1242 if not ImgState.SelectionMaskEmpty then
1243 FPrevSelectionMask := TStoredImage.Create(ImgState.SelectionMask, True)
1244 else FPrevSelectionMask := nil;
1245 if not ImgState.SelectionLayerEmpty then
1246 FPrevSelectionLayer := TStoredImage.Create(ImgState.SelectionLayer, False)
1247 else FPrevSelectionLayer := nil;
1248 if AApplyNow then ApplyTo(ADestination);
1249 end;
1250
1251 destructor TSelectionTransformDifference.Destroy;
1252 begin
1253 FPrevSelectionMask.Free;
1254 FPrevSelectionLayer.Free;
1255 inherited Destroy;
1256 end;
1257
1258 procedure TSelectionTransformDifference.ApplyTo(AState: TState);
1259 var
1260 ImgState: TImageState;
1261 newBmp: TBGRABitmap;
1262 newLeft, newTop: integer;
1263 r: TRect;
1264 begin
1265 inherited ApplyTo(AState);
1266 if not IsIdentity then
1267 begin
1268 ImgState := AState as TImageState;
1269 if not ImgState.SelectionMaskEmpty then
1270 begin
1271 ImgState.ComputeTransformedSelectionMask(newBmp,newLeft,newTop);
1272 r := ImgState.GetSelectionMaskBounds;
1273 ImgState.SelectionMask.FillRect(r, BGRABlack, dmSet);
1274 ImgState.SelectionMask.PutImage(newLeft,newTop,newBmp,dmSet);
1275 newBmp.Free;
1276 end;
1277 if not ImgState.SelectionLayerEmpty then
1278 begin
1279 ImgState.ComputeTransformedSelectionLayer(newBmp,newLeft,newTop);
1280 r := ImgState.GetSelectionLayerBounds;
1281 ImgState.SelectionLayer.FillRect(r, BGRAPixelTransparent, dmSet);
1282 ImgState.SelectionLayer.PutImage(newLeft,newTop,newBmp,dmSet);
1283 newBmp.Free;
1284 end;
1285 ImgState.SelectionTransform := AffineMatrixIdentity;
1286 ImgState.DiscardSelectionMaskBoundsCompletely;
1287 ImgState.DiscardSelectionLayerBoundsCompletely;
1288 end;
1289 end;
1290
1291 procedure TSelectionTransformDifference.UnapplyTo(AState: TState);
1292 var
1293 ImgState: TImageState;
1294 prevMask, prevSelectionLayer: TBGRABitmap;
1295 begin
1296 if not IsIdentity then
1297 begin
1298 ImgState := AState as TImageState;
1299 if Assigned(FPrevSelectionMask) then prevMask := FPrevSelectionMask.GetBitmap else prevMask := nil;
1300 if Assigned(FPrevSelectionLayer) then prevSelectionLayer := FPrevSelectionLayer.GetBitmap else prevSelectionLayer := nil;
1301 ImgState.ReplaceSelection(prevMask, prevSelectionLayer);
1302 ImgState.DiscardSelectionMaskBoundsCompletely;
1303 ImgState.DiscardSelectionLayerBoundsCompletely;
1304 ImgState.SelectionTransform := FPrevTransform;
1305 end;
1306 inherited UnapplyTo(AState);
1307 end;
1308
1309 { TReplaceLayerByOriginalDifference }
1310
GetLayerIdnull1311 function TReplaceLayerByOriginalDifference.GetLayerId: integer;
1312 begin
1313 result := FSourceLayerId;
1314 end;
1315
TReplaceLayerByOriginalDifference.GetImageDifferenceKindnull1316 function TReplaceLayerByOriginalDifference.GetImageDifferenceKind: TImageDifferenceKind;
1317 begin
1318 Result:= idkChangeImage;
1319 end;
1320
ShouldRenderOriginalnull1321 function TReplaceLayerByOriginalDifference.ShouldRenderOriginal: boolean;
1322 begin
1323 result := false;
1324 end;
1325
1326 procedure TReplaceLayerByOriginalDifference.StorePreviousLayer(
1327 AImgState: TImageState; ALayerIndex: integer; AAlwaysStoreBitmap: boolean);
1328 begin
1329 FPreviousLayerContent := TStoredLayer.Create(AImgState.LayeredBitmap, ALayerIndex, AAlwaysStoreBitmap);
1330 end;
1331
1332 procedure TReplaceLayerByOriginalDifference.CustomUnapplyto(AState: TState);
1333 begin
1334 inherited UnapplyTo(AState);
1335 end;
1336
1337 constructor TReplaceLayerByOriginalDifference.Create(
1338 AFromState: TState; AIndex: integer; AAlwaysStoreBitmap: boolean);
1339 var
1340 imgState: TImageState;
1341 begin
1342 inherited Create(AFromState);
1343 imgState := AFromState as TImageState;
1344 FSourceBounds := imgState.LayeredBitmap.LayerBitmap[AIndex].GetImageBounds;
1345 FSourceLayerId := imgState.LayeredBitmap.LayerUniqueId[AIndex];
1346 with imgState.LayeredBitmap.LayerOffset[AIndex] do FPrevMatrix := AffineMatrixTranslation(x+FSourceBounds.Left,y+FSourceBounds.Top);
1347 StorePreviousLayer(imgState, AIndex, AAlwaysStoreBitmap);
1348 FNextMatrix := FPrevMatrix;
1349 ApplyTo(imgState);
1350 end;
1351
TReplaceLayerByOriginalDifference.UsedMemorynull1352 function TReplaceLayerByOriginalDifference.UsedMemory: int64;
1353 begin
1354 Result:= FPreviousLayerContent.UsedMemory;
1355 end;
1356
TryCompressnull1357 function TReplaceLayerByOriginalDifference.TryCompress: boolean;
1358 begin
1359 Result:= FPreviousLayerContent.Compress;
1360 end;
1361
1362 procedure TReplaceLayerByOriginalDifference.ApplyTo(AState: TState);
1363 var
1364 imgState: TImageState;
1365 orig: TBGRALayerCustomOriginal;
1366 origIndex,layerIdx: Integer;
1367 begin
1368 inherited ApplyTo(AState);
1369 imgState := AState as TImageState;
1370 layerIdx := imgState.LayeredBitmap.GetLayerIndexFromId(FSourceLayerId);
1371 orig := CreateOriginal(imgState, layerIdx);
1372 if FOriginalGuid <> GUID_NULL then orig.Guid := FOriginalGuid;
1373 origIndex := imgState.LayeredBitmap.AddOriginal(orig, true);
1374 if FOriginalGuid = GUID_NULL then FOriginalGuid := orig.Guid;
1375 imgState.LayeredBitmap.LayerOriginalGuid[layerIdx] := imgState.LayeredBitmap.OriginalGuid[origIndex];
1376 imgState.LayeredBitmap.LayerOriginalMatrix[layerIdx] := FNextMatrix;
1377 if (FNextMatrix = FPrevMatrix) and not ShouldRenderOriginal then
1378 imgState.LayeredBitmap.LayerOriginalRenderStatus[layerIdx] := orsProof
1379 else
1380 begin
1381 imgState.LayeredBitmap.LayerOriginalRenderStatus[layerIdx] := orsNone;
1382 imgState.LayeredBitmap.RenderLayerFromOriginal(layerIdx);
1383 end;
1384 imgState.LayeredBitmap.RemoveUnusedOriginals;
1385 end;
1386
1387 procedure TReplaceLayerByOriginalDifference.UnapplyTo(AState: TState);
1388 var
1389 imgState: TImageState;
1390 begin
1391 CustomUnapplyto(AState);
1392 imgState := AState as TImageState;
1393 FPreviousLayerContent.Replace(imgState.LayeredBitmap);
1394 end;
1395
1396 destructor TReplaceLayerByOriginalDifference.Destroy;
1397 begin
1398 FPreviousLayerContent.Free;
1399 inherited Destroy;
1400 end;
1401
1402 { TSetSelectionTransformDifference }
1403
TSetSelectionTransformDifference.GetImageDifferenceKindnull1404 function TSetSelectionTransformDifference.GetImageDifferenceKind: TImageDifferenceKind;
1405 begin
1406 Result:= idkChangeImageAndSelection;
1407 end;
1408
GetIsIdentitynull1409 function TSetSelectionTransformDifference.GetIsIdentity: boolean;
1410 begin
1411 Result:= previousMatrix = nextMatrix;
1412 end;
1413
1414 constructor TSetSelectionTransformDifference.Create(ADestination: TState;
1415 ANextMatrix: TAffineMatrix);
1416 var
1417 imgState: TImageState;
1418 begin
1419 imgState := ADestination as TImageState;
1420 previousMatrix := imgState.SelectionTransform;
1421 nextMatrix := ANextMatrix;
1422 end;
1423
1424 procedure TSetSelectionTransformDifference.ApplyTo(AState: TState);
1425 var
1426 imgState: TImageState;
1427 begin
1428 inherited ApplyTo(AState);
1429 imgState := AState as TImageState;
1430 imgState.SelectionTransform := nextMatrix;
1431 end;
1432
1433 procedure TSetSelectionTransformDifference.UnapplyTo(AState: TState);
1434 var
1435 imgState: TImageState;
1436 begin
1437 inherited UnapplyTo(AState);
1438 imgState := AState as TImageState;
1439 imgState.SelectionTransform := previousMatrix;
1440 end;
1441
1442 { TDiscardOriginalStateDifference }
1443
TDiscardOriginalStateDifference.GetImageDifferenceKindnull1444 function TDiscardOriginalStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1445 begin
1446 Result:= idkChangeStack;
1447 end;
1448
UsedMemorynull1449 function TDiscardOriginalStateDifference.UsedMemory: int64;
1450 begin
1451 if Assigned(origData) then
1452 result := origData.Size
1453 else
1454 result := 0;
1455 end;
1456
TDiscardOriginalStateDifference.TryCompressnull1457 function TDiscardOriginalStateDifference.TryCompress: boolean;
1458 begin
1459 Result:= false;
1460 end;
1461
1462 procedure TDiscardOriginalStateDifference.ApplyTo(AState: TState);
1463 var
1464 imgState: TImageState;
1465 idx: Integer;
1466 begin
1467 imgState := AState as TImageState;
1468 idx := imgState.LayeredBitmap.GetLayerIndexFromId(layerId);
1469 imgState.LayeredBitmap.LayerOriginalGuid[idx] := GUID_NULL;
1470 imgState.LayeredBitmap.LayerOriginalMatrix[idx] := AffineMatrixIdentity;
1471 imgState.LayeredBitmap.RemoveUnusedOriginals;
1472 end;
1473
1474 procedure TDiscardOriginalStateDifference.UnapplyTo(AState: TState);
1475 var
1476 imgState: TImageState;
1477 idx, idxOrig: Integer;
1478 begin
1479 imgState := AState as TImageState;
1480 idx := imgState.LayeredBitmap.GetLayerIndexFromId(layerId);
1481 if Assigned(origData) then
1482 begin
1483 origData.Position:= 0;
1484 idxOrig := imgState.LayeredBitmap.AddOriginalFromStream(origData, true);
1485 imgState.LayeredBitmap.LayerOriginalGuid[idx] := imgState.LayeredBitmap.OriginalGuid[idxOrig];
1486 imgState.LayeredBitmap.LayerOriginalMatrix[idx] := origMatrix;
1487 imgState.LayeredBitmap.LayerOriginalRenderStatus[idx] := origRenderStatus;
1488 end;
1489 end;
1490
1491 constructor TDiscardOriginalStateDifference.Create(AState: TState; AIndex: integer);
1492 var
1493 imgState: TImageState;
1494 begin
1495 inherited Create(AState);
1496 imgState := AState as TImageState;
1497 if imgState.LayeredBitmap = nil then
1498 raise exception.Create('Layered bitmap not created');
1499 AIndex := AIndex;
1500 if AIndex = -1 then raise exception.Create('No layer selected');
1501 layerId:= imgState.LayerId[AIndex];
1502 if imgState.LayerOriginalDefined[AIndex] then
1503 begin
1504 origData := TMemoryStream.Create;
1505 imgState.LayeredBitmap.SaveOriginalToStream(imgState.LayeredBitmap.LayerOriginalGuid[AIndex], origData);
1506 origMatrix := imgState.LayeredBitmap.LayerOriginalMatrix[AIndex];
1507 origRenderStatus:= imgState.LayeredBitmap.LayerOriginalRenderStatus[AIndex];
1508 end else
1509 begin
1510 origData := nil;
1511 origMatrix := AffineMatrixIdentity;
1512 origRenderStatus:= orsNone;
1513 end;
1514 end;
1515
1516 destructor TDiscardOriginalStateDifference.Destroy;
1517 begin
1518 origData.Free;
1519 inherited Destroy;
1520 end;
1521
1522 { TSetLayerMatrixDifference }
1523
TSetLayerMatrixDifference.GetImageDifferenceKindnull1524 function TSetLayerMatrixDifference.GetImageDifferenceKind: TImageDifferenceKind;
1525 begin
1526 Result:= idkChangeImage;
1527 end;
1528
GetIsIdentitynull1529 function TSetLayerMatrixDifference.GetIsIdentity: boolean;
1530 begin
1531 Result:= nextMatrix = previousMatrix;
1532 end;
1533
1534 constructor TSetLayerMatrixDifference.Create(ADestination: TState;
1535 ALayerId: integer; APreviousMatrix, ANextMatrix: TAffineMatrix);
1536 begin
1537 layerId:= ALayerId;
1538 previousMatrix := APreviousMatrix;
1539 nextMatrix := ANextMatrix;
1540 end;
1541
1542 procedure TSetLayerMatrixDifference.ApplyTo(AState: TState);
1543 var
1544 idx: Integer;
1545 begin
1546 inherited ApplyTo(AState);
1547 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1548 if idx =-1 then raise exception.Create('Layer not found');
1549 TImageState(AState).LayeredBitmap.LayerOriginalMatrix[idx] := nextMatrix;
1550 TImageState(AState).LayeredBitmap.RenderLayerFromOriginal(idx);
1551 end;
1552
1553 procedure TSetLayerMatrixDifference.UnapplyTo(AState: TState);
1554 var
1555 idx: Integer;
1556 begin
1557 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1558 if idx =-1 then raise exception.Create('Layer not found');
1559 TImageState(AState).LayeredBitmap.LayerOriginalMatrix[idx] := previousMatrix;
1560 TImageState(AState).LayeredBitmap.RenderLayerFromOriginal(idx);
1561 end;
1562
1563 { TSelectCurrentLayer }
1564
TSelectCurrentLayer.GetImageDifferenceKindnull1565 function TSelectCurrentLayer.GetImageDifferenceKind: TImageDifferenceKind;
1566 begin
1567 Result:= idkChangeImage; //selection layer can affect image
1568 end;
1569
1570 constructor TSelectCurrentLayer.Create(AState: TState; ANewLayerIndex: integer);
1571 begin
1572 inherited Create(AState.saved, AState.saved);
1573 FPrevLayerIndex:= (AState as TImageState).SelectedImageLayerIndex;
1574 FNewLayerIndex:= ANewLayerIndex;
1575 end;
1576
1577 procedure TSelectCurrentLayer.ApplyTo(AState: TState);
1578 begin
1579 (AState as TImageState).SelectedImageLayerIndex:= FNewLayerIndex;
1580 end;
1581
1582 procedure TSelectCurrentLayer.UnApplyTo(AState: TState);
1583 begin
1584 (AState as TImageState).SelectedImageLayerIndex:= FPrevLayerIndex;
1585 end;
1586
TSelectCurrentLayer.ToStringnull1587 function TSelectCurrentLayer.ToString: ansistring;
1588 begin
1589 Result:= ClassName+'('+IntToStr(FPrevLayerIndex)+' to '+IntToStr(FNewLayerIndex)+')';
1590 end;
1591
1592 { TAddLayerFromOwnedOriginalStateDifference }
1593
TAddLayerFromOwnedOriginalStateDifference.GetImageDifferenceKindnull1594 function TAddLayerFromOwnedOriginalStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1595 begin
1596 Result:= idkChangeImage;
1597 end;
1598
1599 procedure TAddLayerFromOwnedOriginalStateDifference.Uncompress;
1600 var
1601 decompression: Tdecompressionstream;
1602 uncompressedSize: Int64;
1603 begin
1604 if Assigned(compressedData) and not Assigned(originalData) then
1605 begin
1606 originalData:= TMemoryStream.Create;
1607 compressedData.Position := 0;
1608 uncompressedSize:= 0;
1609 compressedData.ReadBuffer(uncompressedSize, sizeof(uncompressedSize));
1610 decompression := Tdecompressionstream.Create(compressedData, true);
1611 originalData.CopyFrom(decompression, uncompressedSize);
1612 decompression.Free;
1613 FreeAndNil(compressedData);
1614 end
1615 end;
1616
TAddLayerFromOwnedOriginalStateDifference.UsedMemorynull1617 function TAddLayerFromOwnedOriginalStateDifference.UsedMemory: int64;
1618 begin
1619 if Assigned(originalData) then
1620 result := originalData.Size
1621 else
1622 if Assigned(compressedData) then
1623 result := compressedData.Size
1624 else
1625 result := 0;
1626 end;
1627
TryCompressnull1628 function TAddLayerFromOwnedOriginalStateDifference.TryCompress: boolean;
1629 var
1630 compression: Tcompressionstream;
1631 uncompressedSize: Int64;
1632 begin
1633 if Assigned(originalData) and not Assigned(compressedData) then
1634 begin
1635 compressedData:= TMemoryStream.Create;
1636 uncompressedSize := originalData.Size;
1637 compressedData.WriteBuffer(uncompressedSize, sizeof(uncompressedSize));
1638 compression := Tcompressionstream.Create(cldefault, compressedData, true);
1639 originalData.Position:= 0;
1640 compression.CopyFrom(originalData, originalData.Size);
1641 compression.Free;
1642 FreeAndNil(originalData);
1643 result := true;
1644 end
1645 else
1646 result := false;
1647 end;
1648
1649 procedure TAddLayerFromOwnedOriginalStateDifference.ApplyTo(AState: TState);
1650 var idx, origIdx: integer;
1651 begin
1652 inherited ApplyTo(AState);
1653 Uncompress;
1654 if not Assigned(originalData) then
1655 raise exception.Create('Original data missing');
1656
1657 with AState as TImageState do
1658 begin
1659 originalData.Position:= 0;
1660 origIdx:= LayeredBitmap.AddOriginalFromStream(originalData);
1661 idx := LayeredBitmap.AddLayerFromOriginal(LayeredBitmap.Original[origIdx].Guid, self.blendOp, self.opacity);
1662 LayeredBitmap.LayerUniqueId[idx] := self.layerId;
1663 LayeredBitmap.LayerName[idx] := name;
1664 LayeredBitmap.LayerOriginalMatrix[idx] := matrix;
1665 LayeredBitmap.RenderLayerFromOriginal(idx);
1666 SelectedImageLayerIndex := idx;
1667 end;
1668 end;
1669
1670 procedure TAddLayerFromOwnedOriginalStateDifference.UnapplyTo(AState: TState);
1671 var idx: integer;
1672 begin
1673 inherited UnapplyTo(AState);
1674 with AState as TImageState do
1675 begin
1676 idx := LayeredBitmap.GetLayerIndexFromId(self.layerId);
1677 LayeredBitmap.RemoveLayer(idx);
1678 SelectedImageLayerIndex := LayeredBitmap.GetLayerIndexFromId(self.previousActiveLayerId);
1679 end;
1680 end;
1681
1682 constructor TAddLayerFromOwnedOriginalStateDifference.Create(ADestination: TState;
1683 AOriginal: TBGRALayerCustomOriginal; AName: ansistring;
1684 ABlendOp: TBlendOperation; AMatrix: TAffineMatrix; AOpacity: Byte);
1685 var idx: integer;
1686 imgDest: TImageState;
1687 begin
1688 inherited Create(ADestination);
1689 imgDest := ADestination as TImageState;
1690 if imgDest.LayeredBitmap = nil then
1691 raise exception.Create('Layered bitmap not created');
1692
1693 self.originalData := TMemoryStream.Create;
1694 AOriginal.SaveToStream(originalData);
1695
1696 self.name := AName;
1697 self.blendOp:= AblendOp;
1698 self.matrix := AMatrix;
1699 self.previousActiveLayerId := imgDest.LayeredBitmap.LayerUniqueId[imgDest.SelectedImageLayerIndex];
1700 idx := imgDest.LayeredBitmap.AddLayerFromOwnedOriginal(AOriginal, ABlendOp, AOpacity);
1701 imgDest.LayeredBitmap.LayerName[idx] := name;
1702 imgDest.LayeredBitmap.LayerOriginalMatrix[idx] := matrix;
1703 self.layerId := imgDest.LayeredBitmap.LayerUniqueId[idx];
1704 imgDest.LayeredBitmap.RenderLayerFromOriginal(idx);
1705 imgDest.SelectedImageLayerIndex := idx;
1706 end;
1707
1708 destructor TAddLayerFromOwnedOriginalStateDifference.Destroy;
1709 begin
1710 originalData.Free;
1711 compressedData.Free;
1712 inherited Destroy;
1713 end;
1714
1715 { TApplyLayerOffsetStateDifference }
1716
GetImageDifferenceKindnull1717 function TApplyLayerOffsetStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1718 begin
1719 Result:= idkChangeImage;
1720 end;
1721
GetIsIdentitynull1722 function TApplyLayerOffsetStateDifference.GetIsIdentity: boolean;
1723 begin
1724 Result:= (previousBounds.Left = nextBounds.Left) and (previousBounds.Top = nextBounds.Top) and
1725 (previousBounds.right = nextBounds.Right) and (previousBounds.bottom = nextBounds.Bottom);
1726 end;
1727
GetChangingBoundsDefinednull1728 function TApplyLayerOffsetStateDifference.GetChangingBoundsDefined: boolean;
1729 begin
1730 Result:= true;
1731 end;
1732
GetChangingBoundsnull1733 function TApplyLayerOffsetStateDifference.GetChangingBounds: TRect;
1734 begin
1735 Result:= EmptyRect;
1736 end;
1737
1738 constructor TApplyLayerOffsetStateDifference.Create(ADestination: TState;
1739 ALayerId: integer; AOffsetX, AOffsetY: integer; AApplyNow: boolean);
1740 var idx: integer;
1741 layers: TBGRALayeredBitmap;
1742 clippedImage: TBGRABitmap;
1743 begin
1744 inherited Create(ADestination);
1745 layerId:= ALayerId;
1746 layers := (ADestination as TImageState).LayeredBitmap;
1747 idx := layers.GetLayerIndexFromId(ALayerId);
1748 if idx = -1 then raise exception.Create('Invalid layer Id');
1749 nextBounds := rect(0,0,layers.Width,layers.Height);
1750 previousBounds.Left := AOffsetX;
1751 previousBounds.Top := AOffsetY;
1752 previousBounds.Right := previousBounds.Left+layers.LayerBitmap[idx].Width;
1753 previousBounds.Bottom := previousBounds.Top+layers.LayerBitmap[idx].Height;
1754 previousLayerOffset := layers.LayerOffset[idx];
1755 if IsIdentity then
1756 begin
1757 clippedData := nil;
1758 useOriginal := false;
1759 unchangedBounds := previousBounds;
1760 end else
1761 begin
1762 unchangedBounds := previousBounds;
1763 IntersectRect(unchangedBounds, unchangedBounds, nextBounds);
1764 OffsetRect(unchangedBounds, -AOffsetX, -AOffsetY);
1765 useOriginal:= layers.LayerOriginalGuid[idx]<>GUID_NULL;
1766 previousOriginalRenderStatus:= layers.LayerOriginalRenderStatus[idx];
1767
1768 clippedImage := layers.LayerBitmap[idx].Duplicate as TBGRABitmap;
1769 clippedImage.FillRect(unchangedBounds,BGRAPixelTransparent,dmSet);
1770 clippedData := TMemoryStream.Create;
1771 TBGRAWriterLazPaint.WriteRLEImage(clippedData, clippedImage);
1772 clippedImage.Free;
1773 end;
1774 if AApplyNow then ApplyTo(ADestination);
1775 end;
1776
1777 destructor TApplyLayerOffsetStateDifference.Destroy;
1778 begin
1779 FreeAndNil(clippedData);
1780 inherited Destroy;
1781 end;
1782
1783 procedure TApplyLayerOffsetStateDifference.ApplyTo(AState: TState);
1784 var idx: integer;
1785 begin
1786 inherited ApplyTo(AState);
1787 if IsIdentity then exit;
1788 idx := (AState as TImageState).LayeredBitmap.GetLayerIndexFromId(layerId);
1789 if idx =-1 then raise exception.Create('Layer not found');
1790 (AState as TImageState).LayeredBitmap.ApplyLayerOffset(idx, true);
1791 end;
1792
1793 procedure TApplyLayerOffsetStateDifference.UnapplyTo(AState: TState);
1794 var idx: integer;
1795 newContent: TBGRABitmap;
1796 layers: TBGRALayeredBitmap;
1797 shifted: TRect;
1798 dummyCaption: ansistring;
1799 guid: TGuid;
1800 m: TAffineMatrix;
1801 begin
1802 inherited ApplyTo(AState);
1803 if IsIdentity then exit;
1804 layers := (AState as TImageState).LayeredBitmap;
1805 idx := layers.GetLayerIndexFromId(layerId);
1806 if idx =-1 then
1807 raise exception.Create('Layer not found');
1808
1809 newContent := TBGRABitmap.Create;
1810 clippedData.Position:= 0;
1811 TBGRAReaderLazPaint.LoadRLEImage(clippedData,newContent,dummyCaption);
1812 shifted := unchangedBounds;
1813 OffsetRect(shifted, previousBounds.left-nextBounds.left,previousBounds.top-nextBounds.top);
1814 newContent.PutImagePart(unchangedBounds.Left,unchangedBounds.Top, layers.LayerBitmap[idx],shifted, dmSet);
1815 guid := layers.LayerOriginalGuid[idx];
1816 m := layers.LayerOriginalMatrix[idx];
1817 layers.SetLayerBitmap(idx,newContent,True);
1818 layers.LayerOffset[idx] := previousLayerOffset;
1819 if useOriginal then
1820 begin
1821 layers.LayerOriginalGuid[idx] := guid;
1822 layers.LayerOriginalMatrix[idx] := m;
1823 layers.LayerOriginalRenderStatus[idx] := previousOriginalRenderStatus;
1824 end;
1825 end;
1826
1827 { TSetLayerOffsetStateDifference }
1828
GetImageDifferenceKindnull1829 function TSetLayerOffsetStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1830 begin
1831 Result:= idkChangeImage;
1832 end;
1833
GetIsIdentitynull1834 function TSetLayerOffsetStateDifference.GetIsIdentity: boolean;
1835 begin
1836 Result:=(previousOffset.x = nextOffset.x) and (previousOffset.y = nextOffset.y);
1837 end;
1838
1839 constructor TSetLayerOffsetStateDifference.Create(ADestination: TState;
1840 ALayerId: integer; ANewOffset: TPoint);
1841 var idx: integer;
1842 imgDest: TImageState;
1843 begin
1844 inherited Create(Adestination);
1845 imgDest := ADestination as TImageState;
1846 layerId:= ALayerId;
1847 nextOffset:= ANewOffset;
1848 idx := imgDest.LayeredBitmap.GetLayerIndexFromId(ALayerId);
1849 if idx =-1 then
1850 raise exception.Create('Layer not found');
1851 previousOffset:= imgDest.LayerOffset[idx];
1852 ApplyTo(imgDest);
1853 end;
1854
1855 procedure TSetLayerOffsetStateDifference.ApplyTo(AState: TState);
1856 var idx: integer;
1857 begin
1858 inherited ApplyTo(AState);
1859 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1860 if idx =-1 then
1861 raise exception.Create('Layer not found');
1862 TImageState(AState).LayeredBitmap.LayerOffset[idx] := nextOffset;
1863 end;
1864
1865 procedure TSetLayerOffsetStateDifference.UnapplyTo(AState: TState);
1866 var idx: integer;
1867 begin
1868 inherited UnapplyTo(AState);
1869 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1870 if idx =-1 then
1871 raise exception.Create('Layer not found');
1872 TImageState(AState).LayeredBitmap.LayerOffset[idx] := previousOffset;
1873 end;
1874
1875 { TSetLayerBlendOpStateDifference }
1876
GetImageDifferenceKindnull1877 function TSetLayerBlendOpStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1878 begin
1879 Result:= idkChangeImage;
1880 end;
1881
TSetLayerBlendOpStateDifference.GetChangingBoundsnull1882 function TSetLayerBlendOpStateDifference.GetChangingBounds: TRect;
1883 begin
1884 Result:= layerBounds;
1885 end;
1886
GetChangingBoundsDefinednull1887 function TSetLayerBlendOpStateDifference.GetChangingBoundsDefined: boolean;
1888 begin
1889 Result:= true;
1890 end;
1891
GetIsIdentitynull1892 function TSetLayerBlendOpStateDifference.GetIsIdentity: boolean;
1893 begin
1894 Result:=previousBlendOp = nextBlendOp;
1895 end;
1896
1897 constructor TSetLayerBlendOpStateDifference.Create(ADestination: TState;
1898 ALayerId: integer; ANewBlendOp: TBlendOperation);
1899 var idx: integer;
1900 imgDest: TImageState;
1901 begin
1902 inherited Create(Adestination);
1903 imgDest := ADestination as TImageState;
1904 layerId:= ALayerId;
1905 nextBlendOp:= ANewBlendOp;
1906 idx := imgDest.LayeredBitmap.GetLayerIndexFromId(ALayerId);
1907 if idx =-1 then
1908 raise exception.Create('Layer not found');
1909 previousBlendOp:= imgDest.BlendOperation[idx];
1910 layerBounds := imgDest.LayerBitmap[idx].GetImageBounds;
1911 with imgDest.LayerOffset[idx] do layerBounds.Offset(x,y);
1912 ApplyTo(imgDest);
1913 end;
1914
1915 procedure TSetLayerBlendOpStateDifference.ApplyTo(AState: TState);
1916 var idx: integer;
1917 begin
1918 inherited ApplyTo(AState);
1919 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1920 if idx =-1 then
1921 raise exception.Create('Layer not found');
1922 TImageState(AState).LayeredBitmap.BlendOperation[idx] := nextBlendOp;
1923 end;
1924
1925 procedure TSetLayerBlendOpStateDifference.UnapplyTo(AState: TState);
1926 var idx: integer;
1927 begin
1928 inherited UnapplyTo(AState);
1929 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1930 if idx =-1 then
1931 raise exception.Create('Layer not found');
1932 TImageState(AState).LayeredBitmap.BlendOperation[idx] := previousBlendOp;
1933 end;
1934
1935 { TSetLayerVisibleStateDifference }
1936
GetImageDifferenceKindnull1937 function TSetLayerVisibleStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1938 begin
1939 Result:= idkChangeImage;
1940 end;
1941
TSetLayerVisibleStateDifference.GetChangingBoundsnull1942 function TSetLayerVisibleStateDifference.GetChangingBounds: TRect;
1943 begin
1944 Result:= layerBounds;
1945 end;
1946
GetChangingBoundsDefinednull1947 function TSetLayerVisibleStateDifference.GetChangingBoundsDefined: boolean;
1948 begin
1949 Result:= true;
1950 end;
1951
GetIsIdentitynull1952 function TSetLayerVisibleStateDifference.GetIsIdentity: boolean;
1953 begin
1954 Result:= previousVisible=nextVisible;
1955 end;
1956
1957 constructor TSetLayerVisibleStateDifference.Create(ADestination: TState;
1958 ALayerId: integer; ANewVisible: boolean);
1959 var idx: integer;
1960 imgDest: TImageState;
1961 begin
1962 inherited Create(Adestination);
1963 imgDest := ADestination as TImageState;
1964 layerId:= ALayerId;
1965 nextVisible:= ANewVisible;
1966 idx := imgDest.LayeredBitmap.GetLayerIndexFromId(ALayerId);
1967 if idx =-1 then
1968 raise exception.Create('Layer not found');
1969 previousVisible:= imgDest.LayerVisible[idx];
1970 layerBounds := imgDest.LayerBitmap[idx].GetImageBounds;
1971 with imgDest.LayerOffset[idx] do layerBounds.Offset(x,y);
1972 ApplyTo(imgDest);
1973 end;
1974
1975 procedure TSetLayerVisibleStateDifference.ApplyTo(AState: TState);
1976 var idx: integer;
1977 begin
1978 inherited ApplyTo(AState);
1979 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1980 if idx =-1 then
1981 raise exception.Create('Layer not found');
1982 TImageState(AState).LayeredBitmap.LayerVisible[idx] := nextVisible;
1983 end;
1984
1985 procedure TSetLayerVisibleStateDifference.UnapplyTo(AState: TState);
1986 var idx: integer;
1987 begin
1988 inherited UnapplyTo(AState);
1989 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
1990 if idx =-1 then
1991 raise exception.Create('Layer not found');
1992 TImageState(AState).LayeredBitmap.LayerVisible[idx] := previousVisible;
1993 end;
1994
1995 { TSetLayerOpacityStateDifference }
1996
TSetLayerOpacityStateDifference.GetImageDifferenceKindnull1997 function TSetLayerOpacityStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
1998 begin
1999 Result:= idkChangeImage;
2000 end;
2001
TSetLayerOpacityStateDifference.GetChangingBoundsnull2002 function TSetLayerOpacityStateDifference.GetChangingBounds: TRect;
2003 begin
2004 Result:= layerBounds;
2005 end;
2006
GetChangingBoundsDefinednull2007 function TSetLayerOpacityStateDifference.GetChangingBoundsDefined: boolean;
2008 begin
2009 Result:= true;
2010 end;
2011
GetIsIdentitynull2012 function TSetLayerOpacityStateDifference.GetIsIdentity: boolean;
2013 begin
2014 Result:= (previousOpacity=nextOpacity);
2015 end;
2016
2017 constructor TSetLayerOpacityStateDifference.Create(ADestination: TState;
2018 ALayerId: integer; ANewOpacity: byte);
2019 var idx: integer;
2020 imgDest: TImageState;
2021 begin
2022 inherited Create(Adestination);
2023 imgDest := ADestination as TImageState;
2024 layerId:= ALayerId;
2025 nextOpacity:= ANewOpacity;
2026 idx := imgDest.LayeredBitmap.GetLayerIndexFromId(ALayerId);
2027 if idx =-1 then
2028 raise exception.Create('Layer not found');
2029 previousOpacity:= imgDest.LayerOpacity[idx];
2030 layerBounds := imgDest.LayerBitmap[idx].GetImageBounds;
2031 with imgDest.LayerOffset[idx] do layerBounds.Offset(x,y);
2032 ApplyTo(imgDest);
2033 end;
2034
2035 procedure TSetLayerOpacityStateDifference.ApplyTo(AState: TState);
2036 var idx: integer;
2037 begin
2038 inherited ApplyTo(AState);
2039 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
2040 if idx =-1 then
2041 raise exception.Create('Layer not found');
2042 TImageState(AState).LayeredBitmap.LayerOpacity[idx] := nextOpacity;
2043 end;
2044
2045 procedure TSetLayerOpacityStateDifference.UnapplyTo(AState: TState);
2046 var idx: integer;
2047 begin
2048 inherited UnapplyTo(AState);
2049 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
2050 if idx =-1 then
2051 raise exception.Create('Layer not found');
2052 TImageState(AState).LayeredBitmap.LayerOpacity[idx] := previousOpacity;
2053 end;
2054
2055 { TSetLayerNameStateDifference }
2056
TSetLayerNameStateDifference.GetImageDifferenceKindnull2057 function TSetLayerNameStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2058 begin
2059 Result:= idkChangeStack;
2060 end;
2061
GetIsIdentitynull2062 function TSetLayerNameStateDifference.GetIsIdentity: boolean;
2063 begin
2064 Result:= (previousName=nextName);
2065 end;
2066
2067 constructor TSetLayerNameStateDifference.Create(ADestination: TState;
2068 ALayerId: integer; ANewName: ansistring);
2069 var idx: integer;
2070 imgDest: TImageState;
2071 begin
2072 inherited Create(Adestination);
2073 imgDest := ADestination as TImageState;
2074 layerId:= ALayerId;
2075 nextName:= ANewName;
2076 idx := imgDest.LayeredBitmap.GetLayerIndexFromId(ALayerId);
2077 if idx =-1 then
2078 raise exception.Create('Layer not found');
2079 previousName:= imgDest.LayerName[idx];
2080 ApplyTo(imgDest);
2081 end;
2082
2083 procedure TSetLayerNameStateDifference.ApplyTo(AState: TState);
2084 var idx: integer;
2085 begin
2086 inherited ApplyTo(AState);
2087 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
2088 if idx =-1 then
2089 raise exception.Create('Layer not found');
2090 TImageState(AState).LayeredBitmap.LayerName[idx] := nextName;
2091 end;
2092
2093 procedure TSetLayerNameStateDifference.UnapplyTo(AState: TState);
2094 var idx: integer;
2095 begin
2096 inherited ApplyTo(AState);
2097 idx := TImageState(AState).LayeredBitmap.GetLayerIndexFromId(layerId);
2098 if idx =-1 then
2099 raise exception.Create('Layer not found');
2100 TImageState(AState).LayeredBitmap.LayerName[idx] := previousName;
2101 end;
2102
TSetLayerNameStateDifference.ToStringnull2103 function TSetLayerNameStateDifference.ToString: ansistring;
2104 begin
2105 Result:=ClassName+'('+QuotedStr(previousName)+' to '+QuotedStr(nextName)+')';
2106 end;
2107
2108 { TAssignStateDifferenceAfter }
2109
2110 constructor TAssignStateDifferenceAfter.Create(AState: TState; ABackup: TState);
2111 var imgState,imgBackup: TImageState;
2112 begin
2113 imgState := AState as TImageState;
2114 imgBackup := ABackup as TImageState;
2115 FSavedBefore := imgState.saved;
2116 FSavedAfter := False;
2117 FStreamBefore := TMemoryStream.Create;
2118 SaveLayersToStream(FStreamBefore,imgBackup.LayeredBitmap,imgBackup.SelectedImageLayerIndex,lzpRLE);
2119 FStreamAfter := TMemoryStream.Create;
2120 SaveLayersToStream(FStreamAfter,imgState.LayeredBitmap,imgState.SelectedImageLayerIndex,lzpRLE);
2121 FSelectionDiff := TImageDiff.Create(imgBackup.SelectionMask, imgState.SelectionMask, True);
2122 FSelectionLayerDiff := TImageDiff.Create(imgBackup.SelectionLayer, imgState.SelectionLayer, False);
2123 end;
2124
2125 { TAssignStateDifference }
2126
2127 procedure TAssignStateDifference.Init(AState: TState; AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer);
2128 begin
2129 with AState as TImageState do
2130 begin
2131 FStreamBefore := TMemoryStream.Create;
2132 SaveLayersToStream(FStreamBefore,LayeredBitmap,SelectedImageLayerIndex,lzpRLE);
2133 FStreamAfter := TMemoryStream.Create;
2134 SaveLayersToStream(FStreamAfter,AValue,ASelectedLayerIndex,lzpRLE);
2135 Assign(AValue, AOwned);
2136 SelectedImageLayerIndex := ASelectedLayerIndex;
2137 end;
2138 FSelectionDiff := nil;
2139 FSelectionLayerDiff := nil;
2140 end;
2141
2142 constructor TAssignStateDifference.Create(AState: TState;
2143 AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer);
2144 begin
2145 inherited Create(AState);
2146 Init(AState, AValue, AOwned, ASelectedLayerIndex);
2147 end;
2148
2149 constructor TAssignStateDifference.Create(AState: TState;
2150 AValue: TBGRACustomLayeredBitmap; AOwned: boolean; ASelectedLayerIndex: integer;
2151 ACurrentSelection: TBGRABitmap; ASelectionLayer: TBGRABitmap);
2152 begin
2153 inherited Create(AState);
2154 Init(AState, AValue, AOwned, ASelectedLayerIndex);
2155 FSelectionDiff := TImageDiff.Create((AState as TImageState).SelectionMask, ACurrentSelection, True);
2156 FSelectionLayerDiff := TImageDiff.Create((AState as TImageState).SelectionLayer, ASelectionLayer, False);
2157 (AState as TImageState).ReplaceSelection(ACurrentSelection, ASelectionLayer);
2158 end;
2159
TAssignStateDifference.UsedMemorynull2160 function TAssignStateDifference.UsedMemory: int64;
2161 begin
2162 Result:= 0;
2163 if Assigned(FStreamBefore) then result += FStreamBefore.Size;
2164 if Assigned(FStreamAfter) then result += FStreamAfter.Size;
2165 if Assigned(FSelectionDiff) then result += FSelectionDiff.UsedMemory;
2166 if Assigned(FSelectionLayerDiff) then result += FSelectionLayerDiff.UsedMemory;
2167 end;
2168
TryCompressnull2169 function TAssignStateDifference.TryCompress: boolean;
2170 begin
2171 result := false;
2172 if Assigned(FSelectionDiff) then result := result or FSelectionDiff.Compress;
2173 if not result and Assigned(FSelectionLayerDiff) then result := result or FSelectionLayerDiff.Compress;
2174 end;
2175
2176 procedure TAssignStateDifference.ApplyTo(AState: TState);
2177 var temp: TBGRALayeredBitmap;
2178 index: integer;
2179 begin
2180 inherited ApplyTo(AState);
2181 FStreamAfter.Position:= 0;
2182 temp := LoadLayersFromStream(FStreamAfter, index, True);
2183 (AState as TImageState).Assign(temp, True);
2184 (AState as TImageState).SelectedImageLayerIndex := index;
2185 (AState as TImageState).ReplaceSelection( FSelectionDiff.ApplyCanCreateNew((AState as TImageState).SelectionMask, False, True),
2186 FSelectionLayerDiff.ApplyCanCreateNew((AState as TImageState).SelectionLayer, False, True) );
2187 end;
2188
2189 procedure TAssignStateDifference.UnApplyTo(AState: TState);
2190 var temp: TBGRALayeredBitmap;
2191 index: integer;
2192 begin
2193 inherited UnapplyTo(AState);
2194 FStreamBefore.Position:= 0;
2195 temp := LoadLayersFromStream(FStreamBefore, index, True);
2196 (AState as TImageState).Assign(temp, True);
2197 (AState as TImageState).SelectedImageLayerIndex := index;
2198 (AState as TImageState).ReplaceSelection( FSelectionDiff.ApplyCanCreateNew((AState as TImageState).SelectionMask, True, True),
2199 FSelectionLayerDiff.ApplyCanCreateNew((AState as TImageState).SelectionLayer, True, True) );
2200 end;
2201
2202 destructor TAssignStateDifference.Destroy;
2203 begin
2204 FStreamBefore.Free;
2205 FStreamAfter.Free;
2206 FSelectionDiff.Free;
2207 FSelectionLayerDiff.Free;
2208 inherited Destroy;
2209 end;
2210
2211 { TInversibleStateDifference }
2212
2213 constructor TInversibleStateDifference.Create(AState: TState;
2214 AAction: TInversibleAction; ALayerIndex : integer = -1);
2215 begin
2216 inherited Create(AState);
2217 FAction := AAction;
2218 FLayerIndex:= ALayerIndex;
2219 ApplyTo(AState);
2220 end;
2221
2222 procedure TInversibleStateDifference.ApplyTo(AState: TState);
2223 begin
2224 inherited ApplyTo(AState);
2225 ApplyAction(AState as TImageState, FAction, False);
2226 end;
2227
2228 procedure TInversibleStateDifference.UnApplyTo(AState: TState);
2229 begin
2230 inherited UnapplyTo(AState);
2231 ApplyAction(AState as TImageState, FAction, True);
2232 end;
2233
2234 procedure TInversibleStateDifference.ApplyAction(AState: TState;
2235 AAction: TInversibleAction; AInverse: boolean);
2236 var i: integer;
2237 imgState: TImageState;
2238 newSelectionMask, newSelectionLayer: TBGRABitmap;
2239 begin
2240 imgState := AState as TImageState;
2241 if AInverse then AAction := GetInverseAction(AAction);
2242 case AAction of
2243 iaSwapRedBlue,iaLinearNegative:
2244 begin
2245 for i := 0 to imgState.NbLayers-1 do
2246 if imgState.LayerOriginalDefined[i] then
2247 raise exception.Create('Cannot do an inversible raster action with layer originals');
2248 case AAction of
2249 iaSwapRedBlue: begin
2250 imgState.LayeredBitmap.Unfreeze;
2251 for i := 0 to imgState.NbLayers-1 do imgState.LayerBitmap[i].SwapRedBlue;
2252 end;
2253 iaLinearNegative:
2254 begin
2255 imgState.LayeredBitmap.Unfreeze;
2256 for i := 0 to imgState.NbLayers-1 do imgState.LayerBitmap[i].LinearNegative;
2257 end
2258 else
2259 raise exception.Create('Unhandled case');
2260 end;
2261 end;
2262 iaHorizontalFlip: imgState.LayeredBitmap.HorizontalFlip;
2263 iaHorizontalFlipLayer: imgState.LayeredBitmap.HorizontalFlip(FLayerIndex);
2264 iaVerticalFlip: imgState.LayeredBitmap.VerticalFlip;
2265 iaVerticalFlipLayer: imgState.LayeredBitmap.VerticalFlip(FLayerIndex);
2266 iaRotate180: begin
2267 imgState.LayeredBitmap.HorizontalFlip;
2268 imgState.LayeredBitmap.VerticalFlip;
2269 end;
2270 iaRotateCW: begin
2271 imgState.LayeredBitmap.RotateCW;
2272 if imgState.SelectionMask <> nil then newSelectionMask := imgState.SelectionMask.RotateCW as TBGRABitmap else newSelectionMask := nil;
2273 if imgState.SelectionLayer <> nil then newSelectionLayer := imgState.SelectionLayer.RotateCW as TBGRABitmap else newSelectionLayer := nil;
2274 imgState.ReplaceSelection(newSelectionMask, newSelectionLayer);
2275 if (imgState.Width <> imgState.Height) then imgState.NotifySizeChanged;
2276 end;
2277 iaRotateCCW: begin
2278 imgState.LayeredBitmap.RotateCCW;
2279 if imgState.SelectionMask <> nil then newSelectionMask := imgState.SelectionMask.RotateCCW as TBGRABitmap else newSelectionMask := nil;
2280 if imgState.SelectionLayer <> nil then newSelectionLayer := imgState.SelectionLayer.RotateCCW as TBGRABitmap else newSelectionLayer := nil;
2281 imgState.ReplaceSelection(newSelectionMask, newSelectionLayer);
2282 if (imgState.Width <> imgState.Height) then imgState.NotifySizeChanged;
2283 end;
2284 end;
2285 end;
2286
TInversibleStateDifference.ToStringnull2287 function TInversibleStateDifference.ToString: ansistring;
2288 begin
2289 Result:= ClassName+'('+InversibleActionStr[FAction];
2290 if FLayerIndex <> -1 then result += ', '+inttostr(FLayerIndex);
2291 result += ')';
2292 end;
2293
2294 { TRemoveLayerStateDifference }
2295
GetImageDifferenceKindnull2296 function TRemoveLayerStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2297 begin
2298 Result:=idkChangeImage;
2299 end;
2300
UsedMemorynull2301 function TRemoveLayerStateDifference.UsedMemory: int64;
2302 begin
2303 if Assigned(FContent) then
2304 result := FContent.UsedMemory
2305 else
2306 result := 0;
2307 end;
2308
TryCompressnull2309 function TRemoveLayerStateDifference.TryCompress: boolean;
2310 begin
2311 Result:= FContent.Compress;
2312 end;
2313
2314 procedure TRemoveLayerStateDifference.ApplyTo(AState: TState);
2315 var idx: integer;
2316 begin
2317 inherited ApplyTo(AState);
2318 with AState as TImageState do
2319 begin
2320 idx := LayeredBitmap.GetLayerIndexFromId(FContent.LayerId);
2321 LayeredBitmap.RemoveLayer(idx);
2322 LayeredBitmap.RemoveUnusedOriginals;
2323 SelectedImageLayerIndex := LayeredBitmap.GetLayerIndexFromId(self.FNextActiveLayerId);
2324 end;
2325 end;
2326
2327 procedure TRemoveLayerStateDifference.UnapplyTo(AState: TState);
2328 begin
2329 inherited UnapplyTo(AState);
2330 with AState as TImageState do
2331 begin
2332 FContent.Restore(LayeredBitmap);
2333 SelectedImageLayerIndex := FContent.LayerIndex;
2334 end;
2335 end;
2336
2337 constructor TRemoveLayerStateDifference.Create(AState: TState; AApplyNow: boolean);
2338 var idx,nextIdx: integer;
2339 imgState: TImageState;
2340 begin
2341 inherited Create(AState);
2342 imgState := AState as TImageState;
2343 if imgState.LayeredBitmap = nil then
2344 raise exception.Create('Layered bitmap not created');
2345 if imgState.NbLayers = 1 then
2346 raise exception.Create('Impossible to remove last layer');
2347 idx := imgState.SelectedImageLayerIndex;
2348 if idx = -1 then
2349 raise exception.Create('No layer selected');
2350 self.FContent := TStoredLayer.Create(imgState.LayeredBitmap, idx);
2351 if idx+1 < imgState.NbLayers then
2352 nextIdx := idx+1 else nextIdx := idx-1;
2353 self.FNextActiveLayerId := imgState.LayeredBitmap.LayerUniqueId[nextIdx];
2354 if AApplyNow then ApplyTo(AState);
2355 end;
2356
2357 destructor TRemoveLayerStateDifference.Destroy;
2358 begin
2359 self.FContent.Free;
2360 inherited Destroy;
2361 end;
2362
2363 { TMergeLayerOverStateDifference }
2364
GetImageDifferenceKindnull2365 function TMergeLayerOverStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2366 begin
2367 Result:= idkChangeImage; //includes stack
2368 end;
2369
2370 constructor TMergeLayerOverStateDifference.Create(ADestination: TState;
2371 ALayerOverIndex: integer);
2372 var
2373 imgDest: TImageState;
2374 totalCost: Integer;
2375 begin
2376 inherited Create(ADestination);
2377 imgDest := ADestination as TImageState;
2378 if (ALayerOverIndex < 0) or (ALayerOverIndex >= imgDest.NbLayers) then
2379 raise exception.Create('Index out of bounds');
2380 if ALayerOverIndex = 0 then
2381 raise exception.Create('First layer cannot be merged over');
2382
2383 mergeVectorial := false;
2384 mergeVectorialGuid := GUID_NULL;
2385 layerOverIndex := ALayerOverIndex;
2386 with imgDest.LayeredBitmap do
2387 begin
2388 previousActiveLayerId:= LayerUniqueId[imgDest.SelectedImageLayerIndex];
2389 layerOverCompressedBackup := TStoredLayer.Create(imgDest.LayeredBitmap, ALayerOverIndex, true);
2390 layerUnderCompressedBackup := TStoredLayer.Create(imgDest.LayeredBitmap, ALayerOverIndex-1, true);
2391 if ((LayerOriginalClass[ALayerOverIndex] = TVectorOriginal) or
2392 (LayerOriginalClass[ALayerOverIndex-1] = TVectorOriginal) or
2393 (LayerOriginalClass[ALayerOverIndex] = TBGRALayerGradientOriginal) or
2394 (LayerOriginalClass[ALayerOverIndex-1] = TBGRALayerGradientOriginal)) and
2395 (BlendOperation[ALayerOverIndex] = boTransparent) and
2396 (BlendOperation[ALayerOverIndex-1] = boTransparent) then
2397 begin
2398 totalCost := 0;
2399 if LayerOriginalClass[ALayerOverIndex] = TVectorOriginal then
2400 inc(totalCost, TVectorOriginal(LayerOriginal[ALayerOverIndex]).GetShapesCost)
2401 else inc(totalCost, 10);
2402 if LayerOriginalClass[ALayerOverIndex-1] = TVectorOriginal then
2403 inc(totalCost, TVectorOriginal(LayerOriginal[ALayerOverIndex-1]).GetShapesCost)
2404 else inc(totalCost, 10);
2405 if totalCost <= MediumShapeCost then mergeVectorial := true;
2406 end;
2407 end;
2408
2409 //select layer under and merge
2410 ApplyTo(imgDest);
2411 end;
2412
UsedMemorynull2413 function TMergeLayerOverStateDifference.UsedMemory: int64;
2414 begin
2415 Result:=0;
2416 if Assigned(layerOverCompressedBackup) then result += layerOverCompressedBackup.UsedMemory;
2417 if Assigned(layerUnderCompressedBackup) then result += layerUnderCompressedBackup.UsedMemory;
2418 end;
2419
TryCompressnull2420 function TMergeLayerOverStateDifference.TryCompress: boolean;
2421 begin
2422 result := layerOverCompressedBackup.Compress or layerUnderCompressedBackup.Compress;
2423 end;
2424
2425 procedure TMergeLayerOverStateDifference.ApplyTo(AState: TState);
2426 var
2427 merged: TBGRABitmap;
2428 mergedOriginal: TVectorOriginal;
2429
2430 procedure AppendToMergedOriginal(ALayeredBitmap: TBGRALayeredBitmap; ALayerIndex: integer);
2431 var
2432 vectOrig: TVectorOriginal;
2433 m: TAffineMatrix;
2434 i: Integer;
2435 s: TVectorShape;
2436 temp: TBGRABitmap;
2437 b: TRect;
2438 c: TBGRALayerOriginalAny;
2439 begin
2440 c := ALayeredBitmap.LayerOriginalClass[ALayerIndex];
2441 m := ALayeredBitmap.LayerOriginalMatrix[ALayerIndex];
2442 if c = TVectorOriginal then
2443 begin
2444 vectOrig := ALayeredBitmap.LayerOriginal[ALayerIndex] as TVectorOriginal;
2445 for i := 0 to vectOrig.ShapeCount-1 do
2446 begin
2447 s := vectOrig.Shape[i].Duplicate;
2448 s.Transform(m);
2449 mergedOriginal.AddShape(s);
2450 end;
2451 end else
2452 if c = TBGRALayerGradientOriginal then
2453 begin
2454 s := TRectShape.Create(mergedOriginal);
2455 s.PenStyle := ClearPenStyle;
2456 s.BackFill.SetGradient(ALayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerGradientOriginal, false);
2457 s.BackFill.Transform(m);
2458 s.QuickDefine(PointF(-0.5,-0.5), PointF(ALayeredBitmap.width-0.5,ALayeredBitmap.Height-0.5));
2459 mergedOriginal.AddShape(s);
2460 end else
2461 if c = TBGRALayerImageOriginal then
2462 begin
2463 temp := (ALayeredBitmap.LayerOriginal[ALayerIndex] as TBGRALayerImageOriginal).GetImageCopy;
2464 if Assigned(temp) then
2465 begin
2466 if not temp.Empty then
2467 begin
2468 s := TRectShape.Create(mergedOriginal);
2469 s.PenStyle := ClearPenStyle;
2470 if temp.Equals(temp.GetPixel(0,0)) then
2471 s.BackFill.SetSolid(temp.GetPixel(0,0))
2472 else s.BackFill.SetTexture(temp, AffineMatrixIdentity, 255, trNone);
2473 s.QuickDefine(PointF(-0.5,-0.5), PointF(temp.width-0.5,temp.Height-0.5));
2474 s.Transform(m);
2475 mergedOriginal.AddShape(s);
2476 end;
2477 temp.FreeReference;
2478 end;
2479 end else
2480 begin
2481 if Assigned(ALayeredBitmap.LayerBitmap[ALayerIndex]) then
2482 begin
2483 b := ALayeredBitmap.LayerBitmap[ALayerIndex].GetImageBounds;
2484 if not b.IsEmpty then
2485 begin
2486 temp := ALayeredBitmap.LayerBitmap[ALayerIndex].GetPart(b) as TBGRABitmap;
2487 s := TRectShape.Create(mergedOriginal);
2488 s.PenStyle := ClearPenStyle;
2489 if temp.Equals(temp.GetPixel(0,0)) then
2490 s.BackFill.SetSolid(temp.GetPixel(0,0))
2491 else s.BackFill.SetTexture(temp, AffineMatrixIdentity, 255, trNone);
2492 s.QuickDefine(PointF(-0.5,-0.5), PointF(temp.width-0.5,temp.Height-0.5));
2493 with ALayeredBitmap.LayerOffset[ALayerIndex] do
2494 s.Transform(AffineMatrixTranslation(b.Left+X,b.Top+Y));
2495 mergedOriginal.AddShape(s);
2496 temp.FreeReference;
2497 end;
2498 end;
2499 end;
2500 end;
2501
2502 begin
2503 inherited ApplyTo(AState);
2504 with AState as TImageState do
2505 begin
2506 if layerOverIndex >= NbLayers then exit;
2507
2508 SelectedImageLayerIndex := layerOverIndex-1;
2509 if mergeVectorial then
2510 begin
2511 mergedOriginal := TVectorOriginal.Create;
2512 mergedOriginal.Guid := mergeVectorialGuid;
2513 AppendToMergedOriginal(LayeredBitmap, layerOverIndex-1);
2514 AppendToMergedOriginal(LayeredBitmap, layerOverIndex);
2515 LayeredBitmap.AddOriginal(mergedOriginal);
2516 mergeVectorialGuid := mergedOriginal.Guid;
2517 LayeredBitmap.LayerOriginalGuid[layerOverIndex-1] := mergedOriginal.Guid;
2518 LayeredBitmap.LayerOriginalMatrix[layerOverIndex-1] := AffineMatrixIdentity;
2519 LayeredBitmap.RenderLayerFromOriginal(layerOverIndex-1);
2520 end else
2521 if (LayerBitmap[layerOverIndex-1].Width <> Width) or
2522 (LayerBitmap[layerOverIndex-1].Height <> Height) or
2523 (LayerOffset[layerOverIndex-1].X <> 0) or
2524 (LayerOffset[layerOverIndex-1].Y <> 0) then
2525 begin
2526 merged := TBGRABitmap.Create(Width,Height);
2527 merged.PutImage(LayerOffset[layerOverIndex-1].X,LayerOffset[layerOverIndex-1].Y,LayerBitmap[layerOverIndex-1],dmSet);
2528 merged.BlendImageOver(LayerOffset[layerOverIndex].X,LayerOffset[layerOverIndex].Y,LayerBitmap[layerOverIndex],
2529 BlendOperation[layerOverIndex],LayerOpacity[layerOverIndex],LinearBlend);
2530 LayeredBitmap.SetLayerBitmap(layerOverIndex-1, merged,true);
2531 LayeredBitmap.LayerOffset[layerOverIndex-1] := Point(0,0);
2532 end else
2533 begin
2534 LayeredBitmap.LayerOriginalGuid[layerOverIndex-1] := GUID_NULL;
2535 LayeredBitmap.LayerOriginalMatrix[layerOverIndex-1] := AffineMatrixIdentity;
2536 LayerBitmap[layerOverIndex-1].BlendImageOver(LayerOffset[layerOverIndex].X,LayerOffset[layerOverIndex].Y,LayerBitmap[layerOverIndex],
2537 BlendOperation[layerOverIndex],LayerOpacity[layerOverIndex],LinearBlend);
2538 end;
2539 LayeredBitmap.RemoveLayer(layerOverIndex);
2540 LayeredBitmap.RemoveUnusedOriginals;
2541 end;
2542 end;
2543
2544 procedure TMergeLayerOverStateDifference.UnapplyTo(AState: TState);
2545 begin
2546 inherited UnapplyTo(AState);
2547 with AState as TImageState do
2548 begin
2549 layerOverCompressedBackup.Restore(LayeredBitmap);
2550 layerUnderCompressedBackup.Replace(LayeredBitmap);
2551
2552 //select previous layer
2553 SelectedImageLayerIndex := LayeredBitmap.GetLayerIndexFromId(Self.previousActiveLayerId);
2554 end;
2555 end;
2556
2557 destructor TMergeLayerOverStateDifference.Destroy;
2558 begin
2559 layerOverCompressedBackup.Free;
2560 layerUnderCompressedBackup.Free;
2561 inherited Destroy;
2562 end;
2563
2564 { TMoveLayerStateDifference }
2565
GetIsIdentitynull2566 function TMoveLayerStateDifference.GetIsIdentity: boolean;
2567 begin
2568 Result:= (sourceIndex = destIndex);
2569 end;
2570
TMoveLayerStateDifference.GetImageDifferenceKindnull2571 function TMoveLayerStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2572 begin
2573 Result:=idkChangeImage; //includes stack
2574 end;
2575
2576 procedure TMoveLayerStateDifference.ApplyTo(AState: TState);
2577 begin
2578 inherited ApplyTo(AState);
2579 with AState as TImageState do
2580 LayeredBitmap.InsertLayer(destIndex, sourceIndex);
2581 end;
2582
2583 procedure TMoveLayerStateDifference.UnapplyTo(AState: TState);
2584 begin
2585 inherited UnapplyTo(AState);
2586 with AState as TImageState do
2587 LayeredBitmap.InsertLayer(sourceIndex, destIndex);
2588 end;
2589
2590 constructor TMoveLayerStateDifference.Create(ADestination: TState;
2591 AFromIndex, AToIndex: integer);
2592 begin
2593 inherited Create(ADestination);
2594 self.sourceIndex := AFromIndex;
2595 self.destIndex := AToIndex;
2596 ApplyTo(ADestination);
2597 end;
2598
2599 { TDuplicateLayerStateDifference }
2600
GetImageDifferenceKindnull2601 function TDuplicateLayerStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2602 begin
2603 Result:=idkChangeImage;
2604 end;
2605
2606 procedure TDuplicateLayerStateDifference.ApplyTo(AState: TState);
2607 var sourceLayerIndex,duplicateIndex: integer;
2608 copy: integer;
2609 stream: TMemoryStream;
2610 begin
2611 inherited ApplyTo(AState);
2612 with AState as TImageState do
2613 begin
2614 sourceLayerIndex := LayeredBitmap.GetLayerIndexFromId(self.sourceLayerId);
2615 duplicateIndex := sourceLayerIndex+1;
2616 with LayeredBitmap do
2617 begin
2618 copy := AddLayer(LayerBitmap[sourceLayerIndex],BlendOperation[sourceLayerIndex],LayerOpacity[sourceLayerIndex]);
2619 LayerName[copy] := LayerName[sourceLayerIndex];
2620 LayerOffset[copy] := LayerOffset[sourceLayerIndex];
2621 LayerVisible[copy] := LayerVisible[sourceLayerIndex];
2622 if useOriginal then
2623 begin
2624 if duplicateOriginal then
2625 begin
2626 stream:= TMemoryStream.Create;
2627 SaveOriginalToStream(LayerOriginalGuid[sourceLayerIndex], stream);
2628 stream.Position:= 0;
2629 AddOriginalFromStream(stream, duplicateGuid, true);
2630 stream.Free;
2631 LayerOriginalGuid[copy] := duplicateGuid;
2632 end else
2633 LayerOriginalGuid[copy] := LayerOriginalGuid[sourceLayerIndex];
2634 LayerOriginalMatrix[copy] := LayerOriginalMatrix[sourceLayerIndex];
2635 LayerOriginalRenderStatus[copy] := LayerOriginalRenderStatus[sourceLayerIndex];
2636 end;
2637 LayerUniqueId[copy] := duplicateId;
2638 InsertLayer(duplicateIndex, copy);
2639 end;
2640 SelectedImageLayerIndex := duplicateIndex;
2641 end;
2642 end;
2643
2644 procedure TDuplicateLayerStateDifference.UnapplyTo(AState: TState);
2645 var sourceLayerIndex,duplicateIndex: integer;
2646 begin
2647 inherited UnapplyTo(AState);
2648 with AState as TImageState do
2649 begin
2650 sourceLayerIndex := LayeredBitmap.GetLayerIndexFromId(self.sourceLayerId);
2651 duplicateIndex := LayeredBitmap.GetLayerIndexFromId(self.duplicateId);
2652 LayeredBitmap.RemoveLayer(duplicateIndex);
2653 SelectedImageLayerIndex := sourceLayerIndex;
2654 if duplicateOriginal then LayeredBitmap.RemoveUnusedOriginals;
2655 end;
2656 end;
2657
2658 constructor TDuplicateLayerStateDifference.Create(ADestination: TState;
2659 AUseOriginal: boolean);
2660 var imgDest: TImageState;
2661 begin
2662 inherited Create(ADestination);
2663 imgDest := ADestination as TImageState;
2664 useOriginal:= AUseOriginal;
2665 with imgDest do
2666 begin
2667 self.sourceLayerId := LayeredBitmap.LayerUniqueId[SelectedImageLayerIndex];
2668 self.duplicateId := LayeredBitmap.ProduceLayerUniqueId;
2669 self.duplicateOriginal := useOriginal and
2670 ((LayeredBitmap.LayerOriginalClass[SelectedImageLayerIndex]=TVectorOriginal) or
2671 (LayeredBitmap.LayerOriginalClass[SelectedImageLayerIndex]=TBGRALayerGradientOriginal));
2672 if self.duplicateOriginal then
2673 CreateGUID(duplicateGuid);
2674 end;
2675 ApplyTo(imgDest);
2676 end;
2677
2678 { TAddLayerStateDifference }
2679
GetImageDifferenceKindnull2680 function TAddLayerStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2681 begin
2682 Result:= idkChangeImage;
2683 end;
2684
UsedMemorynull2685 function TAddLayerStateDifference.UsedMemory: int64;
2686 begin
2687 if Assigned(content) then
2688 result := content.UsedMemory
2689 else
2690 result := 0;
2691 end;
2692
TryCompressnull2693 function TAddLayerStateDifference.TryCompress: boolean;
2694 begin
2695 if Assigned(content) then
2696 Result := content.Compress
2697 else
2698 result := false;
2699 end;
2700
2701 procedure TAddLayerStateDifference.ApplyTo(AState: TState);
2702 var idx: integer;
2703 bmp: TBGRABitmap;
2704 begin
2705 inherited ApplyTo(AState);
2706 with AState as TImageState do
2707 begin
2708 bmp := content.GetBitmap;
2709 if bmp = nil then
2710 raise exception.Create('Bitmap not found');
2711 idx := LayeredBitmap.AddOwnedLayer(bmp, self.offset, self.blendOp, self.opacity);
2712 LayeredBitmap.LayerUniqueId[idx] := self.layerId;
2713 LayeredBitmap.LayerName[idx] := name;
2714 SelectedImageLayerIndex := idx;
2715 end;
2716 end;
2717
2718 procedure TAddLayerStateDifference.UnapplyTo(AState: TState);
2719 var idx: integer;
2720 begin
2721 inherited UnapplyTo(AState);
2722 with AState as TImageState do
2723 begin
2724 idx := LayeredBitmap.GetLayerIndexFromId(self.layerId);
2725 LayeredBitmap.RemoveLayer(idx);
2726 SelectedImageLayerIndex := LayeredBitmap.GetLayerIndexFromId(self.previousActiveLayerId);
2727 end;
2728 end;
2729
2730 constructor TAddLayerStateDifference.Create(ADestination: TState;
2731 AContent: TBGRABitmap; AName: ansistring; AOffset: TPoint;
2732 ABlendOp: TBlendOperation; AOpacity: byte);
2733 var idx: integer;
2734 imgDest: TImageState;
2735 begin
2736 inherited Create(ADestination);
2737 imgDest := ADestination as TImageState;
2738 if imgDest.LayeredBitmap = nil then
2739 raise exception.Create('Layered bitmap not created');
2740 self.content := TStoredImage.Create(AContent, False);
2741 self.name := AName;
2742 self.offset := AOffset;
2743 self.blendOp:= AblendOp;
2744 self.opacity:= AOpacity;
2745 self.previousActiveLayerId := imgDest.LayeredBitmap.LayerUniqueId[imgDest.SelectedImageLayerIndex];
2746 idx := imgDest.LayeredBitmap.AddLayer(AContent, AOffset, ABlendOp, AOpacity);
2747 imgDest.LayeredBitmap.LayerName[idx] := name;
2748 self.layerId := imgDest.LayeredBitmap.LayerUniqueId[idx];
2749 imgDest.SelectedImageLayerIndex := idx;
2750 end;
2751
2752 destructor TAddLayerStateDifference.Destroy;
2753 begin
2754 self.content.Free;
2755 inherited Destroy;
2756 end;
2757
2758 { TImageLayerStateDifference }
2759
TImageLayerStateDifference.GetChangeImageLayernull2760 function TImageLayerStateDifference.GetChangeImageLayer: boolean;
2761 begin
2762 result := (imageDiff <> nil) and not imageDiff.IsIdentity;
2763 end;
2764
GetChangeSelectionLayernull2765 function TImageLayerStateDifference.GetChangeSelectionLayer: boolean;
2766 begin
2767 result := (selectionLayerDiff <> nil) and not selectionLayerDiff.IsIdentity;
2768 end;
2769
GetChangeSelectionMasknull2770 function TImageLayerStateDifference.GetChangeSelectionMask: boolean;
2771 begin
2772 result := (selectionMaskDiff <> nil) and not selectionMaskDiff.IsIdentity;
2773 end;
2774
TImageLayerStateDifference.GetImageDifferenceKindnull2775 function TImageLayerStateDifference.GetImageDifferenceKind: TImageDifferenceKind;
2776 begin
2777 if ChangeImageLayer or ChangeSelectionLayer then
2778 begin
2779 if ChangeSelectionMask then
2780 result := idkChangeImageAndSelection
2781 else if ChangeSelectionLayer then
2782 result := idkChangeImage
2783 else
2784 result := idkChangeImage;
2785 end
2786 else if ChangeSelectionMask then
2787 result := idkChangeSelection
2788 else
2789 result := idkChangeStack; //some default value
2790 end;
2791
GetIsIdentitynull2792 function TImageLayerStateDifference.GetIsIdentity: boolean;
2793 begin
2794 Result:= not ChangeImageLayer and
2795 not ChangeSelectionMask and
2796 not ChangeSelectionLayer;
2797 end;
2798
GetChangingBoundsDefinednull2799 function TImageLayerStateDifference.GetChangingBoundsDefined: boolean;
2800 begin
2801 Result:= true;
2802 end;
2803
GetChangingBoundsnull2804 function TImageLayerStateDifference.GetChangingBounds: TRect;
2805 var
2806 r: TRect;
2807 begin
2808 result := EmptyRect;
2809 if ChangeImageLayer then
2810 begin
2811 r := imageDiff.ChangeRect;
2812 OffsetRect(r, layerRect.Left, layerRect.Top);
2813 result := RectUnion(result, r);
2814 end;
2815 if ChangeSelectionLayer then result := RectUnion(result, selectionLayerDiff.ChangeRect);
2816 if ChangeSelectionMask then result := RectUnion(result, selectionMaskDiff.ChangeRect);
2817 end;
2818
TImageLayerStateDifference.GetLayerRectnull2819 function TImageLayerStateDifference.GetLayerRect(AState: TImageState;
2820 AIndex: integer): TRect;
2821 begin
2822 result.TopLeft := AState.LayerOffset[AIndex];
2823 result.Width:= AState.LayerBitmap[AIndex].Width;
2824 result.Height:= AState.LayerBitmap[AIndex].Height;
2825 end;
2826
2827 procedure TImageLayerStateDifference.EnsureLayerRect(AState: TImageState;
2828 AIndex: integer);
2829 var
2830 curRect: TRect;
2831 newBmp: TBGRABitmap;
2832 begin
2833 curRect := GetLayerRect(AState, AIndex);
2834 if (layerRect.Left<>curRect.Left) or
2835 (layerRect.Top<>curRect.Top) or
2836 (layerRect.Width<>curRect.Width) or
2837 (layerRect.Height<>curRect.Height) then
2838 begin
2839 newBmp := TBGRABitmap.Create(layerRect.Width,layerRect.Height);
2840 newBmp.PutImage(curRect.Left-layerRect.Left,curRect.Top-layerRect.Top,
2841 AState.LayerBitmap[AIndex], dmSet);
2842 AState.SetLayerBitmap(AIndex, newBmp, true);
2843 AState.LayeredBitmap.LayerOffset[AIndex] := layerRect.TopLeft;
2844 end;
2845 end;
2846
2847 procedure TImageLayerStateDifference.Init(AToState: TState; APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
2848 APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
2849 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect);
2850 var
2851 next: TImageState;
2852 curIdx: integer;
2853 begin
2854 inherited Create((AToState as TImageState).saved,false);
2855 layerId := -1;
2856 imageDiff := nil;
2857 layerRect := EmptyRect;
2858 selectionMaskDiff := nil;
2859 selectionLayerDiff := nil;
2860
2861 next := AToState as TImageState;
2862 layerId := next.selectedLayerId;
2863 curIdx := next.LayeredBitmap.GetLayerIndexFromId(LayerId);
2864 if curIdx = -1 then
2865 raise exception.Create('Layer not found')
2866 else
2867 begin
2868 if not IsRectEmpty(APreviousImageChangeRect) then
2869 begin
2870 imageDiff := TImageDiff.Create(APreviousImage, next.LayerBitmap[curIdx],
2871 False, APreviousImageChangeRect);
2872 layerRect := GetLayerRect(next,curIdx);
2873 end;
2874 if not IsRectEmpty(APreviousSelectionChangeRect) then
2875 selectionMaskDiff := TImageDiff.Create(APreviousSelection, next.SelectionMask,
2876 True, APreviousSelectionChangeRect);
2877 if not IsRectEmpty(APreviousSelectionLayerChangeRect) then
2878 selectionLayerDiff := TImageDiff.Create(APreviousSelectionLayer, next.SelectionLayer,
2879 False, APreviousSelectionLayerChangeRect);
2880 end;
2881 end;
2882
TryCompressnull2883 function TImageLayerStateDifference.TryCompress: boolean;
2884 begin
2885 result := false;
2886 if Assigned(imageDiff) then result := result or imageDiff.Compress;
2887 if Assigned(selectionMaskDiff) then result := result or selectionMaskDiff.Compress;
2888 if Assigned(selectionLayerDiff) then result := result or selectionLayerDiff.Compress;
2889 end;
2890
2891 procedure TImageLayerStateDifference.ApplyTo(AState: TState);
2892 var
2893 idx: integer;
2894 lState: TImageState;
2895 newSelectionMask, newSelectionLayer: TBGRABitmap;
2896 begin
2897 inherited ApplyTo(AState);
2898 lState := AState as TImageState;
2899 if layerId <> -1 then
2900 begin
2901 idx := lState.LayeredBitmap.GetLayerIndexFromId(layerId);
2902 if idx = -1 then raise exception.Create('Layer not found');
2903 lState.LayeredBitmap.Unfreeze(idx);
2904 if ChangeImageLayer and (lState.LayeredBitmap.LayerOriginalGuid[idx] <> GUID_NULL) then raise exception.Create('Does not apply to originals');
2905 if ChangeImageLayer then
2906 begin
2907 EnsureLayerRect(lState,idx);
2908 lState.LayeredBitmap.SetLayerBitmap(idx,
2909 imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx], False, True), True);
2910 end;
2911 if ChangeSelectionMask then
2912 newSelectionMask := selectionMaskDiff.ApplyCanCreateNew(lState.SelectionMask, False, True)
2913 else newSelectionMask := lState.SelectionMask;
2914 if ChangeSelectionLayer then
2915 newSelectionLayer := selectionLayerDiff.ApplyCanCreateNew(lState.SelectionLayer, False, True)
2916 else newSelectionLayer := lState.SelectionLayer;
2917 lState.ReplaceSelection(newSelectionMask, newSelectionLayer);
2918 end;
2919 end;
2920
2921 procedure TImageLayerStateDifference.UnapplyTo(AState: TState);
2922 var
2923 idx: integer;
2924 lState: TImageState;
2925 newSelectionMask, newSelectionLayer: TBGRABitmap;
2926 begin
2927 inherited UnapplyTo(AState);
2928 lState := AState as TImageState;
2929 if layerId <> -1 then
2930 begin
2931 idx := lState.LayeredBitmap.GetLayerIndexFromId(layerId);
2932 if idx = -1 then raise exception.Create('Layer not found');
2933 lState.LayeredBitmap.Unfreeze(idx);
2934 if ChangeImageLayer and (lState.LayeredBitmap.LayerOriginalGuid[idx] <> GUID_NULL) then raise exception.Create('Does not apply to originals');
2935 if ChangeImageLayer then
2936 begin
2937 EnsureLayerRect(lState,idx);
2938 lState.LayeredBitmap.SetLayerBitmap(idx,
2939 imageDiff.ApplyCanCreateNew(lState.LayerBitmap[idx], True, True), True);
2940 end;
2941 if ChangeSelectionMask then
2942 newSelectionMask := selectionMaskDiff.ApplyCanCreateNew(lState.SelectionMask, True, True)
2943 else newSelectionMask := lState.SelectionMask;
2944 if ChangeSelectionLayer then
2945 newSelectionLayer := selectionLayerDiff.ApplyCanCreateNew(lState.SelectionLayer, True, True)
2946 else newSelectionLayer := lState.SelectionLayer;
2947 lState.ReplaceSelection(newSelectionMask, newSelectionLayer);
2948 end;
2949 end;
2950
UsedMemorynull2951 function TImageLayerStateDifference.UsedMemory: int64;
2952 begin
2953 Result:= 0;
2954 if Assigned(imageDiff) then result += imageDiff.UsedMemory;
2955 if Assigned(selectionMaskDiff) then result += selectionMaskDiff.UsedMemory;
2956 if Assigned(selectionLayerDiff) then result += selectionLayerDiff.UsedMemory;
2957 end;
2958
2959 constructor TImageLayerStateDifference.Create(AFromState, AToState: TState);
2960 var
2961 prev,next: TImageState;
2962 prevIdx,curIdx: integer;
2963 begin
2964 inherited Create(AFromState,AToState);
2965 layerId := -1;
2966 imageDiff := nil;
2967 layerRect := EmptyRect;
2968 selectionMaskDiff := nil;
2969 selectionLayerDiff := nil;
2970
2971 prev := AFromState as TImageState;
2972 next := AToState as TImageState;
2973 layerId := next.selectedLayerId;
2974 if layerId <> prev.selectedLayerId then
2975 raise exception.Create('Inconsistent layer id');
2976 prevIdx := prev.LayeredBitmap.GetLayerIndexFromId(LayerId);
2977 curIdx := next.LayeredBitmap.GetLayerIndexFromId(LayerId);
2978 if (curIdx = -1) or (prevIdx = -1) then
2979 raise exception.Create('Layer not found')
2980 else
2981 begin
2982 imageDiff := TImageDiff.Create(prev.LayerBitmap[prevIdx], next.LayerBitmap[curIdx], False);
2983 layerRect := GetLayerRect(next, curIdx);
2984 selectionMaskDiff := TImageDiff.Create(prev.SelectionMask, next.SelectionMask, True);
2985 selectionLayerDiff := TImageDiff.Create(prev.SelectionLayer, next.SelectionLayer, False);
2986 end;
2987 end;
2988
2989 constructor TImageLayerStateDifference.Create(AToState: TState;
2990 APreviousImage: TBGRABitmap; APreviousImageDefined: boolean;
2991 APreviousSelection: TBGRABitmap; APreviousSelectionDefined: boolean;
2992 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerDefined: boolean);
2993 var
2994 r1,r2,r3: TRect;
2995 w,h: integer;
2996 begin
2997 w := (AToState as TImageState).Width;
2998 h := (AToState as TImageState).Height;
2999 if APreviousImageDefined then r1 := rect(0,0,w,h) else r1 := EmptyRect;
3000 if APreviousSelectionDefined then r2 := rect(0,0,w,h) else r2 := EmptyRect;
3001 if APreviousSelectionLayerDefined then r3 := rect(0,0,w,h) else r3 := EmptyRect;
3002 Init(AToState,APreviousImage,r1,APreviousSelection,r2,APreviousSelectionLayer,r3);
3003 end;
3004
3005 constructor TImageLayerStateDifference.Create(AToState: TState;
3006 APreviousImage: TBGRABitmap; APreviousImageChangeRect: TRect;
3007 APreviousSelection: TBGRABitmap; APreviousSelectionChangeRect: TRect;
3008 APreviousSelectionLayer: TBGRABitmap; APreviousSelectionLayerChangeRect: TRect);
3009 begin
3010 Init(AToState, APreviousImage, APreviousImageChangeRect, APreviousSelection,
3011 APreviousSelectionChangeRect, APreviousSelectionLayer, APreviousSelectionLayerChangeRect);
3012 end;
3013
TImageLayerStateDifference.ToStringnull3014 function TImageLayerStateDifference.ToString: ansistring;
3015 begin
3016 Result:= ClassName+'(';
3017 If ChangeImageLayer then
3018 begin
3019 if (imageDiff.SizeBefore.cx = 0) or (imageDiff.SizeBefore.cy = 0) then
3020 result += 'Create'
3021 else
3022 if (imageDiff.SizeAfter.cx = 0) or (imageDiff.SizeAfter.cy = 0) then
3023 result += 'Remove'
3024 else
3025 result += 'Change';
3026
3027 result += 'ImageLayer ';
3028 end;
3029 If ChangeSelectionMask then
3030 begin
3031 if (selectionMaskDiff.SizeBefore.cx = 0) or (selectionMaskDiff.SizeBefore.cy = 0) then
3032 result += 'Create'
3033 else
3034 if (selectionMaskDiff.SizeAfter.cx = 0) or (selectionMaskDiff.SizeAfter.cy = 0) then
3035 result += 'Remove'
3036 else
3037 result += 'Change';
3038
3039 result += 'SelectionMask ';
3040 end;
3041 If ChangeSelectionLayer then
3042 begin
3043 if (selectionLayerDiff.SizeBefore.cx = 0) or (selectionLayerDiff.SizeBefore.cy = 0) then
3044 result += 'Create'
3045 else
3046 if (selectionLayerDiff.SizeAfter.cx = 0) or (selectionLayerDiff.SizeAfter.cy = 0) then
3047 result += 'Remove'
3048 else
3049 result += 'Change';
3050
3051 result += 'SelectionLayer ';
3052 end;
3053 result := trim(Result)+')';
3054 end;
3055
3056 destructor TImageLayerStateDifference.Destroy;
3057 begin
3058 imageDiff.Free;
3059 selectionMaskDiff.Free;
3060 selectionLayerDiff.Free;
3061 inherited Destroy;
3062 end;
3063
3064 end.
3065
3066