123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- unit LCVectorClipboard;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, Clipbrd, LCLType, LCVectorOriginal, BGRATransform, BGRABitmapTypes;
- function CopyShapesToClipboard(AShapes: array of TVectorShape; const AMatrix: TAffineMatrix): boolean;
- procedure PasteShapesFromClipboard(ATargetContainer: TVectorOriginal; const ATargetMatrix: TAffineMatrix; const ABounds: TRectF);
- function ClipboardHasShapes: boolean;
- implementation
- uses math;
- var
- vectorClipboardFormat : TClipboardFormat;
- function CopyShapesToClipboard(AShapes: array of TVectorShape; const AMatrix: TAffineMatrix): boolean;
- var
- tempContainer: TVectorOriginal;
- mem: TMemoryStream;
- i, j: Integer;
- s: TVectorShape;
- multiSel: IVectorMultishape;
- begin
- result:= false;
- if length(AShapes)=0 then exit;
- tempContainer := TVectorOriginal.Create;
- mem := TMemoryStream.Create;
- try
- for i := 0 to high(AShapes) do
- begin
- if AShapes[i] is VectorMultiselectionFactory then
- begin
- multiSel := AShapes[i].GetAsMultishape;
- for j := 0 to multiSel.ShapeCount-1 do
- begin
- s := multiSel.GetShape(j).Duplicate;
- s.Transform(AMatrix);
- tempContainer.AddShape(s);
- end;
- end else
- begin
- s := AShapes[i].Duplicate;
- s.Transform(AMatrix);
- tempContainer.AddShape(s);
- end;
- end;
- tempContainer.SaveToStream(mem);
- Clipboard.Clear;
- mem.Position:= 0;
- result := Clipboard.AddFormat(vectorClipboardFormat, mem);
- finally
- mem.Free;
- tempContainer.Free;
- end;
- end;
- procedure PasteShapesFromClipboard(ATargetContainer: TVectorOriginal; const ATargetMatrix: TAffineMatrix; const ABounds: TRectF);
- var
- tempContainer: TVectorOriginal;
- mem: TMemoryStream;
- i: Integer;
- pastedShape: TVectorShape;
- pastedShapes: TVectorShapes;
- invMatrix, m: TAffineMatrix;
- pastedBounds: TRectF;
- ofs: TPointF;
- begin
- if not IsAffineMatrixInversible(ATargetMatrix) then exit;
- invMatrix := AffineMatrixInverse(ATargetMatrix);
- if Clipboard.HasFormat(vectorClipboardFormat) then
- begin
- mem := TMemoryStream.Create;
- tempContainer := TVectorOriginal.Create;
- try
- if Clipboard.GetFormat(vectorClipboardFormat, mem) then
- begin
- mem.Position:= 0;
- tempContainer.LoadFromStream(mem);
- pastedBounds := EmptyRectF;
- ofs := PointF(0, 0);
- if not ABounds.IsEmpty then
- begin
- for i := 0 to tempContainer.ShapeCount-1 do
- pastedBounds := pastedBounds.Union(pastedBounds,
- tempContainer.Shape[i].GetAlignBounds(InfiniteRect, AffineMatrixIdentity), true);
- if (pastedBounds.Left < ABounds.Left) and (pastedBounds.Right < ABounds.Right) then
- ofs.x := ceil(ABounds.Left - pastedBounds.Left) else
- if (pastedBounds.Right > ABounds.Right) and (pastedBounds.Left > ABounds.Left) then
- ofs.x := floor(ABounds.Right - pastedBounds.Right);
- if (pastedBounds.Top < ABounds.Top) and (pastedBounds.Bottom < ABounds.Bottom) then
- ofs.y := ceil(ABounds.Top - pastedBounds.Top) else
- if (pastedBounds.Bottom > ABounds.Bottom) and (pastedBounds.Top > ABounds.Top) then
- ofs.y := floor(ABounds.Bottom - pastedBounds.Bottom);
- end;
- m := invMatrix*AffineMatrixTranslation(ofs.x,ofs.y);
- ATargetContainer.DeselectShapes;
- pastedShapes := TVectorShapes.Create;
- for i := 0 to tempContainer.ShapeCount-1 do
- begin
- pastedShape := tempContainer.Shape[i].Duplicate;
- pastedShape.Transform(m);
- pastedShapes.Add(pastedShape);
- end;
- ATargetContainer.AddShapes(pastedShapes);
- ATargetContainer.SelectShapes(pastedShapes);
- pastedShapes.Free;
- end;
- finally
- tempContainer.Free;
- mem.Free;
- end;
- end;
- end;
- function ClipboardHasShapes: boolean;
- begin
- result := Clipboard.HasFormat(vectorClipboardFormat);
- end;
- initialization
- vectorClipboardFormat := RegisterClipboardFormat('TVectorOriginal');
- end.
|