unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, FileCtrl, Menus, ComCtrls, Types, BGRABitmapTypes, BGRABitmap, BGRASVG, BGRASVGType, BGRASVGShapes, BGRAUnits, UProfiler; type { TForm1 } TForm1 = class(TForm) CheckBox_ReplaceStrokeAndFill: TCheckBox; FileListBox1: TFileListBox; Image1: TImage; Image2: TImage; MainMenu1: TMainMenu; MCopy1: TMenuItem; MCut1: TMenuItem; Memo1: TMemo; MenuItem1: TMenuItem; MenuItem2: TMenuItem; MenuItem3: TMenuItem; MenuItem4: TMenuItem; MenuItem5: TMenuItem; MenuItem6: TMenuItem; MenuItem7: TMenuItem; MenuItem8: TMenuItem; MenuItem9: TMenuItem; N1: TMenuItem; MPaste1: TMenuItem; MSelectAll: TMenuItem; PageControl1: TPageControl; Panel1: TPanel; Panel2: TPanel; Panel3: TPanel; PanProf: TPanel; PopupMenu1: TPopupMenu; PopupMenu2: TPopupMenu; SaveDialog1: TSaveDialog; Splitter2: TSplitter; Splitter3: TSplitter; Splitter4: TSplitter; TabSheet1: TTabSheet; procedure CheckBox_ReplaceStrokeAndFillChange(Sender: TObject); procedure FileListBox1Change(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MCopy1Click(Sender: TObject); procedure MCut1Click(Sender: TObject); procedure Memo1DblClick(Sender: TObject); procedure Memo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MenuItem1Click(Sender: TObject); procedure MenuItem2Click(Sender: TObject); procedure MenuItem4Click(Sender: TObject); procedure MenuItem8Click(Sender: TObject); procedure MenuItem9Click(Sender: TObject); procedure MPaste1Click(Sender: TObject); procedure MSelectAllClick(Sender: TObject); procedure PopupMenu1Popup(Sender: TObject); private svg: TBGRASVG; last_image: TImage; prof: TProfiler; procedure ChangeFill(AElement: TSVGElement; AData: pointer; var ARecursive: boolean); procedure ReloadFile; procedure Test(var ms: TMemoryStream; kzoom: Single = 1; AFillCode: boolean = false); procedure Test(path: String; kzoom: Single = 1; AFillCode: boolean = false); public end; var Form1: TForm1; implementation uses Clipbrd, BGRAVectorize; {$R *.lfm} const s_file_overwrite = 'Existing file: do you want to overwrite it?'; procedure TForm1.Test(var ms: TMemoryStream; kzoom: Single = 1; AFillCode: boolean = false); Var v: Double; s: String; bmp: TBGRABitmap; begin bmp:= TBGRABitmap.Create; try if Assigned(svg) then svg.Free; prof.BeginMeasure; svg:= TBGRASVG.Create(ms); v:= prof.EndMeasure; s:= prof.FormatTime('create: ',v); prof.BeginMeasure; svg.ContainerWidthAsPixel := 480; svg.ContainerHeightAsPixel := 360; bmp.FontRenderer := TBGRAVectorizedFontRenderer.Create; bmp.SetSize(Round(svg.WidthAsPixel*kzoom),Round(svg.HeightAsPixel*kzoom)); bmp.Fill(BGRAWhite); v:= prof.EndMeasure; s:= s + prof.FormatTime(' | bmp: ',v); prof.BeginMeasure; if CheckBox_ReplaceStrokeAndFill.Checked then svg.IterateElements(@ChangeFill, nil, true); svg.StretchDraw(bmp.Canvas2D, 0,0,bmp.Width,bmp.Height); v:= prof.EndMeasure; s:= s + prof.FormatTime(' | draw: ',v); Image1.Picture.Bitmap.Assign(bmp); PanProf.Caption:= s; if AFillCode then Memo1.Text:= svg.AsUTF8String; finally bmp.Free; end; end; procedure TForm1.ChangeFill(AElement: TSVGElement; AData: pointer; var ARecursive: boolean); begin if AElement is TSVGDefine then ARecursive:= false else begin if not AElement.isFillNone then AElement.fillColor := CSSSkyBlue; if not AElement.isStrokeNone then AElement.strokeColor := CSSOrange; end; end; procedure TForm1.ReloadFile; Var png_find: Boolean; path: String; begin if FileListBox1.ItemIndex <> -1 then begin path:= FileListBox1.FileName; Test(path, Screen.PixelsPerInch / 96 * GetCanvasScaleFactor, true); //(view correct result) path:= ChangeFileExt(path,'.png'); png_find:= False; if FileExists(path) then try with Image2.Picture do begin LoadFromFile(path); Image2.Hint:= '(anteprime: png '+ IntToStr(Width)+'x'+IntToStr(Height)+')'; end; png_find:= True; except end; if not png_find then begin Image2.Hint:= ''; Image2.Picture:= nil; end; end; end; procedure TForm1.Test(path: String; kzoom: Single = 1; AFillCode: boolean = false); Var ms: TMemoryStream; begin ms:= TMemoryStream.Create; try ms.LoadFromFile(path); ms.Position:= 0; path:= ExtractFileName(path); Test(ms, kzoom, AFillCode); finally ms.Free; end; end; procedure TForm1.FormCreate(Sender: TObject); var baseDir: string; begin svg:= nil; last_image:= nil; prof:= TProfiler.Create; with FileListBox1 do begin baseDir := ExtractFilePath(Application.ExeName); {$IFDEF DARWIN} if not FileExists(baseDir+'testsvg') then baseDir += '../../../'; {$ENDIF} Directory := baseDir+'svg'+PathDelim; Mask:= '*.svg'; end; PanProf.DoubleBuffered:= True; end; procedure TForm1.FormShow(Sender: TObject); begin if FileListBox1.Count <> 0 then begin FileListBox1.ItemIndex:= 0; FileListBox1.Click; end; PageControl1.ActivePageIndex:= 0; end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin svg.Free; prof.Free; end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Sender is TImage then begin last_image:= Sender as TImage; if (Button = mbRight) and (last_image.Picture <> nil) then PopupMenu2.PopUp(Mouse.CursorPos.x,Mouse.CursorPos.y); end; end; procedure TForm1.MCut1Click(Sender: TObject); begin if Memo1.SelLength <> 0 then Memo1.CutToClipboard; end; procedure TForm1.MCopy1Click(Sender: TObject); begin if Memo1.SelLength <> 0 then Memo1.CopyToClipboard; end; procedure TForm1.MPaste1Click(Sender: TObject); begin Memo1.PasteFromClipboard; end; procedure TForm1.MSelectAllClick(Sender: TObject); begin Memo1.SelectAll; end; procedure TForm1.PopupMenu1Popup(Sender: TObject); Var b: Boolean; begin b:= Memo1.SelLength <> 0; MCut1.Enabled:= b; MCopy1.Enabled:= b; MPaste1.Enabled:= Clipboard.HasFormat(CF_Text); MSelectAll.Enabled:= Length(Memo1.Lines.Text) <> 0; end; procedure TForm1.Memo1DblClick(Sender: TObject); begin Memo1.ReadOnly:= not Memo1.ReadOnly; end; procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (Button = mbRight) and (not Memo1.ReadOnly) then PopupMenu1.PopUp(Mouse.CursorPos.x,Mouse.CursorPos.y); end; procedure TForm1.MenuItem1Click(Sender: TObject); Var s: String; scale: single; ms: TMemoryStream; begin if (Sender is TMenuItem) then scale:= (Sender as TMenuItem).Tag / 100 else scale:= 1; ms:= TMemoryStream.Create; try s:= Memo1.Text; ms.WriteBuffer(s[1],Length(s)); ms.Position:= 0; Test(ms,scale); finally ms.Free; end; end; procedure TForm1.MenuItem2Click(Sender: TObject); Var path: String; begin SaveDialog1.Filter:= 'png|*.png'; if SaveDialog1.Execute then try path:= SaveDialog1.FileName; if FileExists(path) then if MessageDlg('', s_file_overwrite, mtConfirmation, [mbYes, mbNo, mbIgnore],0) <> mrYes then Exit; last_image.Picture.SaveToFile(path); except end; end; procedure TForm1.MenuItem4Click(Sender: TObject); Var path: String; begin SaveDialog1.Filter:= 'svg|*.svg'; if SaveDialog1.Execute then try path:= SaveDialog1.FileName; if FileExists(path) then if MessageDlg('', s_file_overwrite, mtConfirmation, [mbYes, mbNo, mbIgnore],0) <> mrYes then Exit; Memo1.Lines.SaveToFile(path); except end; end; procedure TForm1.MenuItem8Click(Sender: TObject); begin MenuItem1.Click; end; procedure TForm1.MenuItem9Click(Sender: TObject); begin Close; end; procedure TForm1.FileListBox1Change(Sender: TObject); begin ReloadFile; end; procedure TForm1.CheckBox_ReplaceStrokeAndFillChange(Sender: TObject); begin ReloadFile; end; end.