| 1 | unit BGRASVGOriginal;
|
|---|
| 2 |
|
|---|
| 3 | {$mode objfpc}{$H+}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | uses
|
|---|
| 8 | Classes, SysUtils, BGRABitmapTypes, BGRABitmap, BGRASVG, BGRATransform, BGRALayerOriginal;
|
|---|
| 9 |
|
|---|
| 10 | type
|
|---|
| 11 | { TBGRALayerSVGOriginal }
|
|---|
| 12 |
|
|---|
| 13 | TBGRALayerSVGOriginal = class(TBGRALayerCustomOriginal)
|
|---|
| 14 | private
|
|---|
| 15 | function GetDPI: single;
|
|---|
| 16 | function GetSvgHeight: single;
|
|---|
| 17 | function GetSvgWidth: single;
|
|---|
| 18 | procedure SetDPI(AValue: single);
|
|---|
| 19 | protected
|
|---|
| 20 | FSVG: TBGRASVG;
|
|---|
| 21 | FContentVersion: integer;
|
|---|
| 22 | procedure ContentChanged;
|
|---|
| 23 | public
|
|---|
| 24 | constructor Create; override;
|
|---|
| 25 | destructor Destroy; override;
|
|---|
| 26 | procedure Render(ADest: TBGRABitmap; AMatrix: TAffineMatrix; ADraft: boolean); override;
|
|---|
| 27 | function GetRenderBounds({%H-}ADestRect: TRect; AMatrix: TAffineMatrix): TRect; override;
|
|---|
| 28 | procedure LoadFromStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|---|
| 29 | procedure SaveToStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|---|
| 30 | procedure LoadFromStream(AStream: TStream); override;
|
|---|
| 31 | procedure SaveSVGToStream(AStream: TStream);
|
|---|
| 32 | procedure LoadSVGFromStream(AStream: TStream);
|
|---|
| 33 | class function StorageClassName: RawByteString; override;
|
|---|
| 34 | property Width: single read GetSvgWidth;
|
|---|
| 35 | property Height: single read GetSvgHeight;
|
|---|
| 36 | property DPI: single read GetDPI write SetDPI;
|
|---|
| 37 | end;
|
|---|
| 38 |
|
|---|
| 39 | implementation
|
|---|
| 40 |
|
|---|
| 41 | uses BGRACanvas2D, BGRAMemDirectory;
|
|---|
| 42 |
|
|---|
| 43 | { TBGRALayerSVGOriginal }
|
|---|
| 44 |
|
|---|
| 45 | function TBGRALayerSVGOriginal.GetDPI: single;
|
|---|
| 46 | begin
|
|---|
| 47 | result := FSVG.DefaultDpi;
|
|---|
| 48 | end;
|
|---|
| 49 |
|
|---|
| 50 | function TBGRALayerSVGOriginal.GetSvgHeight: single;
|
|---|
| 51 | begin
|
|---|
| 52 | result := FSVG.ViewSizeInUnit[cuPixel].y;
|
|---|
| 53 | end;
|
|---|
| 54 |
|
|---|
| 55 | function TBGRALayerSVGOriginal.GetSvgWidth: single;
|
|---|
| 56 | begin
|
|---|
| 57 | result := FSVG.ViewSizeInUnit[cuPixel].x;
|
|---|
| 58 | end;
|
|---|
| 59 |
|
|---|
| 60 | procedure TBGRALayerSVGOriginal.SetDPI(AValue: single);
|
|---|
| 61 | begin
|
|---|
| 62 | FSVG.DefaultDpi:= AValue;
|
|---|
| 63 | NotifyChange;
|
|---|
| 64 | end;
|
|---|
| 65 |
|
|---|
| 66 | procedure TBGRALayerSVGOriginal.ContentChanged;
|
|---|
| 67 | begin
|
|---|
| 68 | FContentVersion += 1;
|
|---|
| 69 | NotifyChange;
|
|---|
| 70 | end;
|
|---|
| 71 |
|
|---|
| 72 | constructor TBGRALayerSVGOriginal.Create;
|
|---|
| 73 | begin
|
|---|
| 74 | inherited Create;
|
|---|
| 75 | FSVG := TBGRASVG.Create;
|
|---|
| 76 | FContentVersion := 0;
|
|---|
| 77 | end;
|
|---|
| 78 |
|
|---|
| 79 | destructor TBGRALayerSVGOriginal.Destroy;
|
|---|
| 80 | begin
|
|---|
| 81 | FSVG.Free;
|
|---|
| 82 | inherited Destroy;
|
|---|
| 83 | end;
|
|---|
| 84 |
|
|---|
| 85 | procedure TBGRALayerSVGOriginal.Render(ADest: TBGRABitmap;
|
|---|
| 86 | AMatrix: TAffineMatrix; ADraft: boolean);
|
|---|
| 87 | var
|
|---|
| 88 | c2D: TBGRACanvas2D;
|
|---|
| 89 | begin
|
|---|
| 90 | if Assigned(FSVG) then
|
|---|
| 91 | begin
|
|---|
| 92 | c2D := TBGRACanvas2D.Create(ADest);
|
|---|
| 93 | c2D.transform(AMatrix);
|
|---|
| 94 | if ADraft then c2D.antialiasing := false;
|
|---|
| 95 | FSVG.Draw(c2D,0,0);
|
|---|
| 96 | c2D.Free;
|
|---|
| 97 | end;
|
|---|
| 98 | end;
|
|---|
| 99 |
|
|---|
| 100 | function TBGRALayerSVGOriginal.GetRenderBounds(ADestRect: TRect;
|
|---|
| 101 | AMatrix: TAffineMatrix): TRect;
|
|---|
| 102 | var
|
|---|
| 103 | aff: TAffineBox;
|
|---|
| 104 | min, size: TPointF;
|
|---|
| 105 | begin
|
|---|
| 106 | if Assigned(FSVG) then
|
|---|
| 107 | begin
|
|---|
| 108 | min := FSVG.ViewMinInUnit[cuPixel];
|
|---|
| 109 | size := FSVG.ViewSizeInUnit[cuPixel];
|
|---|
| 110 | aff := AMatrix*TAffineBox.AffineBox(min,PointF(min.x+size.x,min.y),PointF(min.x,min.y+size.y));
|
|---|
| 111 | result := aff.RectBounds;
|
|---|
| 112 | end else
|
|---|
| 113 | result := EmptyRect;
|
|---|
| 114 | end;
|
|---|
| 115 |
|
|---|
| 116 | procedure TBGRALayerSVGOriginal.LoadFromStorage(
|
|---|
| 117 | AStorage: TBGRACustomOriginalStorage);
|
|---|
| 118 | var svgStream: TMemoryStream;
|
|---|
| 119 | valDpi: Single;
|
|---|
| 120 | begin
|
|---|
| 121 | svgStream := TMemoryStream.Create;
|
|---|
| 122 | try
|
|---|
| 123 | if AStorage.ReadFile('content.svg', svgStream) then
|
|---|
| 124 | begin
|
|---|
| 125 | if not Assigned(FSVG) then FSVG := TBGRASVG.Create;
|
|---|
| 126 | svgStream.Position:= 0;
|
|---|
| 127 | FSVG.LoadFromStream(svgStream);
|
|---|
| 128 | end else
|
|---|
| 129 | begin
|
|---|
| 130 | FreeAndNil(FSVG);
|
|---|
| 131 | FSVG := TBGRASVG.Create;
|
|---|
| 132 | end;
|
|---|
| 133 | FContentVersion:= AStorage.Int['content-version'];
|
|---|
| 134 | finally
|
|---|
| 135 | svgStream.Free;
|
|---|
| 136 | end;
|
|---|
| 137 | valDpi := AStorage.Float['dpi'];
|
|---|
| 138 | if valDpi <> EmptySingle then
|
|---|
| 139 | FSVG.DefaultDpi:= valDpi;
|
|---|
| 140 | end;
|
|---|
| 141 |
|
|---|
| 142 | procedure TBGRALayerSVGOriginal.SaveToStorage(
|
|---|
| 143 | AStorage: TBGRACustomOriginalStorage);
|
|---|
| 144 | var svgStream: TMemoryStream;
|
|---|
| 145 | begin
|
|---|
| 146 | if Assigned(FSVG) then
|
|---|
| 147 | begin
|
|---|
| 148 | if FContentVersion > AStorage.Int['content-version'] then
|
|---|
| 149 | begin
|
|---|
| 150 | svgStream := TMemoryStream.Create;
|
|---|
| 151 | try
|
|---|
| 152 | FSVG.SaveToStream(svgStream);
|
|---|
| 153 | AStorage.WriteFile('content.svg', svgStream, true);
|
|---|
| 154 | svgStream := nil;
|
|---|
| 155 | AStorage.Int['content-version'] := FContentVersion;
|
|---|
| 156 | finally
|
|---|
| 157 | svgStream.Free;
|
|---|
| 158 | end;
|
|---|
| 159 | end;
|
|---|
| 160 | AStorage.Float['dpi'] := FSVG.DefaultDpi;
|
|---|
| 161 | end;
|
|---|
| 162 | end;
|
|---|
| 163 |
|
|---|
| 164 | procedure TBGRALayerSVGOriginal.LoadFromStream(AStream: TStream);
|
|---|
| 165 | begin
|
|---|
| 166 | if TMemDirectory.CheckHeader(AStream) then
|
|---|
| 167 | inherited LoadFromStream(AStream)
|
|---|
| 168 | else
|
|---|
| 169 | LoadSVGFromStream(AStream);
|
|---|
| 170 | end;
|
|---|
| 171 |
|
|---|
| 172 | procedure TBGRALayerSVGOriginal.SaveSVGToStream(AStream: TStream);
|
|---|
| 173 | begin
|
|---|
| 174 | FSVG.SaveToStream(AStream);
|
|---|
| 175 | end;
|
|---|
| 176 |
|
|---|
| 177 | procedure TBGRALayerSVGOriginal.LoadSVGFromStream(AStream: TStream);
|
|---|
| 178 | begin
|
|---|
| 179 | FSVG.LoadFromStream(AStream);
|
|---|
| 180 | ContentChanged;
|
|---|
| 181 | end;
|
|---|
| 182 |
|
|---|
| 183 | class function TBGRALayerSVGOriginal.StorageClassName: RawByteString;
|
|---|
| 184 | begin
|
|---|
| 185 | result := 'svg';
|
|---|
| 186 | end;
|
|---|
| 187 |
|
|---|
| 188 | initialization
|
|---|
| 189 |
|
|---|
| 190 | RegisterLayerOriginal(TBGRALayerSVGOriginal);
|
|---|
| 191 |
|
|---|
| 192 | end.
|
|---|
| 193 |
|
|---|