{LogoMaker}
{"Королевство Дельфи" http://delphi.vitpc.com}

unit LogoMakerUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, ActnList, ImgList, ComCtrls, ToolWin, StdCtrls, Spin, ExtCtrls;

type
  T4Points = array[0..3] of TPoint;
type
  TfmLogoMaker = class(TForm)
    MainMenu1: TMainMenu;
    mnuFile: TMenuItem;
    mnuAbout: TMenuItem;
    mnuNew: TMenuItem;
    mnuEdit: TMenuItem;
    mnuOpen: TMenuItem;
    mnuSave: TMenuItem;
    mnuSaveAs: TMenuItem;
    N1: TMenuItem;
    mnuMakeCode: TMenuItem;
    N2: TMenuItem;
    mnuExit: TMenuItem;
    mnuChangeMode: TMenuItem;
    mnuUndo: TMenuItem;
    mnuRedo: TMenuItem;
    ActionList: TActionList;
    actNew: TAction;
    actOpen: TAction;
    actSave: TAction;
    actChangeMode: TAction;
    actUndo: TAction;
    actRedo: TAction;
    ImageList1: TImageList;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    ToolButton8: TToolButton;
    ToolButton9: TToolButton;
    ToolButton10: TToolButton;
    ToolButton11: TToolButton;
    ToolButton12: TToolButton;
    ToolButton13: TToolButton;
    ToolButton14: TToolButton;
    actMakeCode: TAction;
    actExit: TAction;
    ToolButton15: TToolButton;
    ToolButton16: TToolButton;
    ToolButton17: TToolButton;
    SpinEdit1: TSpinEdit;
    ToolButton18: TToolButton;
    ToolButton19: TToolButton;
    actClear: TAction;
    actSaveAs: TAction;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    SaveDialog2: TSaveDialog;
    ToolButton20: TToolButton;
    procedure mnuAboutClick(Sender: TObject);
    procedure actNewExecute(Sender: TObject);
    procedure actUndoExecute(Sender: TObject);
    procedure actRedoExecute(Sender: TObject);
    procedure actOpenExecute(Sender: TObject);
    procedure actSaveExecute(Sender: TObject);
    procedure actMakeCodeExecute(Sender: TObject);
    procedure actExitExecute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure actChangeModeExecute(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure ToolButton9Click(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
    procedure actClearExecute(Sender: TObject);
    procedure ToolButton7Click(Sender: TObject);
    procedure ToolButton10Click(Sender: TObject);
    procedure ToolButton11Click(Sender: TObject);
    procedure ToolButton12Click(Sender: TObject);
    procedure actSaveAsExecute(Sender: TObject);
    procedure ToolButton20Click(Sender: TObject);
  private
    procedure AppException(Sender: TObject; E: Exception);
    procedure PutPolygon(strPolygon:string);
    procedure PutEllipse(strRegion:string);
    procedure PutRegion(strRegion:string);
    procedure CanvasClear;
    procedure SetDrawingColor(clColor: TColor);
    procedure PutLine(x:T4Points);
  end;

var
  fmLogoMaker: TfmLogoMaker;

implementation

uses AboutUnit;



{$R *.DFM}



type
  TCurMode = (mdAdd, mdSub);
  TCurDrawingMode = (dmBigPen, dmBigLine, dmPen, dmPolygon, dmEllipse, dmCircle);

const
  FileModified : boolean = false;
  FileName : string = '';
  strRegion : string = '';
  strLocalRegion : string = '';
  strUndo : string = '';
  AddColor = clMenu;
  SubColor = clWhite;
  CurMode : TCurMode = mdAdd;
  CurDrawingMode : TCurDrawingMode = dmBigPen;
  DrawingBegining : boolean = true;
  Drawing : boolean = false;
  hh = 28;
  dd = 2;

var
  f : file of char;
  x1, y1, x2, y2 : integer;

procedure MakeCodeFile(FileName,strRegion:string);
var
  n, nn, i : integer;
  f : TextFile;

procedure PutPolygon(strPolygon:string; FistRecord:boolean);
var
  i, j, n, k, m, a, b, num : integer;
  arPoints : array of TPoint;
  strPoint : string;
begin
  if Length(strPolygon)<1 then exit;

  //определяем количеслво точек n многоугольника
  n:=0;
  for num:=1 to Length(strPolygon) do
    if strPolygon[num]='(' then n:=n+1;
  Writeln(f,'  //Put polygon');
  Writeln(f,'  nn := ',n,';');

  //Запись в файл f операторов заполнения массива P
  k:=0;
  for i:=2 to Length(strPolygon) do
    case strPolygon[i] of
      '(' : begin
              k:=k+1;
              j:=i
            end;
      ')' : begin
              strPoint:=Copy(strPolygon,j,i-j+1);
              Writeln(f, '  P[', k-1, '] := Point', strPoint, ';');
            end;
    end;

  if (FistRecord)
    then begin
        Writeln(f, '  //инициализация ResultReg');    
        Writeln(f, '  ResultReg := CreatePolygonRgn(P, nn, ALTERNATE);');//WINDING
      end
    else begin
        Writeln(f, '  Reg := CreatePolygonRgn(P, nn, ALTERNATE);');
        case strPolygon[1] of
          '+' : Writeln(f, '  CombineRgn(ResultReg,ResultReg,Reg,RGN_OR);');
          '-' : Writeln(f, '  CombineRgn(ResultReg,ResultReg,Reg,RGN_DIFF);');
        end;
      end;
end;//PutPolygon

procedure PutEllipse(strRegion:string; FistRecord:boolean);
var
  k, l, m, n, o, x1, y1, x2, y2 : integer;
  Str : string;
begin
  Writeln(f, '  //Put Ellipse');

  for k:=1 to Length(strRegion) do
    if strRegion[k]='(' then break;

  for l:=k to Length(strRegion) do
    if strRegion[l]=')' then break;

  if (FistRecord)
    then begin
        Writeln(f, '  //инициализация ResultReg');
        Writeln(f, '  ResultReg := CreateEllipticRgn', Copy(strRegion,k,l-k+1), ';');
      end
    else begin
        Writeln(f, '  Reg := CreateEllipticRgn', Copy(strRegion,k,l-k+1), ';');
        case strRegion[1] of
          '+' : Writeln(f, '  CombineRgn(ResultReg,ResultReg,Reg,RGN_OR);');
          '-' : Writeln(f, '  CombineRgn(ResultReg,ResultReg,Reg,RGN_DIFF);');
        end;//case
      end;//else
end;//PutEllipse

procedure PutRegion;
const
  FistRecord : boolean = true;
var
  i, j, k, n, RegionLength : integer;
  strMiddleStr : string;
begin
  strRegion:=strRegion+'+';
  RegionLength:=Length(strRegion);
  for i:=1 to RegionLength do begin
    if not(strRegion[i] in ['+','-']) then continue;
    case strRegion[i+1] of
      '1' : begin
              for j:=i to RegionLength do
                if (strRegion[j]=')') and (strRegion[j+1]<>'(')
                  then break;
              strMiddleStr:=Copy(strRegion,i,j-i+1);
              n:=0;
              if (FistRecord)
                then begin
                  PutPolygon(strMiddleStr,true);
                  FistRecord:=false;
                  end
                else begin
                  PutPolygon(strMiddleStr,false);
                  end;
            end;
      '2' : begin
              for j:=i to RegionLength do
                if (strRegion[j]=')') and (strRegion[j+1]<>'(')
                  then break;
                   strMiddleStr:=Copy(strRegion,i,j-i+1);
              if (FistRecord)
                then begin
                  PutEllipse(strMiddleStr,true);
                  FistRecord:=false;
                  end
                else begin
                  PutEllipse(strMiddleStr,false);
                  end;
            end;
    end;//case
  end;//for
end;//PutRegion

begin//MakeRgnFile
  AssignFile(f,FileName);
  Rewrite(f);
  //Запись в файл f заголовка процедуры TForm1.FormCreate
  WriteLn(f,'procedure TForm1.FormCreate(Sender: TObject);');

  //Нахождение максимального n и запись в файл f раздела const
  n:=0;
  nn:=0;
  strRegion:=strRegion+'+';
  for i:=1 to Length(strRegion) do
     case strRegion[i] of
       '+', '-' : begin
                    if (nn > n) then begin
                      n:=nn;
                      nn:=0;
                    end;
                  end;
        '('     : begin
                    nn:=nn+1;
                  end;
     end;
  WriteLn(f,'const');
  WriteLn(f,'  n = ',n,';');

  //Запись в файл f раздела var и слова begin
  WriteLn(f,'var');
  WriteLn(f,'  nn : integer;');
  WriteLn(f,'  ResultReg, Reg : HRGN;');
  WriteLn(f,'  P : array[0..n-1] of TPoint;');
  WriteLn(f,'begin');

  PutRegion;

  //Запись в файл f заключительных строк
  WriteLn(f,'  SetWindowRgn(Handle, ResultReg, False);');
  WriteLn(f,'end;');
  CloseFile(f);
end;

function BGColor : TColor;
begin
  Result:=SubColor;
end;

procedure TfmLogoMaker.SetDrawingColor(clColor: TColor);
begin
  Canvas.Pen.Color:=clColor;
  Canvas.Brush.Color:=clColor;
end;


function CurColor : TColor;
begin
  case CurMode of
    mdAdd : Result:=AddColor;
    mdSub : Result:=SubColor;
  end;
end;


procedure TfmLogoMaker.PutLine(x:T4Points);
begin
  Canvas.Polygon(x);
end;

function WideLineToT4Points(x1, y1, x2, y2, d : integer) : T4Points;
var
  k, alpha : single;
  x3, y3, r : integer;
  Res : T4Points;
begin
  r:=round(d/2);
  if (x1=x2) then begin
    //Canvas.Rectangle(x1-r,y1,x2+r,y2);
    Res[0]:=Point(x1-r,y1);
    Res[1]:=Point(x1-r,y2);
    Res[2]:=Point(x1+r,y2);
    Res[3]:=Point(x1+r,y1);
    Result:=Res;
    exit;
  end;
  if (y1=y2) then begin
    //Canvas.Rectangle(x1,y1+r,x2,y2-r);
    Res[0]:=Point(x1,y1-r);
    Res[1]:=Point(x1,y2+r);
    Res[2]:=Point(x2,y2+r);
    Res[3]:=Point(x2,y1-r);
    Result:=Res;
    exit;
  end;
  k:=(x1-x2)/(y2-y1);
  alpha:=arctan(k);
  x3:=x1+round(r*cos(alpha));
  y3:=y1+round(r*sin(alpha));
  Res[0]:=Point(x3,y3);
  Res[1]:=Point(x2-x1+x3,y3+y2-y1);
  Res[2]:=Point(x2+x1-x3,y2-y3+y1);
  Res[3]:=Point(x1+x1-x3,y1-y3+y1);
  Result:=Res;
  {Canvas.Polygon([Point(x3,y3),
                  Point(x2-x1+x3,y3+y2-y1),
                  Point(x2+x1-x3,y2-y3+y1),
                  Point(x1+x1-x3,y1-y3+y1)
                  ]);}
end;


procedure TfmLogoMaker.AppException(Sender: TObject; E: Exception);
begin
  ShowMessage('Извините, LogoMaker глючит');
end;

procedure TfmLogoMaker.CanvasClear;
var
  i, j : integer;
begin
  SetDrawingColor(BGColor);
  Canvas.Rectangle(1, 1, ClientWidth, ClientHeight);
  CurMode:=mdAdd;
end;

function ModeChar : char;
begin
  case CurMode of
    mdAdd : Result:='+';
    mdSub : Result:='-';
  end;
end;

function PointToStr(x,y:integer):string;
begin
  Result:='(' + IntToStr(x) + ',' + IntToStr(y) + ')';
end;

function T4PointsToStr(x:T4Points):string;
begin
  Result:='(' + IntToStr(x[0].x) + ',' + IntToStr(x[0].y) + ')' +
          '(' + IntToStr(x[1].x) + ',' + IntToStr(x[1].y) + ')' +
          '(' + IntToStr(x[2].x) + ',' + IntToStr(x[2].y) + ')' +
          '(' + IntToStr(x[3].x) + ',' + IntToStr(x[3].y) + ')' ;
end;

function PointToEllipse(X,Y,r:integer):string;
begin
  Result:='(' + IntToStr(x-r) + ',' + IntToStr(y-r) + ',' + IntToStr(x+r) + ',' + IntToStr(y+r) + ')';
end;

procedure TfmLogoMaker.PutPolygon(strPolygon:string);
var
  i, j, n, k, m, a, b, num : integer;
  arPoints : array of TPoint;
begin
  if Length(strPolygon)<1 then exit;
  //определяем количеслво точек n многоугольника
  n:=0;
  for num:=1 to Length(strPolygon) do
    if strPolygon[num]='(' then n:=n+1;
  SetLength(arPoints,n);

  //заполняем массив arPoints
  k:=0;
  for i:=2 to Length(strPolygon) do
    case strPolygon[i] of
      '(' : begin
              k:=k+1;
              j:=i+1
            end;
      ',' : begin
              m:=i;
            end;
      ')' : begin
              a:=StrToInt(Copy(strPolygon,j,m-j));
              b:=StrToInt(Copy(strPolygon,m+1,i-m-1));
              arPoints[k-1]:=Point(a,b);
            end;
    end;
  case strPolygon[1] of
    '+' : SetDrawingColor(AddColor);
    '-' : SetDrawingColor(SubColor);
  end;
  Canvas.Polygon(arPoints);
end;

procedure TfmLogoMaker.PutEllipse(strRegion:string);
var
  k, l, m, n, o, x1, y1, x2, y2 : integer;
  Str : string;
begin
  for k:=1 to Length(strRegion) do
    if strRegion[k]='(' then break;

  for l:=k to Length(strRegion) do
    if strRegion[l]=',' then break;

  for m:=l+1 to Length(strRegion) do
    if strRegion[m]=',' then break;

  for n:=m+1 to Length(strRegion) do
    if strRegion[n]=',' then break;

  for o:=n to Length(strRegion) do
    if strRegion[o]=')' then break;

  x1:=StrToInt(Copy(strRegion,k+1,l-k-1));
  y1:=StrToInt(Copy(strRegion,l+1,m-l-1));
  x2:=StrToInt(Copy(strRegion,m+1,n-m-1));
  y2:=StrToInt(Copy(strRegion,n+1,o-n-1));

  case strRegion[1] of
    '+' : SetDrawingColor(AddColor);
    '-' : SetDrawingColor(SubColor);
  end;
  Canvas.Ellipse(x1,y1,x2,y2);
end;

procedure TfmLogoMaker.PutRegion(strRegion:string);
var
  i, j, k, n, RegionLength : integer;
  strMiddleStr : string;
begin
  strRegion:=strRegion+'+';
  RegionLength:=Length(strRegion);
  for i:=1 to RegionLength do begin
    if not(strRegion[i] in ['+','-']) then continue;
    case strRegion[i+1] of
      '1' : begin
              for j:=i to RegionLength do
                if (strRegion[j]=')') and (strRegion[j+1]<>'(')
                  then break;
              strMiddleStr:=Copy(strRegion,i,j-i+1);
              n:=0;
              PutPolygon(strMiddleStr);
            end;
      '2' : begin
              for j:=i to RegionLength do
                if (strRegion[j]=')') and (strRegion[j+1]<>'(')
                  then break;
                   strMiddleStr:=Copy(strRegion,i,j-i+1);
              PutEllipse(strMiddleStr);
            end;
    end;//case
  end;//for
end;

procedure TfmLogoMaker.mnuAboutClick(Sender: TObject);
begin
  fmAbout.ShowModal;
end;

procedure TfmLogoMaker.actNewExecute(Sender: TObject);
var
  strMsg : string;
begin
  if FileModified then begin
    if FileName=''
      then strMsg := 'Save Changes to previous to file ?'
      else strMsg := 'Save Changes to file ' + FileName + '.rgn ?';
    case MessageDlg(strMsg,mtInformation,[mbYes, mbNo, mbCancel],0) of
        mrYes    : actSaveExecute(Self);
        mrCancel : Exit;
    end;//case
  end;//if
  FileName := '';
  strRegion := '';
  FileModified := false;
  FormPaint(Self);
  CurDrawingMode := dmBigPen;
end;

function GetRgnFromFile(FileName:string):string;
var
  f : file of char;
  ch : char;
  Str : string;
begin
  AssignFile(f,FileName);
  Reset(f);
  Str:='';
  while not(EOF(f)) do begin
    Read(f,ch);
    Str:=Str+ch;
  end;
  Result:=Str;
end;

procedure SaveRgnToFile(FileName:string);
var
  f : file of char;
  i : integer;
  ch : char;
  Str : string;
begin
  AssignFile(f,FileName);
  Rewrite(f);
  for i:=1 to Length(strRegion) do write(f,strRegion[i]);
end;

procedure TfmLogoMaker.actOpenExecute(Sender: TObject);
var
  strMsg : string;
begin
  if FileModified then begin
    if FileName=''
      then strMsg := 'Save Changes to previous to file ?'
      else strMsg := 'Save Changes to file ' + FileName + '.rgn ?';
    case MessageDlg(strMsg,mtInformation,[mbYes, mbNo, mbCancel],0) of
        mrYes    : actSaveExecute(Self);
        mrCancel : Exit;
    end;//case
  end;//if

  OpenDialog1.Filter:='Файлы заставок Delphi|*.rgn'+
                      '|Все файлы|*.*';
  if OpenDialog1.Execute and FileExists(OpenDialog1.FileName)
  then begin
    FileName := OpenDialog1.FileName;
    strRegion:=GetRgnFromFile(FileName);
    FormPaint(Self);
    end
  else begin
    MessageDlg('Csn not open file',mtWarning,[mbOk],0);
    end;
  FileModified := false;
  CurDrawingMode := dmBigPen;
end;

procedure TfmLogoMaker.actSaveAsExecute(Sender: TObject);
begin
  SaveDialog1.Filter:='Файлы заставок Delphi|*.rgn';
  if SaveDialog1.Execute then
  begin
    if FileExists(SaveDialog1.FileName) then
      if MessageDlg(Format('Overwrite  %s ?', [SaveDialog1.FileName]),
        mtConfirmation, mbYesNoCancel, 0) <> mrYes then Exit;
    FileName:=SaveDialog1.FileName;
    SaveRgnToFile(FileName);
  end;
end;

procedure TfmLogoMaker.actSaveExecute(Sender: TObject);
begin
  if FileName=''
    then actSaveAsExecute(Self)
    else SaveRgnToFile(FileName);
end;

procedure TfmLogoMaker.actUndoExecute(Sender: TObject);
var
  beg : integer;
begin
  if strRegion='' then exit;
//определяем начало beg последнего региона в strRegion
  for beg:= Length(strRegion) downto 1 do
    if strRegion[beg] in ['+','-'] then break;
  strUndo:=strUndo+Copy(strRegion,beg,Length(strRegion)-beg+1);
//удаляем последнюю запись из strRegion
  Delete(strRegion,beg,Length(strRegion)-beg+1);
//
  FormPaint(Self);
end;

procedure TfmLogoMaker.actRedoExecute(Sender: TObject);
var
  beg : integer;
begin
  if strUndo='' then exit;
//определяем начало beg последнего региона в strUndo
  for beg:= Length(strUndo) downto 1 do
    if strUndo[beg] in ['+','-'] then break;
  strRegion:=strRegion+Copy(strUndo,beg,Length(strUndo)-beg+1);
//удаляем последнюю запись из strRegion
  Delete(strUndo,beg,Length(strUndo)-beg+1);
//
  FormPaint(Self);
end;

procedure TfmLogoMaker.actMakeCodeExecute(Sender: TObject);
begin
  SaveDialog2.Filter:='Файлы Delphi|*.pas'+
                      '|Текстовые файлы |*.txt'+
                      '|Все файлы |*.*';
  if SaveDialog2.Execute then
  begin
    if FileExists(SaveDialog2.FileName) then
      if MessageDlg(Format('Overwrite  %s ?', [SaveDialog2.FileName]),
        mtConfirmation, mbYesNoCancel, 0) <> mrYes then Exit;
    MakeCodeFile(SaveDialog2.FileName,strRegion);
  end;
end;

procedure TfmLogoMaker.actExitExecute(Sender: TObject);
begin
  Halt;
end;

//---------------------------------------------------

procedure TfmLogoMaker.FormCreate(Sender: TObject);
begin
  Application.OnException := AppException;
end;

procedure TfmLogoMaker.actChangeModeExecute(Sender: TObject);
begin
  case CurMode of
  mdAdd : begin
            CurMode:=mdSub;
            actChangeMode.ImageIndex:=26
          end;
  mdSub : begin
            CurMode:=mdAdd;
            actChangeMode.ImageIndex:=25
          end;
  end;
  Canvas.Pen.Color:=CurColor;
  Canvas.Brush.Color:=CurColor;
end;

procedure TfmLogoMaker.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  d, r : integer;
begin
  Drawing:=true;

  SetDrawingColor(CurColor);
  if X<1 then X:=dd;
  if Y<hh+dd then Y:=hh+dd;
  if X>ClientWidth-dd then X:=ClientWidth-dd;
  if Y>ClientHeight-dd then Y:=ClientHeight-dd;

  case CurDrawingMode of
    dmBigPen   : begin
                   d:=SpinEdit1.Value;
                   r:=round(d/2);
                   if X<dd+R then X:=dd+R;
                   if Y<hh+dd+R then Y:=hh+dd+R;
                   if X>ClientWidth-dd-R then X:=ClientWidth-dd-R;
                   if Y>ClientHeight-dd-R then Y:=ClientHeight-dd-R;
                   x1:=X; y1:=Y;
                   strLocalRegion:=ModeChar+'2'+PointToEllipse(X,Y,r);
                   Canvas.Ellipse(X-r,Y-r,X+r,Y+r);
                 end;
    dmBigLine  : begin
                   d:=SpinEdit1.Value;
                   r:=round(d/2);
                   if X<dd+R then X:=dd+R;
                   if Y<hh+dd+R then Y:=hh+dd+R;
                   if X>ClientWidth-dd-R then X:=ClientWidth-dd-R;
                   if Y>ClientHeight-dd-R then Y:=ClientHeight-dd-R;
                   x1:=X; y1:=Y;
                   Canvas.Ellipse(X-r,Y-r,X+r,Y+r);
                 end;
    dmPen      : begin
                   Canvas.MoveTo(X,Y);
                   strLocalRegion:=ModeChar+'1'+PointToStr(X,Y);
                 end;
    dmPolygon  : begin
                 end;
    dmEllipse  : begin
                   x1:=X;
                   y1:=Y;
                 end;
    dmCircle   : begin
                   x1:=X;
                   y1:=Y;
                 end;
  end;
end;

procedure TfmLogoMaker.FormMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  d, r : integer;
  A4Points : T4Points;
begin
  if X<1 then X:=dd;
  if Y<hh+dd then Y:=hh+dd;
  if X>ClientWidth-dd then X:=ClientWidth-dd;
  if Y>ClientHeight-dd then Y:=ClientHeight-dd;
  if Drawing then case CurDrawingMode of
    dmBigPen   : begin
                   d:=SpinEdit1.Value;
                   r:=round(d/2);
                   if X<dd+R then X:=dd+R;
                   if Y<hh+dd+R then Y:=hh+dd+R;
                   if X>ClientWidth-dd-R then X:=ClientWidth-dd-R;
                   if Y>ClientHeight-dd-R then Y:=ClientHeight-dd-R;
                   A4Points:=WideLineToT4Points(x1,y1,X,Y,d);
                   PutLine(A4Points);
                   strLocalRegion:=strLocalRegion+ModeChar+'1'+T4PointsToStr(A4Points);
                   Canvas.Ellipse(X-R,Y-R,X+R,Y+R);
                   strLocalRegion:=strLocalRegion+ModeChar+'2'+PointToEllipse(X,Y,r);
                   x1:=X; y1:=Y;
                 end;
    dmBigLine  : begin
                   d:=SpinEdit1.Value;
                   r:=round(d/2);
                   if X<dd+R then X:=dd+R;
                   if Y<hh+dd+R then Y:=hh+dd+R;
                   if X>ClientWidth-dd-R then X:=ClientWidth-dd-R;
                   if Y>ClientHeight-dd-R then Y:=ClientHeight-dd-R;
                   A4Points:=WideLineToT4Points(x1,y1,X,Y,d);
                   FormPaint(Self);
                   Canvas.Ellipse(X1-R,Y1-R,X1+R,Y1+R);
                   PutLine(A4Points);
                   Canvas.Ellipse(X-R,Y-R,X+R,Y+R);
                 end;
    dmPen      : begin
                   Canvas.LineTo(X,Y);
                   strLocalRegion:=strLocalRegion+PointToStr(X,Y);
                 end;
    dmPolygon  : begin
                 end;
    dmEllipse  : begin
                   FormPaint(Self);
                   Canvas.Ellipse(x1,y1,X,Y);
                 end;
    dmCircle   : begin
                   FormPaint(Self);
                   R:=round(sqrt(sqr(x1-X)+sqr(y1-Y)));
                   Canvas.Ellipse(x1-r,y1-r,x1+r,y1+r);
                 end;
  end;
end;

procedure TfmLogoMaker.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  R, d : integer;
  A4Points : T4Points;
begin
  Drawing:=false;
  case CurDrawingMode of
    dmBigPen   : begin
                   strRegion:=strRegion+strLocalRegion;
                 end;
    dmBigLine  : begin
                   d:=SpinEdit1.Value;
                   r:=round(d/2);
                   A4Points:=WideLineToT4Points(x1,y1,X,Y,d);
                   strLocalRegion:=ModeChar+'2'+PointToEllipse(X1,Y1,r)+
                                   ModeChar+'1'+T4PointsToStr(A4Points)+
                                   ModeChar+'2'+PointToEllipse(X,Y,r);
                   strRegion:=strRegion+strLocalRegion;
                 end;
    dmPen      : begin
                   PutPolygon(strLocalRegion);
                   strRegion:=strRegion+strLocalRegion;
                 end;
    dmPolygon  : begin
                 end;
    dmEllipse  : begin
                   strRegion:=strRegion+ModeChar + '2'+
                       '(' + IntToStr(x1) + ',' +
                             IntToStr(y1) + ',' +
                             IntToStr(X)  + ',' +
                             IntToStr(Y)  + ')';
                 end;
    dmCircle   : begin
                   R:=round(sqrt(sqr(x1-X)+sqr(y1-Y)));
                   strRegion:=strRegion+ModeChar + '2'+
                       '(' + IntToStr(x1-r) + ',' +
                             IntToStr(y1-r) + ',' +
                             IntToStr(x1+r)  + ',' +
                             IntToStr(y1+r)  + ')';
                 end;
  end;
  FileModified:=true;
end;


procedure TfmLogoMaker.ToolButton9Click(Sender: TObject);
begin
  CurDrawingMode:=dmPen;
end;

procedure fmTryClick;// of object;
begin
 ;;;
end;

procedure TfmLogoMaker.FormPaint(Sender: TObject);
var
  i : integer;
begin
  CanvasClear;

  for i:=1 to Length(strRegion) do
     if strRegion[i]='+' then break;
  strRegion:=Copy(strRegion,i,Length(strRegion)-i+1);

  PutRegion(strRegion);
  case actChangeMode.ImageIndex of
    25 : CurMode:=mdSub;
    26 : CurMode:=mdAdd;
  end;
  actChangeModeExecute(Self);
end;

procedure TfmLogoMaker.SpinEdit1Change(Sender: TObject);
begin
  try
    with SpinEdit1 do
      begin
        if Value>MaxValue then Value:=MaxValue;
        if Value<MinValue then Value:=MinValue;
      end;
  except
    SpinEdit1.Value:=SpinEdit1.MinValue;
  end;
end;

procedure TfmLogoMaker.actClearExecute(Sender: TObject);
begin
  strRegion:='';
  strUndo:='';
  CanvasClear;
end;

procedure TfmLogoMaker.ToolButton7Click(Sender: TObject);
begin
  CurDrawingMode:=dmBigPen;
end;

procedure TfmLogoMaker.ToolButton10Click(Sender: TObject);
begin
  CurDrawingMode:=dmPolygon;
end;

procedure TfmLogoMaker.ToolButton11Click(Sender: TObject);
begin
  CurDrawingMode:=dmEllipse;
end;

procedure TfmLogoMaker.ToolButton12Click(Sender: TObject);
begin
  CurDrawingMode:=dmCircle;
end;

procedure TfmLogoMaker.ToolButton20Click(Sender: TObject);
begin
  CurDrawingMode:=dmBigLine;
end;

end.
