mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 14:49:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1234 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			1234 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{ Current issues:
 | 
						|
  - Radial gradient not rendered correctly (position, colors), saving to svg ok.
 | 
						|
  - Save polygon to svg empty
 | 
						|
  - Nonzero/even-odd winding rule not working
 | 
						|
}
 | 
						|
 | 
						|
unit vtmain;
 | 
						|
 | 
						|
{$mode objfpc}{$H+}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
uses
 | 
						|
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
 | 
						|
  ExtCtrls, ComCtrls, EditBtn, fpimage, fpvectorial, Types;
 | 
						|
 | 
						|
type
 | 
						|
 | 
						|
  TRenderEvent = procedure(APage: TvVectorialPage;
 | 
						|
    AIntParam: Integer = MaxInt) of object;
 | 
						|
 | 
						|
  TRenderParams = class
 | 
						|
    RefFile: String;
 | 
						|
    IntParam: Integer;
 | 
						|
    OnRender: TRenderEvent;
 | 
						|
    constructor Create(ARenderEvent: TRenderEvent; ARefFilename: String;
 | 
						|
      AIntParam: Integer = MaxInt);
 | 
						|
  end;
 | 
						|
 | 
						|
  TRenderCoords  = (rcBottomLeftCoords, rcTopLeftCoords);
 | 
						|
 | 
						|
  { TMainForm }
 | 
						|
 | 
						|
  TMainForm = class(TForm)
 | 
						|
    BtnSaveAsRef: TButton;
 | 
						|
    BtnSaveToFiles: TButton;
 | 
						|
    BtnViewBottomLeft: TButton;
 | 
						|
    BtnViewTopLeft: TButton;
 | 
						|
    CbFileFormat: TComboBox;
 | 
						|
    gbWRBottomLeft: TGroupBox;
 | 
						|
    gbRenderTest: TGroupBox;
 | 
						|
    gbBottomLeft: TGroupBox;
 | 
						|
    gbWRTopLeft: TGroupBox;
 | 
						|
    gbTopLeft: TGroupBox;
 | 
						|
    gbReferenceImageTest: TGroupBox;
 | 
						|
    GroupBox1: TGroupBox;
 | 
						|
    gbReadWriteTest: TGroupBox;
 | 
						|
    GbTree: TGroupBox;
 | 
						|
    Label1: TLabel;
 | 
						|
    Label14: TLabel;
 | 
						|
    LblBothImagesMustMatch1: TLabel;
 | 
						|
    RefImage: TImage;
 | 
						|
    Label10: TLabel;
 | 
						|
    Label11: TLabel;
 | 
						|
    Label13: TLabel;
 | 
						|
    Label6: TLabel;
 | 
						|
    Label7: TLabel;
 | 
						|
    Label8: TLabel;
 | 
						|
    LblBothImagesMustMatch: TLabel;
 | 
						|
    LblRefImgMustMatch: TLabel;
 | 
						|
    LblReadWriteInstructions: TLabel;
 | 
						|
    BottomLeftPaintbox: TPaintBox;
 | 
						|
    ScrollBox1: TScrollBox;
 | 
						|
    WRTopLeftPaintbox: TPaintBox;
 | 
						|
    TopLeftPaintbox: TPaintBox;
 | 
						|
    WRBottomLeftPaintbox: TPaintBox;
 | 
						|
    AllTestsPanel: TPanel;
 | 
						|
    Tree: TTreeView;
 | 
						|
    procedure BtnSaveToFilesClick(Sender: TObject);
 | 
						|
    procedure BtnSaveAsRefClick(Sender: TObject);
 | 
						|
    procedure BtnViewImageClick(Sender: TObject);
 | 
						|
    procedure CbFileFormatChange(Sender: TObject);
 | 
						|
    procedure FormCreate(Sender: TObject);
 | 
						|
    procedure FormDestroy(Sender: TObject);
 | 
						|
    procedure PaintBoxPaint(Sender: TObject);
 | 
						|
    procedure TreeCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
 | 
						|
      State: TCustomDrawState; var DefaultDraw: Boolean);
 | 
						|
    procedure TreeSelectionChanged(Sender: TObject);
 | 
						|
 | 
						|
  private
 | 
						|
    { private declarations }
 | 
						|
    FDoc: array[TRenderCoords] of TvVectorialDocument;
 | 
						|
    FDocFromWMF: array[TRenderCoords] of TvVectorialDocument;
 | 
						|
    FDocFromSVG: array[TRenderCoords] of TvVectorialDocument;
 | 
						|
    function GetFileFormat: TvVectorialFormat;
 | 
						|
    function GetFileFormatExt: String;
 | 
						|
    procedure Populate;
 | 
						|
    procedure PrepareDoc(var ADoc: TvVectorialDocument; var APage: TvVectorialPage;
 | 
						|
      AUseTopLeftCoords: boolean);
 | 
						|
    procedure ReadIni;
 | 
						|
    procedure ShowFileImage(AFilename: String; AUseTopLeftCoords: Boolean;
 | 
						|
      APaintbox: TPaintbox);
 | 
						|
    procedure ShowRefImageTest;
 | 
						|
    procedure ShowRenderTestImages;
 | 
						|
    procedure ShowWriteReadTestImages;
 | 
						|
    procedure UpdateCmdStates;
 | 
						|
    procedure WriteIni;
 | 
						|
 | 
						|
    // Simple shapes, solid fills and gradients
 | 
						|
    procedure Render_Shape(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
 | 
						|
    // Complex shapes
 | 
						|
    procedure Render_Path_Hole_SolidFill(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
    procedure Render_Path_Hole_GradientFill(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
    procedure Render_SelfIntersectingPoly_SolidFill_EvenOdd(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
    procedure Render_SelfIntersectingPoly_GradientFill_EvenOdd(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
    procedure Render_SelfIntersectingPoly_SolidFill_NonZeroWinding(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
    procedure Render_SelfIntersectingPoly_GradientFill_NonZeroWinding(APage: TvVectorialPage;
 | 
						|
      AIntParam: Integer);
 | 
						|
 | 
						|
    // Arcs
 | 
						|
    procedure Render_Arc(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
 | 
						|
    // Bezier
 | 
						|
    procedure Render_Bezier(Apage: TvVectorialPage; AIntParam: Integer);
 | 
						|
 | 
						|
    // Text
 | 
						|
    procedure Render_Text(APage: TvVectorialpage; AIntParam: Integer);
 | 
						|
    procedure Render_Text_Fonts(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
    procedure Render_Text_Colors(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
  public
 | 
						|
    { public declarations }
 | 
						|
  end;
 | 
						|
 | 
						|
var
 | 
						|
  MainForm: TMainForm;
 | 
						|
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
{$R *.lfm}
 | 
						|
 | 
						|
uses
 | 
						|
  Math, FPCanvas, IniFiles, LazFileUtils, LCLIntf,
 | 
						|
  fpvutils, vtprimitives;
 | 
						|
 | 
						|
const
 | 
						|
  IMG_FOLDER = 'images' + PathDelim;
 | 
						|
  NOT_SAVED = '(not saved)';
 | 
						|
 | 
						|
 | 
						|
{ TRenderParams }
 | 
						|
 | 
						|
constructor TRenderParams.Create(ARenderEvent: TRenderEvent;
 | 
						|
  ARefFilename: String; AIntParam: Integer = MaxInt);
 | 
						|
begin
 | 
						|
  OnRender := ARenderEvent;
 | 
						|
  RefFile := ARefFileName;
 | 
						|
  IntParam := AIntParam;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{ TMainForm }
 | 
						|
 | 
						|
procedure TMainForm.BtnSaveAsRefClick(Sender: TObject);
 | 
						|
var
 | 
						|
  bmp: TBitmap;
 | 
						|
  png: TPortableNetworkGraphic;
 | 
						|
  fn: String;
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  page: TvVectorialPage;
 | 
						|
begin
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if RenderParams = nil then
 | 
						|
    exit;
 | 
						|
  if FDoc[rcBottomLeftCoords] = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  page := FDoc[rcBottomLeftCoords].GetPageAsVectorial(0);
 | 
						|
 | 
						|
  bmp := TBitmap.Create;
 | 
						|
  try
 | 
						|
    bmp.SetSize(BottomLeftPaintbox.Width, BottomLeftPaintbox.Height);
 | 
						|
    bmp.Canvas.GetUpdatedHandle([csHandleValid]);  // create the Handle needed by next line
 | 
						|
    page.DrawBackground(bmp.Canvas);
 | 
						|
    // bmp canvas has origin at top/left
 | 
						|
    page.Render(bmp.Canvas, 0, bmp.Height, 1.0, -1.0);
 | 
						|
    png := TPortableNetworkGraphic.Create;
 | 
						|
    try
 | 
						|
      png.Assign(bmp);
 | 
						|
     // renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
      ForceDirectory(IMG_FOLDER);
 | 
						|
      fn := IncludeTrailingPathDelimiter(IMG_FOLDER) + renderParams.RefFile;
 | 
						|
      png.SaveToFile(fn);
 | 
						|
    finally
 | 
						|
      png.Free;
 | 
						|
    end;
 | 
						|
    RefImage.Picture.Assign(bmp);
 | 
						|
    RefImage.Hint := fn;
 | 
						|
  finally
 | 
						|
    bmp.Free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.BtnSaveToFilesClick(Sender: TObject);
 | 
						|
var
 | 
						|
  fn: String;
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  folder: String;
 | 
						|
  fmt: TvVectorialFormat;
 | 
						|
  ext: String;
 | 
						|
begin
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if RenderParams = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  fmt := GetFileFormat;
 | 
						|
  ext := GetFileFormatExt;
 | 
						|
  folder := IMG_FOLDER + ext + PathDelim;
 | 
						|
  ForceDirectory(folder);
 | 
						|
 | 
						|
  if FDoc[rcBottomLeftCoords] <> nil then begin
 | 
						|
    fn := folder + 'bl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
    FDoc[rcBottomLeftCoords].WriteToFile(fn, fmt);
 | 
						|
    ShowFileImage(fn, false, WRBottomLeftPaintbox);
 | 
						|
  end;
 | 
						|
 | 
						|
  if FDoc[rcTopLeftCoords] <> nil then begin
 | 
						|
    fn := folder + 'tl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
    FDoc[rcTopLeftCoords].WriteToFile(fn, fmt);
 | 
						|
    ShowFileImage(fn, true, WRTopLeftPaintbox);
 | 
						|
  end;
 | 
						|
 | 
						|
  UpdateCmdStates;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.BtnViewImageClick(Sender: TObject);
 | 
						|
var
 | 
						|
  fn: String;
 | 
						|
  ext: String;
 | 
						|
  folder: String;
 | 
						|
  renderParams: TRenderParams;
 | 
						|
begin
 | 
						|
  BtnSaveToFilesClick(nil);
 | 
						|
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if renderParams = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  ext := GetFileFormatExt;
 | 
						|
  folder := IMG_FOLDER + ext + PathDelim;
 | 
						|
 | 
						|
  if Sender = BtnViewBottomLeft then
 | 
						|
    fn := folder + 'bl_' + ChangeFileExt(renderParams.RefFile, '.' + ext)
 | 
						|
  else if Sender = BtnViewTopLeft then
 | 
						|
    fn := folder + 'tl_' + ChangeFileExt(renderParams.RefFile, '.' + ext)
 | 
						|
  else
 | 
						|
    raise Exception.Create('BtnViewImageClick: this sender is not supported.');
 | 
						|
 | 
						|
  if FileExists(fn) then
 | 
						|
    OpenDocument(fn);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.CbFileFormatChange(Sender: TObject);
 | 
						|
begin
 | 
						|
  ShowWriteReadTestImages;
 | 
						|
  UpdateCmdStates;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.PrepareDoc(var ADoc: TvVectorialDocument;
 | 
						|
  var APage: TvVectorialPage; AUseTopLeftCoords: boolean);
 | 
						|
var
 | 
						|
  r: TvRectangle;
 | 
						|
begin
 | 
						|
  FreeAndNil(ADoc);
 | 
						|
  ADoc := TvVectorialDocument.Create;
 | 
						|
  APage := ADoc.AddPage;
 | 
						|
  APage.BackgroundColor := colWhite;
 | 
						|
  APage.Width := PAGE_SIZE;
 | 
						|
  APage.Height := PAGE_SIZE;
 | 
						|
  ADoc.Width := PAGE_SIZE;
 | 
						|
  ADoc.Height := PAGE_SIZE;
 | 
						|
  APage.UseTopLeftCoordinates := AUseTopLeftCoords;
 | 
						|
 | 
						|
  // Add a frame around the page
 | 
						|
  r := TvRectangle.Create(APage);
 | 
						|
  r.X := 0;
 | 
						|
  if AUseTopLeftCoords then
 | 
						|
    r.Y := 0
 | 
						|
  else
 | 
						|
    r.Y := APage.Height;
 | 
						|
  r.CX := APage.Width - 1;
 | 
						|
  r.CY := APage.Height - 1;
 | 
						|
  r.Brush := CreateSimpleBrush(bsClear);
 | 
						|
  r.Pen := CreatePen(psSolid, 1, colSilver);
 | 
						|
  APage.AddEntity(r);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.FormCreate(Sender: TObject);
 | 
						|
begin
 | 
						|
  RefImage.Hint := NOT_SAVED;
 | 
						|
  WRBottomLeftPaintbox.Hint := NOT_SAVED;
 | 
						|
  WRTopLeftPaintbox.Hint := NOT_SAVED;
 | 
						|
 | 
						|
  ReadIni;
 | 
						|
  Populate;
 | 
						|
  TreeSelectionChanged(nil);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.FormDestroy(Sender: TObject);
 | 
						|
var
 | 
						|
  parentnode, node: TTreeNode;
 | 
						|
  rc: TRenderCoords;
 | 
						|
begin
 | 
						|
  parentnode := Tree.Items.GetFirstNode;
 | 
						|
  while parentnode <> nil do begin
 | 
						|
    node := parentnode.GetFirstChild;
 | 
						|
    while node <> nil do begin
 | 
						|
      TObject(node.Data).Free;
 | 
						|
      node := node.GetNextSibling;
 | 
						|
    end;
 | 
						|
    parentnode := parentnode.GetNextSibling;
 | 
						|
  end;
 | 
						|
 | 
						|
  for rc in TRenderCoords do begin
 | 
						|
    FreeAndNil(FDoc[rc]);
 | 
						|
    FreeAndNil(FDocFromSVG[rc]);
 | 
						|
    FreeAndNil(FDocFromWMF[rc]);
 | 
						|
  end;
 | 
						|
 | 
						|
  WriteIni;
 | 
						|
end;
 | 
						|
 | 
						|
function TMainForm.GetFileFormat: TvVectorialFormat;
 | 
						|
begin
 | 
						|
  case CbFileFormat.ItemIndex of
 | 
						|
    0: Result := vfSVG;
 | 
						|
    1: Result := vfWindowsMetafileWMF;
 | 
						|
    else raise Exception.Create('Format not supported');
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
function TMainForm.GetFileFormatExt: String;
 | 
						|
begin
 | 
						|
  case CbFileFormat.ItemIndex of
 | 
						|
    0: Result := 'svg';
 | 
						|
    1: Result := 'wmf';
 | 
						|
    else raise Exception.Create('Format not supported');
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.PaintBoxPaint(Sender: TObject);
 | 
						|
var
 | 
						|
  doc: TvVectorialDocument;
 | 
						|
  page: TvVectorialPage;
 | 
						|
  w, h: Integer;
 | 
						|
  fmt: TvVectorialFormat;
 | 
						|
  rc: TRenderCoords;
 | 
						|
begin
 | 
						|
  fmt := GetFileFormat;
 | 
						|
 | 
						|
  if (Sender = BottomLeftPaintbox) or (Sender = WRBottomLeftPaintbox) then
 | 
						|
    rc := rcBottomLeftCoords
 | 
						|
  else
 | 
						|
  if (Sender = TopLeftPaintbox) or (Sender = WRTopLeftPaintbox) then
 | 
						|
    rc := rcTopLeftCoords
 | 
						|
  else
 | 
						|
    raise Exception.Create('This sender is not supported here.');
 | 
						|
 | 
						|
  doc := nil;
 | 
						|
  if (Sender = BottomLeftPaintbox) or (Sender = TopLeftPaintbox) then
 | 
						|
    doc := FDoc[rc]
 | 
						|
  else
 | 
						|
  if (Sender = WRBottomLeftPaintbox) or (Sender = WRTopLeftPaintbox) then
 | 
						|
    case GetFileFormat of
 | 
						|
      vfSVG:
 | 
						|
        doc := FDocFromSVG[rc];
 | 
						|
      vfWindowsMetafileWMF:
 | 
						|
        doc := FDocFromWMF[rc];
 | 
						|
      else
 | 
						|
        raise Exception.Create('File format not supported.');
 | 
						|
    end;
 | 
						|
 | 
						|
  w := TPaintbox(Sender).Width;
 | 
						|
  h := TPaintbox(Sender).Height;
 | 
						|
 | 
						|
  if doc = nil then begin
 | 
						|
    TPaintbox(Sender).Canvas.Brush.Color := clDefault;
 | 
						|
    TPaintbox(Sender).Canvas.Brush.Style := bsSolid;
 | 
						|
    TPaintbox(Sender).Canvas.FillRect(0, 0, w, h);
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
 | 
						|
  page := doc.GetPageAsVectorial(0);
 | 
						|
  page.DrawBackground(TPaintbox(Sender).Canvas);
 | 
						|
  if page.UseTopLeftCoordinates then
 | 
						|
    page.Render(TPaintbox(Sender).Canvas, 0, 0, 1.0, 1.0)
 | 
						|
  else
 | 
						|
    page.Render(TPaintbox(Sender).Canvas, 0, h, 1.0, -1.0);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Populate;
 | 
						|
var
 | 
						|
  node, node0, node1: TTreeNode;
 | 
						|
begin
 | 
						|
  Tree.Items.Clear;
 | 
						|
 | 
						|
  { --------------------------------------------------}
 | 
						|
  node := Tree.Items.AddChild(nil, 'Simple shapes');
 | 
						|
  { --------------------------------------------------}
 | 
						|
  Tree.Items.AddChildObject(node, 'Circle (solid) - move up',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'circle_solid.png', $0100));
 | 
						|
  Tree.Items.AddChildObject(node, 'Ellipse (solid) - moved up',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'ellipse_solid.png', $0200));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rectangle(solid) - moved up',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rect_solid.png', $0300));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rounded rectangle (solid) - moved up',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rounded_rect_solid.png', $0400));
 | 
						|
  Tree.Items.AddChildObject(node, 'Polygon (solid) - moved up',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'polygon_solid.png', $0500));
 | 
						|
 | 
						|
  { --------------------------------------------------}
 | 
						|
  node := Tree.Items.AddChild(nil, 'Complex shapes');
 | 
						|
  { --------------------------------------------------}
 | 
						|
  Tree.Items.AddChildObject(node, 'Path with hole (solid fill)',
 | 
						|
    TRenderParams.Create(@Render_Path_Hole_SolidFill, 'path_hole_solid.png'));
 | 
						|
  Tree.Items.AddChildObject(node, 'Path with hole (gradient fill)',
 | 
						|
    TRenderParams.Create(@Render_Path_Hole_GradientFill, 'path_hole_gradient.png'));
 | 
						|
  Tree.Items.AddChildObject(node, 'Self-intersecting polygon (solid fill, even-odd rule) - tip at bottom',
 | 
						|
    TRenderParams.Create(@Render_SelfIntersectingPoly_SolidFill_EvenOdd, 'selfintersecting_poly_solid_eo.png'));
 | 
						|
  Tree.Items.AddChildObject(node, 'Self-intersecting polygon (gradient fill, even-odd rule) - tip at bottom',
 | 
						|
    TRenderParams.Create(@Render_SelfIntersectingPoly_GradientFill_EvenOdd, 'selfintersecting_poly_gradient_eo.png'));
 | 
						|
  Tree.Items.AddChildObject(node, 'Self-intersecting polygon (solid fill, nonzero winding rule) - tip at bottom',
 | 
						|
    TRenderParams.Create(@Render_SelfIntersectingPoly_SolidFill_NonZeroWinding, 'selfintersecting_poly_solid_nzw.png'));
 | 
						|
  Tree.Items.AddChildObject(node, 'Self-intersecting polygon (gradient fill, nonzero winding rule) - tip at bottom',
 | 
						|
    TRenderParams.Create(@Render_SelfIntersectingPoly_GradientFill_NonZeroWinding, 'selfintersecting_poly_gradient_nzw.png'));
 | 
						|
 | 
						|
  { -----------------------------------------}
 | 
						|
  node0 := Tree.Items.AddChild(nil, 'Arcs');
 | 
						|
  { -----------------------------------------}
 | 
						|
  node1 := Tree.Items.AddChild(node0, 'circular');
 | 
						|
  node := Tree.Items.AddChild(node1, 'clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q1.png', $0200));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q12.png', $0201));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q2.png', $0202));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q23.png', $0203));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q3.png', $0204));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q34.png', $0205));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q4.png', $0206));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q41.png', $0207));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q1r.png', $0300));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q12r.png', $0301));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q2r.png', $0302));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q23r.png', $0303));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q3r.png', $0304));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q34r.png', $0305));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q4r.png', $0306));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_cw_q41r.png', $0307));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node1, 'counter-clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q1.png', $0000));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q12.png', $0001));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q2.png', $0002));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q23.png', $0003));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q3.png', $0004));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q34.png', $0005));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q4.png', $0006));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q41.png', $0007));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q1r.png', $0100));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q12r.png', $0101));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q2r.png', $0102));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q23r.png', $0103));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q3r.png', $0104));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q34r.png', $0105));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q4r.png', $0106));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ccw_q41r.png', $0107));
 | 
						|
 | 
						|
  node1 := Tree.Items.AddChild(node0, 'elliptical');
 | 
						|
  node := Tree.Items.AddChild(node1, 'clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q1.png', $1200));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q12.png', $1201));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q2.png', $1202));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q23.png', $1203));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q3.png', $1204));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q34.png', $1205));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q4.png', $1206));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q41.png', $1207));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q1r.png', $1300));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q12r.png', $1301));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q2r.png', $1302));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q23r.png', $1303));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q3r.png', $1304));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q34r.png', $1305));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q4r.png', $1306));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_cw_q41r.png', $1307));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node1, 'counter-clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q1.png', $1000));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q12.png', $1001));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q2.png', $1002));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q23.png', $1003));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q3.png', $1004));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q34.png', $1005));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q4.png', $1006));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q41.png', $1007));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q1r.png', $1100));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q12r.png', $1101));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q2r.png', $1102));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q23r.png', $1103));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q3r.png', $1104));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q34r.png', $1105));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q4r.png', $1106));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ell_ccw_q41r.png', $1107));
 | 
						|
 | 
						|
  node1 := Tree.Items.AddChild(node0, 'elliptical, rotated 30deg');
 | 
						|
  node := Tree.Items.AddChild(node1, 'clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q1.png', $2200));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q12.png', $2201));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q2.png', $2202));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q23.png', $2203));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q3.png', $2204));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q34.png', $2205));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q4.png', $2206));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q41.png', $2207));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q1r.png', $2300));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q12r.png', $2301));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q2r.png', $2302));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q23r.png', $2303));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q3r.png', $2304));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q34r.png', $2305));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q4r.png', $2306));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_cw_q41r.png', $2307));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node1, 'counter-clockwise from point 1 to point 2');
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q1.png', $2000));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q12.png', $2001));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q2.png', $2002));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q23.png', $2003));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q3.png', $2004));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q34.png', $2005));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q4.png', $2006));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q41.png', $2007));
 | 
						|
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q1r.png', $2100));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant I+II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q12r.png', $2101));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q2r.png', $2102));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant II+III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q23r.png', $2103));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q3r.png', $2104));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant III+IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q34r.png', $2105));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q4r.png', $2106));
 | 
						|
  Tree.Items.AddChildObject(node, 'Quadrant IV+I, reverse',
 | 
						|
    TRenderParams.Create(@Render_Arc, 'arc_ellrot_ccw_q41r.png', $2107));
 | 
						|
 | 
						|
  { -----------------------------------------------}
 | 
						|
  node := Tree.Items.AddChild(nil, 'Bezier');
 | 
						|
  { -----------------------------------------------}
 | 
						|
  Tree.Items.AddChildObject(node, 'Single segment',
 | 
						|
    TRenderParams.Create(@Render_Bezier, 'bezier.png'));
 | 
						|
 | 
						|
  { -----------------------------------------------}
 | 
						|
  node0 := Tree.Items.AddChild(nil, 'Gradients');
 | 
						|
  { -----------------------------------------------}
 | 
						|
  node := Tree.Items.AddChild(node0, 'horizontal');
 | 
						|
  Tree.Items.AddChildObject(node, 'Circle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'circle_gradienthor.png', $0101));
 | 
						|
  Tree.Items.AddChildObject(node, 'Ellipse',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'ellipse_gradienthor.png', $0201));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rect_gradienthor.png', $0301));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rounded rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rounded_rect_gradienthor.png', $0401));
 | 
						|
  Tree.Items.AddChildObject(node, 'Polygon',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'polygon_gradienthor.png', $0501));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'vertical');
 | 
						|
  Tree.Items.AddChildObject(node, 'Circle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'circle_gradientvert.png', $0102));
 | 
						|
  Tree.Items.AddChildObject(node, 'Ellipse',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'ellipse_gradientvert.png', $0202));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rect_gradientvert.png', $0302));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rounded rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rounded_rect_gradientvert.png', $0402));
 | 
						|
  Tree.Items.AddChildObject(node, 'Polygon',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'polygon_gradientvert.png', $0502));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'linear');
 | 
						|
  Tree.Items.AddChildObject(node, 'Circle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'circle_gradientlinear.png', $0103));
 | 
						|
  Tree.Items.AddChildObject(node, 'Ellipse',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'ellipse_gradientlinear.png', $0203));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rect_gradientlinear.png', $0303));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rounded rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rounded_rect_gradientlinear.png', $0403));
 | 
						|
  Tree.Items.AddChildObject(node, 'Polygon',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'polygon_gradientlinear.png', $0503));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'radial');
 | 
						|
  Tree.Items.AddChildObject(node, 'Circle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'circle_gradientradial.png', $0104));
 | 
						|
  Tree.Items.AddChildObject(node, 'Ellipse',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'ellipse_gradientradial.png', $0204));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rect_gradientradial.png', $0304));
 | 
						|
  Tree.Items.AddChildObject(node, 'Rounded rectangle',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'rounded_rect_gradientradial.png', $0404));
 | 
						|
  Tree.Items.AddChildObject(node, 'Polygon',
 | 
						|
    TRenderParams.Create(@Render_Shape, 'polygon_gradientradial.png', $0504));
 | 
						|
 | 
						|
  { -----------------------------------------------}
 | 
						|
  node0 := Tree.Items.AddChild(nil, 'Text');
 | 
						|
  { -----------------------------------------------}
 | 
						|
  node := Tree.Items.AddChild(node0, 'horizontal');
 | 
						|
  Tree.Items.AddChildObject(node, 'left aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_left.png', $0000));
 | 
						|
  Tree.Items.AddChildObject(node, 'centered',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_center.png', $0001));
 | 
						|
  Tree.Items.AddChildObject(node, 'right aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_right.png', $0002));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'rotated by 30 deg');
 | 
						|
  Tree.Items.AddChildObject(node, 'left aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_left_30.png', $1000));
 | 
						|
  Tree.Items.AddChildObject(node, 'centered',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_center_30.png', $1001));
 | 
						|
  Tree.Items.AddChildObject(node, 'right aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_right_30.png', $1002));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'vertical (90 deg, upward)');
 | 
						|
  Tree.Items.AddChildObject(node, 'left aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_left_90.png', $2000));
 | 
						|
  Tree.Items.AddChildObject(node, 'centered',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_center_90.png', $2001));
 | 
						|
  Tree.Items.AddChildObject(node, 'right aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_right_90.png', $2002));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'vertical (-90 deg, downward)');
 | 
						|
  Tree.Items.AddChildObject(node, 'left aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_left_m90.png', $3000));
 | 
						|
  Tree.Items.AddChildObject(node, 'centered',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_center_m90.png', $3001));
 | 
						|
  Tree.Items.AddChildObject(node, 'right aligned',
 | 
						|
    TRenderParams.Create(@Render_Text, 'text_right_m90.png', $3002));
 | 
						|
 | 
						|
  node := Tree.Items.AddChild(node0, 'Fonts');
 | 
						|
  Tree.Items.AddChildObject(node, 'Times New Roman + Courier New',
 | 
						|
    TRenderParams.Create(@Render_Text_Fonts, 'text_fonts.png'));
 | 
						|
  Tree.Items.AddChildObject(node0, 'Text colors',
 | 
						|
    TRenderParams.Create(@Render_Text_Colors, 'text_colors.png'));
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Shape(APage: TvVectorialPage;
 | 
						|
  AIntParam: Integer);
 | 
						|
{ AIntParam and $00FF = 0 --> solid fill
 | 
						|
                        1 --> horizontal gradient
 | 
						|
                        2 --> vertical gradient
 | 
						|
                        3 --> linear gradient
 | 
						|
                        4 --> radial gradient
 | 
						|
  AIntParam and $FF00 = $0100 --> circle
 | 
						|
                        $0200 --> ellipse
 | 
						|
                        $0300 --> rectangle
 | 
						|
                        $0400 --> rounded rect
 | 
						|
                        $0500 --> polygon (triangle) }
 | 
						|
var
 | 
						|
  ent: TvEntityWithPenAndBrush;
 | 
						|
begin
 | 
						|
  case AIntParam and $FF00 of
 | 
						|
    $0100: ent := CreateStdCircle(APage);
 | 
						|
    $0200: ent := CreateStdEllipse(APage);
 | 
						|
    $0300: ent := CreateStdRect(APage);
 | 
						|
    $0400: ent := CreateStdRoundedRect(APage);
 | 
						|
    $0500: ent := CreateStdPolygon(APage);
 | 
						|
    else   raise Exception.Create('Shape not supported.');
 | 
						|
  end;
 | 
						|
  case AIntParam and $00FF of
 | 
						|
    $0000: ent.Brush := StdSolidBrush;
 | 
						|
    $0001: ent.Brush := StdHorizGradientBrush;
 | 
						|
    $0002: ent.Brush := StdVertGradientBrush;
 | 
						|
    $0003: ent.Brush := StdLinearGradientBrush;
 | 
						|
    $0004: ent.Brush := StdRadialGradientBrush;
 | 
						|
    else raise Exception.Create('Brush not supported');
 | 
						|
  end;
 | 
						|
  APage.AddEntity(ent);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Arc(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
//
 | 
						|
// AIntParam and $000F = $0000  --> circular arc
 | 
						|
//                       $1000  --> elliptical arc
 | 
						|
//                       $2000  --> elliptical arc, rotated
 | 
						|
// AIntParam and $000F = $0000  --> quarter 1
 | 
						|
//                       $0001  --> quarter 1 + 2
 | 
						|
//                       $0002  --> quarter 2
 | 
						|
//                       $0003  --> quarter 2 + 3
 | 
						|
//                       $0004  --> quarter 3
 | 
						|
//                       $0005  --> quarter 3+4
 | 
						|
//                       $0006  --> quarter 4
 | 
						|
//                       $0007  --> quarter 4+1
 | 
						|
// AIntParam and $0100 = $0100  --> start and end points exchanged
 | 
						|
// AIntParan and $0200 = $0200  --> clockwise
 | 
						|
const
 | 
						|
  ROT_ANGLE = 30;
 | 
						|
  RY_MULT = 0.6;
 | 
						|
  CX = 50;
 | 
						|
  CY = 55;
 | 
						|
  R = 30;
 | 
						|
var
 | 
						|
  isReversed, isClockwise, isEllipse, isRotated: Boolean;
 | 
						|
  p: T3dPoint;
 | 
						|
  x1, y1, x2, y2, rx, ry: Double;
 | 
						|
  startAngle, endAngle, phi: Double;
 | 
						|
begin
 | 
						|
  isReversed := AIntParam and $0100 <> 0;
 | 
						|
  isClockwise := AIntParam and $0200 <> 0;
 | 
						|
  isEllipse := AIntParam and $F000 <> 0;
 | 
						|
  isRotated := AIntParam and $F000 = $2000;
 | 
						|
 | 
						|
  rx := R;
 | 
						|
  ry := IfThen(isEllipse, R * RY_MULT, R);
 | 
						|
  phi := IfThen(isRotated, DegToRad(ROT_ANGLE), 0.0);
 | 
						|
 | 
						|
  startAngle := DegToRad((AIntParam and $000F) * 45);  //  0°,  45°,  90°, ...
 | 
						|
  endAngle := startAngle + pi/2;                       // 90°, 135°, 180°, ...
 | 
						|
  x1 := CX + rx * cos(startAngle);
 | 
						|
  y1 := CY + ry * sin(startAngle);
 | 
						|
  x2 := CX + rx * cos(endAngle);
 | 
						|
  y2 := CY + ry * sin(endAngle);
 | 
						|
  if isRotated then begin
 | 
						|
    p := Rotate3DPointInXY(Make3DPoint(x1, y1), Make3DPoint(CX, CY), -phi);
 | 
						|
    // See comment at Rotate3DPointInXY regarding the negative sign of phi
 | 
						|
    x1 := p.x;
 | 
						|
    y1 := p.y;
 | 
						|
    p := Rotate3DPointInXY(Make3DPoint(x2, y2), Make3DPoint(CX, CY), -phi);
 | 
						|
    x2 := p.x;
 | 
						|
    y2 := p.y;
 | 
						|
  end;
 | 
						|
 | 
						|
  if isReversed then
 | 
						|
    CreateArc(APage, x2, y2, x1, y1, CX, CY, rx, ry, phi, isClockwise)
 | 
						|
  else
 | 
						|
    CreateArc(APage, x1, y1, x2, y2, CX, CY, rx, ry, phi, isClockwise);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Bezier(APage: TvVectorialpage; AIntParam: Integer);
 | 
						|
const
 | 
						|
  X1 = 10;
 | 
						|
  Y1 = 25;
 | 
						|
  X2 = 30;
 | 
						|
  Y2 = 80;
 | 
						|
  X3 = 50;
 | 
						|
  Y3 = 70;
 | 
						|
  X4 = 90;
 | 
						|
  Y4 = 25;
 | 
						|
begin
 | 
						|
  CreateBezier(APage, X1,Y1, X2,Y2, X3,Y3, X4,Y4);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Path_Hole_SolidFill(APage: TvVectorialPage;
 | 
						|
  AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TPath;
 | 
						|
begin
 | 
						|
  obj := CreatePathWithHole(APage);  // no need to AddEntity!
 | 
						|
  obj.Brush.Color := colYellow;
 | 
						|
  obj.Brush.Style := bsSolid;
 | 
						|
  obj.Pen.Width := 3;
 | 
						|
  obj.Pen.Color := colBlue;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Path_Hole_GradientFill(APage: TvVectorialPage;
 | 
						|
  AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TPath;
 | 
						|
begin
 | 
						|
  obj := CreatePathWithHole(APage);  // No need to AddEntity!
 | 
						|
  obj.Brush := StdLinearGradientBrush;
 | 
						|
  obj.Pen.Width := 3;
 | 
						|
  obj.Pen.Color := colBlue;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_SelfIntersectingPoly_SolidFill_EvenOdd(
 | 
						|
  APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TvPolygon;
 | 
						|
begin
 | 
						|
  obj := CreateStdSelfIntersectingPolygon(APage);
 | 
						|
  obj.WindingRule := vcmEvenOddRule;
 | 
						|
  obj.Brush := StdSolidBrush;
 | 
						|
  APage.AddEntity(obj);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_SelfIntersectingPoly_GradientFill_EvenOdd(
 | 
						|
  APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TvPolygon;
 | 
						|
begin
 | 
						|
  obj := CreateStdSelfIntersectingPolygon(APage);
 | 
						|
  obj.Brush := StdHorizGradientBrush;
 | 
						|
  obj.WindingRule := vcmEvenOddRule;
 | 
						|
  APage.AddEntity(obj);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_SelfIntersectingPoly_SolidFill_NonZeroWinding(
 | 
						|
  APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TvPolygon;
 | 
						|
begin
 | 
						|
  obj := CreateStdSelfIntersectingPolygon(APage);
 | 
						|
  obj.WindingRule := vcmNonZeroWindingRule;
 | 
						|
  obj.Brush := StdSolidBrush;
 | 
						|
  APage.AddEntity(obj);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_SelfIntersectingPoly_GradientFill_NonZeroWinding(
 | 
						|
  APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
var
 | 
						|
  obj: TvPolygon;
 | 
						|
begin
 | 
						|
  obj := CreateStdSelfIntersectingPolygon(APage);
 | 
						|
  obj.Brush := StdHorizGradientBrush;
 | 
						|
  obj.WindingRule := vcmNonzeroWindingRule;
 | 
						|
  APage.AddEntity(obj);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Text(APage: TvVectorialPage; AIntParam: Integer);
 | 
						|
{ AIntParam and $000F = $0000  --> anchor at left
 | 
						|
                        $0001  --> anchor at center
 | 
						|
                        $0002  --> anchor at right
 | 
						|
  AIntParam and $F000 = $0000  --> horizontal
 | 
						|
                        $1000  --> rotated 30deg
 | 
						|
                        $2000  --> rotated 90deg
 | 
						|
                        $3000  --> rotated -90deg }
 | 
						|
const
 | 
						|
  XTEXT = 50;
 | 
						|
  YTEXT = 40;  // we assume that y points up
 | 
						|
  L = 10;
 | 
						|
var
 | 
						|
  txt: TvText;
 | 
						|
  p: TPath;
 | 
						|
  angle: double;
 | 
						|
  anchor: TvTextAnchor;
 | 
						|
begin
 | 
						|
  case AIntParam and $000F of
 | 
						|
    $0000 : anchor := vtaStart;
 | 
						|
    $0001 : anchor := vtaMiddle;
 | 
						|
    $0002 : anchor := vtaEnd;
 | 
						|
    else raise Exception.Create('Text anchor not supported');
 | 
						|
  end;
 | 
						|
  case AIntParam and $F000 of
 | 
						|
    $0000 : angle := 0;
 | 
						|
    $1000 : angle := 30;
 | 
						|
    $2000 : angle := 90;
 | 
						|
    $3000 : angle := -90;
 | 
						|
    else raise Exception.Create('Text angle not supported.');
 | 
						|
  end;
 | 
						|
 | 
						|
  // Draw "+" at the origin of the text
 | 
						|
  if APage.UseTopLeftCoordinates then begin
 | 
						|
    APage.StartPath    (XTEXT - L, PAGE_SIZE - YTEXT);
 | 
						|
    APage.AddLineToPath(XTEXT + L, PAGE_SIZE - YTEXT);
 | 
						|
    APage.AddMoveToPath(XTEXT,     PAGE_SIZE - YTEXT - L);
 | 
						|
    APage.AddLineToPath(XTEXT,     PAGE_SIZE - YTEXT + L);
 | 
						|
  end else begin
 | 
						|
    APage.StartPath    (XTEXT - L, YTEXT);
 | 
						|
    APage.AddLineToPath(XTEXT + L, YTEXT);
 | 
						|
    APage.AddMoveToPath(XTEXT,     YTEXT - L);
 | 
						|
    APage.AddLineToPath(XTEXT,     YTEXT + L);
 | 
						|
  end;
 | 
						|
  p := APage.EndPath;
 | 
						|
  p.Pen.Width := 1;
 | 
						|
  p.Pen.Color := colRed;
 | 
						|
 | 
						|
  // Draw text
 | 
						|
  txt := TvText.Create(APage);
 | 
						|
  txt.X := XTEXT;
 | 
						|
  if APage.UseTopLeftCoordinates then
 | 
						|
    txt.Y := PAGE_SIZE - YTEXT else
 | 
						|
    txt.Y := YTEXT;
 | 
						|
  txt.Value.Add('ABC');
 | 
						|
  txt.Font.Size := 14;
 | 
						|
  txt.TextAnchor := anchor;
 | 
						|
  txt.Font.Orientation := angle;
 | 
						|
 | 
						|
  APage.AddEntity(txt);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Text_Fonts(APage: TvVectorialPage;
 | 
						|
  AIntParam: Integer);
 | 
						|
var
 | 
						|
  txt: TvText;
 | 
						|
begin
 | 
						|
  txt := TvText.Create(APage);
 | 
						|
  txt.X := 10;
 | 
						|
  txt.Y := 80;
 | 
						|
  txt.Font.Name := 'Times New Roman';
 | 
						|
  txt.Font.Size := 10;
 | 
						|
  txt.Value.Add('Times');
 | 
						|
  APage.AddEntity(txt);
 | 
						|
 | 
						|
  txt := TvText.Create(APage);
 | 
						|
  txt.X := 10;
 | 
						|
  txt.Y := 60;
 | 
						|
  txt.Font.Name := 'Courier New';
 | 
						|
  txt.Font.Size := 12;
 | 
						|
  txt.Value.Add('Courier');
 | 
						|
  APage.AddEntity(txt);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.Render_Text_Colors(APage: TvVectorialPage;
 | 
						|
  AIntParam: Integer);
 | 
						|
var
 | 
						|
  txt: TvText;
 | 
						|
begin
 | 
						|
  txt := TvText.Create(APage);
 | 
						|
  txt.X := 10;
 | 
						|
  txt.Y := 80;
 | 
						|
  txt.Font.Name := 'Times New Roman';
 | 
						|
  txt.Font.Size := 14;
 | 
						|
  txt.Font.Color := colRed;
 | 
						|
  txt.Value.Add('Text');
 | 
						|
  txt.Brush.Style := bsSolid;
 | 
						|
  txt.Brush.Color := colYellow;
 | 
						|
  txt.Brush.Kind := bkSimpleBrush;
 | 
						|
  APage.AddEntity(txt);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.ReadIni;
 | 
						|
var
 | 
						|
  ini: TCustomIniFile;
 | 
						|
  L, T, W, H: Integer;
 | 
						|
  rct: TRect;
 | 
						|
begin
 | 
						|
  ini := TMemIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
 | 
						|
  try
 | 
						|
    L := ini.ReadInteger('MainForm', 'Left', Left);
 | 
						|
    T := ini.ReadInteger('MainForm', 'Top', Top);
 | 
						|
    W := ini.ReadInteger('MainForm', 'Width', Width);
 | 
						|
    H := ini.ReadInteger('MainForm', 'Height', Height);
 | 
						|
    rct := Screen.DesktopRect;
 | 
						|
    if L + W > rct.Right - rct.Left then L := rct.Right - W;
 | 
						|
    if L < 0 then L := rct.Left;
 | 
						|
    if T + H > rct.Bottom - rct.Top then T := rct.Bottom - H;
 | 
						|
    if T < 0 then T := rct.Top;
 | 
						|
    SetBounds(L, T, W, H);
 | 
						|
  finally
 | 
						|
    ini.Free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.WriteIni;
 | 
						|
var
 | 
						|
  ini: TCustomIniFile;
 | 
						|
begin
 | 
						|
  ini := TMemIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
 | 
						|
  try
 | 
						|
    if WindowState = wsNormal then
 | 
						|
    begin
 | 
						|
      ini.WriteInteger('MainForm', 'Left', Left);
 | 
						|
      ini.WriteInteger('MainForm', 'Top', Top);
 | 
						|
      ini.WriteInteger('MainForm', 'Width', Width);
 | 
						|
      ini.WriteInteger('MainForm', 'Height', Height);
 | 
						|
    end;
 | 
						|
  finally
 | 
						|
    ini.Free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.ShowFileImage(AFilename: String; AUseTopLeftCoords: Boolean;
 | 
						|
  APaintbox: TPaintbox);
 | 
						|
var
 | 
						|
  ext: String;
 | 
						|
  rc: TRenderCoords;
 | 
						|
begin
 | 
						|
  if AUseTopLeftCoords then
 | 
						|
    rc := rcTopLeftCoords else
 | 
						|
    rc := rcBottomLeftCoords;
 | 
						|
 | 
						|
  ext := Lowercase(ExtractFileExt(AFileName));
 | 
						|
 | 
						|
  if not FileExists(AFileName) then begin
 | 
						|
    case ext of
 | 
						|
      '.svg': FreeAndNil(FDocFromSVG[rc]);
 | 
						|
      '.wmf': FreeAndNil(FDocFromWMF[rc]);
 | 
						|
      else    raise Exception.Create('File type not supported');
 | 
						|
    end;
 | 
						|
    APaintbox.Hint := NOT_SAVED;
 | 
						|
    APaintbox.Invalidate;
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
 | 
						|
  if ext = '.svg' then begin
 | 
						|
    FreeAndNil(FDocFromSVG[rc]);
 | 
						|
    FDocFromSVG[rc] := TvVectorialDocument.Create;
 | 
						|
    FDocFromSVG[rc].ReadFromFile(AFileName);
 | 
						|
  end else
 | 
						|
  if ext = '.wmf' then begin
 | 
						|
    FreeAndNil(FDocFromWMF[rc]);
 | 
						|
    FDocFromWMF[rc] := TvVectorialDocument.Create;
 | 
						|
    FDocFromWMF[rc].ReadFromFile(AFilename);
 | 
						|
  end;
 | 
						|
  APaintbox.Hint := AFileName;
 | 
						|
  APaintBox.Invalidate;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.ShowRefImageTest;
 | 
						|
var
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  fn: String;
 | 
						|
begin
 | 
						|
  if Tree.Selected = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if renderParams = nil then
 | 
						|
  begin
 | 
						|
    RefImage.Picture := nil;
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
 | 
						|
  fn := IncludeTrailingPathDelimiter(IMG_FOLDER) + renderParams.RefFile;
 | 
						|
  if FileExists(fn) then begin
 | 
						|
    RefImage.Picture.LoadFromFile(fn);
 | 
						|
    RefImage.Hint := fn;
 | 
						|
  end else begin
 | 
						|
    RefImage.Picture := nil;
 | 
						|
    RefImage.Hint := NOT_SAVED;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.ShowRenderTestImages;
 | 
						|
var
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  page: TvVectorialPage = nil;
 | 
						|
begin
 | 
						|
  if Tree.Selected = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if renderParams = nil then
 | 
						|
  begin
 | 
						|
    BottomLeftPaintbox.Invalidate;
 | 
						|
    TopLeftPaintbox.Invalidate;
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
 | 
						|
  // Render document with bottom/left origin
 | 
						|
  PrepareDoc(FDoc[rcBottomLeftCoords], page, false);
 | 
						|
  renderParams.OnRender(page, renderParams.IntParam);
 | 
						|
  BottomLeftPaintbox.Invalidate;
 | 
						|
 | 
						|
  // Render document with top/left origin
 | 
						|
  PrepareDoc(FDoc[rcTopLeftCoords], page, true);
 | 
						|
  renderParams.OnRender(page, renderParams.IntParam);
 | 
						|
  TopLeftPaintbox.Invalidate;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.ShowWriteReadTestImages;
 | 
						|
var
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  folder: String;
 | 
						|
  fn: String;
 | 
						|
  ext: String;
 | 
						|
  rc: TRenderCoords;
 | 
						|
begin
 | 
						|
  for rc in TRenderCoords do begin
 | 
						|
    FreeAndNil(FDocFromSVG[rc]);
 | 
						|
    FreeAndNil(FDocFromWMF[rc]);
 | 
						|
  end;
 | 
						|
 | 
						|
  if Tree.Selected = nil then
 | 
						|
    exit;
 | 
						|
 | 
						|
  renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
  if renderParams = nil then
 | 
						|
  begin
 | 
						|
    WRBottomLeftPaintbox.Invalidate;
 | 
						|
    WRTopLeftPaintbox.Invalidate;
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
 | 
						|
  ext := GetFileFormatExt;
 | 
						|
  folder := IMG_FOLDER + ext + PathDelim;
 | 
						|
 | 
						|
  fn := folder + 'bl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
  ShowFileImage(fn, false, WRBottomLeftPaintbox);
 | 
						|
 | 
						|
  fn := folder + 'tl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
  ShowFileImage(fn, true, WRTopLeftPaintbox);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.TreeSelectionChanged(Sender: TObject);
 | 
						|
begin
 | 
						|
  ShowRenderTestImages;
 | 
						|
  ShowRefImageTest;
 | 
						|
  ShowWriteReadTestImages;
 | 
						|
  UpdateCmdStates;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.TreeCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
 | 
						|
  State: TCustomDrawState; var DefaultDraw: Boolean);
 | 
						|
begin
 | 
						|
  if Node.HasChildren then
 | 
						|
    Sender.Canvas.Font.Style := [fsBold] else
 | 
						|
    Sender.Canvas.Font.Style := [];
 | 
						|
end;
 | 
						|
 | 
						|
procedure TMainForm.UpdateCmdStates;
 | 
						|
var
 | 
						|
  fn: String;
 | 
						|
  folder: string;
 | 
						|
  renderParams: TRenderParams;
 | 
						|
  ext: String;
 | 
						|
  rc: TRenderCoords;
 | 
						|
  rcOK: array[TRenderCoords] of boolean = (false, false);
 | 
						|
begin
 | 
						|
  BtnSaveAsRef.Enabled := Tree.Selected <> nil;
 | 
						|
  BtnSaveToFiles.Enabled := Tree.Selected <> nil;
 | 
						|
  BtnViewBottomLeft.Enabled := Tree.Selected <> nil;
 | 
						|
  BtnViewTopLeft.Enabled := Tree.Selected <> nil;
 | 
						|
 | 
						|
  if Tree.Selected <> nil then begin
 | 
						|
    renderParams := TRenderParams(Tree.Selected.Data);
 | 
						|
    if renderParams <> nil then begin
 | 
						|
      ext := GetFileFormatExt;
 | 
						|
      folder := IMG_FOLDER + ext + PathDelim;
 | 
						|
      fn := folder + 'bl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
      rcOK[rcBottomLeftCoords] := FileExists(fn);
 | 
						|
      fn := folder + 'tl_' + ChangeFileExt(renderParams.RefFile, '.' + ext);
 | 
						|
      rcOK[rcTopLeftCoords] := FileExists(fn);
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  BtnViewBottomLeft.Enabled := rcOK[rcBottomLeftcoords];
 | 
						|
  BtnViewTopLeft.Enabled := rcOK[rcTopLeftCoords];
 | 
						|
end;
 | 
						|
 | 
						|
end.
 | 
						|
 |