{************************************************************}
{                   Delphi VCL Extensions                    }
{                                                            }
{                   CAD Direct Export interface              }
{                                                            }
{      Copyright (c) 2012-2014 SoftGold software company     }
{                                                            }
{************************************************************}

unit CADDirectExport;
{$INCLUDE SGDXF.INC}
interface

uses Windows, SysUtils, Graphics, Classes, CADExport, CADImage, DXFConv, sgConsts,
  ExtData, sgFunction, sgBitmap, Math, ActiveX, sgOle, sgLines
{$IFDEF SG_USEGDIPLUS}
  , GDIPLUS
{$ENDIF}
{$IFDEF SGDEL_XE2}
  , System.Types
{$ENDIF}
  ;

type
  TsgExportOLEEvent = function(AOLE: TsgDXFOle2Frame; Data: TObject): Boolean of object;
  TsgExportWipeoutEvent = function(AWipeout: TsgCADWipeout; Data: TObject): Boolean of object;
  TsgExportImageEntEvent = TsgExportWipeoutEvent;

  TsgConvertToOle = (ctoConvertAllImageToOle, ctoConverOrtoImageToOle);

  PsgDirectExportData = ^TsgDirectExportData;
  TsgDirectExportData = record
    OwnerHandle: UInt64;
    EntMode: Byte;
    PrevEntHandle: UInt64;
    NextEntHandle: UInt64;
    OwnerDWGCode: Word;
    Owner: TsgDXFEntity;
    EntDWGCode: Word;
    UseEntCode: Boolean;
  end;


  TsgCADDirectExport = class(TsgCADExport)
  private
    FPathDir: string;
    FFileName: string;
    FConverImageToOLE: Boolean;
    FImageDefList: TList;
    FCADImage: TsgCADImage;
    FVersion: TsgDWGVersion;
    FXDataAppName: string;
    FDrwPropInfo: TStringList;
    FDrwPropCustomSummaryInfo: TStringList;
    FExportImageFileIndex: Integer;
    FOutFileInfo: Boolean;
    FGroupsToFree: TList;
    function GetDrwHyperlinkBase: string;
    function GetDrwPropAuthor: string;
    function GetDrwPropComments: string;
    function GetDrwPropKeywords: string;
    function GetDrwPropSavedBy: string;
    function GetDrwPropSubject: string;
    function GetDrwPropTitle: string;
    function GetDrwRevisionNumber: string;
    procedure SetDrwHyperlinkBase(const Value: string);
    procedure SetDrwPropAuthor(const Value: string);
    procedure SetDrwPropComments(const Value: string);
    procedure SetDrwPropKeywords(const Value: string);
    procedure SetDrwPropSavedBy(const Value: string);
    procedure SetDrwPropSubject(const Value: string);
    procedure SetDrwPropTitle(const Value: string);
    procedure SetDrwRevisionNumber(const Value: string);
    function GetDrwPropCustomSummaryInfo: TStringList;
  protected
    procedure ApplyBlocksByProc(AProc: TsgApplyBlocksProc; Data: TObject = nil); virtual;
    procedure Clear; virtual;
    function CorrectLineWeight(const ALineWeight: Double; ANeedToConvert: Boolean): Integer; virtual;
    procedure CreateDefaultDrawingProp; virtual;
    function CreateDefaultViewPort(const AHandle: UInt64): TsgDXFViewport;
    function CreateViewPortAsACADWindow(ALayout: TsgDXFLayout;
      AHandle: UInt64 = cnstBadHandle): TsgDXFViewport;
    function CreateDefaultVPort(const Handle: UInt64): TsgDXFVPort;
    function CreateDefaultDimStyle(const Handle: UInt64): TsgDXFDimensionStyle;
    function CreateGroup(const E: TsgDXFEntity): Boolean;
    function DoHandle: UInt64; virtual;
    procedure DoExport(const E: TsgDXFEntity; const Data: PsgDirectExportData = nil;
      const AIsTempObject: Boolean = False); virtual;
    function ExtractName(const AName: string): string;
    function ExportImageEntAsOle(W: TsgDXFImageEnt; ADoOnOLEExport: TsgExportOLEEvent;
      AData: TObject; ADoAssignHandle: Boolean = False): Boolean;
    function ExportImageEntAsExternalFile(W: TsgDXFImageEnt; AHandle: UInt64;
       ADoOnImageEntExport: TsgExportImageEntEvent; AData: TObject): Boolean;
    function ExportGroup(E: TsgDXFEntity; APolyLineDWGCode: Word;
      const AExportData: TsgDirectExportData): Boolean;
    procedure GetCorrectImageVectorData(W: TsgDXFImageEnt;
      var AUVector, AVVector, ASize: TFPoint);
    function GetConverter: TsgDXFConverter; override;
    function GetCorrectBlockName(const AName: string): string; virtual;
    function GetEntityStringValue(ATextEntity: TsgDXFEntity): string;
    function GetModelSpaceName: string; virtual;
    function GetPaperSpaceName: string; virtual;
    function GetPaperLayout: TsgDXFLayout; virtual;
    function GetExtLinMaxMin(ALayout: TsgDXFLayout; AMax, AExt: Boolean): TFPoint;

    function GetExtMax(ALayout: TsgDXFLayout): TFPoint;
    function GetExtMin(ALayout: TsgDXFLayout): TFPoint;
    function GenLTypeDiscriptText(const ALType: TsgDXFLineType; var Len: Double): string;
    function GetLinMax(ALayout: TsgDXFLayout): TFPoint;
    function GetLinMin(ALayout: TsgDXFLayout): TFPoint;
    function GetImageDefHandle(W: TsgCADWipeOut): UInt64;
    function GetRealCountBoundaryPoints(W: TsgCADWipeout): Integer;
    function GetNextEntHandle(Group: TsgDXFEntity; Index: Integer;
      AList: TList = nil): UInt64; virtual;
    function GetPrevEntHandle(Group: TsgDXFEntity; Index: Integer;
      AList: TList = nil): UInt64; virtual;

    procedure InitEntityForExport(const Entity: TsgDXFEntity);
    //GetExportImageIndex returns
    //0 - export as WipeOut
    //1 - export as OLE
    //2 - export as external file
    function GetExportImageIndex(I: TsgDXFImageEnt; AIndex: Integer): Integer;
    function IsNeedAddPointForBoundary(W: TsgCADWipeout): Boolean;
    function IsNeedImageDefHandle(W: TsgCADWipeout): Boolean;

    function IsNameInternal(const AName: string): Boolean;

    procedure PrepareDrawingDatabase; virtual;
    procedure PrepareOLEHeader(OLE2: TsgDXFOle2Frame;
      const POleHeader: PsgOle2FrameHeaderData);
    procedure ProcessExport(Stream: TStream); virtual;
    procedure SaveToStreamCustom(S: TStream); override;
    procedure SetVersion(const Value: TsgDWGVersion); virtual;
    procedure SetOleFrameVariable(const AValue: Integer); virtual;
    property ExportCADImage: TsgCADImage read FCADImage;
    property ExportImageFileIndex: Integer read FExportImageFileIndex;
    property FileName: string read FFileName;
    property ImageDefList: TList read FImageDefList;
    property PathDir: string read FPathDir;
    property OutFileInfo: Boolean read FOutFileInfo write FOutFileInfo;
  public
    constructor Create(ACADImage: TsgCADImage); override;
    destructor Destroy; override;
    procedure ApplyParams(const AExportParams: TsgExportParams); override;
    procedure AddCustomSummaryInfo(const Key, Value: string); virtual;
    procedure DeleteCustomSummaryInfo(const Key: string); virtual;
    property ConverImageToOLE: Boolean read FConverImageToOLE write FConverImageToOLE;
    property DrwPropAuthor: string read GetDrwPropAuthor write SetDrwPropAuthor;
    property DrwPropComments: string read GetDrwPropComments write SetDrwPropComments;
    property DrwPropHyperlinkBase: string read GetDrwHyperlinkBase write SetDrwHyperlinkBase;
    property DrwPropKeywords: string read GetDrwPropKeywords write SetDrwPropKeywords;
    property DrwPropRevisionNumber: string read GetDrwRevisionNumber write SetDrwRevisionNumber;
    property DrwPropSavedBy: string read GetDrwPropSavedBy write SetDrwPropSavedBy;
    property DrwPropSubject: string read GetDrwPropSubject write SetDrwPropSubject;
    property DrwPropTitle: string read GetDrwPropTitle write SetDrwPropTitle;
    property DrwPropCustomSummaryInfo: TStringList read GetDrwPropCustomSummaryInfo;
    property Version: TsgDWGVersion read FVersion write SetVersion;
    property XDataAppName: string read FXDataAppName write FXDataAppName;
  end;

  TsgDXFImageDefExport = class(TsgDXFImageDef)
  private
    FImageEnt: TsgDXFImageEnt;
    FImageSize: TFPoint;
  public
    constructor Create; override;
    destructor Destroy; override;
    property ImageEnt: TsgDXFImageEnt read FImageEnt write FImageEnt;
    property ImageSize: TFPoint read FImageSize write FImageSize;
  end;

  TsgDWGExportDataClass = class
  private
    FBits: TObject;
    FExportData: TsgDirectExportData;
    FOwnerObject: TObject;
    FGroup: TObject;
    FGroupIndex: Integer;
    function GetPExportData: PsgDirectExportData;
  public
    constructor Create;
    constructor CreateEx(const ABits, AOwnerObject, AGroup: TObject;
      AExportData: TsgDirectExportData);
    property Bits: TObject read FBits write FBits;
    property ExportData: TsgDirectExportData read FExportData write FExportData;
    property Group: TObject read FGroup write FGroup;
    property GroupIndex: Integer read FGroupIndex write FGroupIndex;
    property OwnerObject: TObject read FOwnerObject write FOwnerObject;
    property PExportData: PsgDirectExportData read GetPExportData;
  end;

   TsgCADDirectExportClass = class of TsgCADDirectExport;

function CreateExportData(OwnerHandle: UInt64 = cnstBadHandle; EntMode: Byte = 2;
  PrevEntHandle: UInt64 = cnstBadHandle; NextEntHandle: UInt64 = cnstBadHandle;
  OwnerDWGCode: Word = cntDWGObjCodeUNSUSED; Owner: TsgDXFEntity = nil;
  EntDWGCode: Word = cntDWGObjCodeUNSUSED): TsgDirectExportData;

function ConvertImageEntToOle(const AImageEnt: TsgDXFImageEnt;
  const AExportCADImage: TsgCADImage;
  const ADoOnOLEExport: TsgExportOLEEvent; const AData: TObject;
  const ADoAssignHandle: Boolean; const AOleList: TList): Boolean;

implementation

type
  TsgDXFEntityEx = class(TsgDXFEntity);
  TsgDXFConverterAccess = class(TsgDXFConverter);
  TsgCADImageAccess = class(TsgCADImage);
  TsgBitmapAccess = class(TsgBitmap);
  TsgDXFImageEntAccess = class(TsgDXFImageEnt);

const
  cnstDefExportData: TsgDirectExportData = (OwnerHandle: cnstBadHandle; EntMode: 2;
    PrevEntHandle: cnstBadHandle; NextEntHandle: cnstBadHandle; OwnerDWGCode: cntDWGObjCodeUNSUSED;
    Owner: nil; EntDWGCode: cntDWGObjCodeUNSUSED);

function CreateExportData(OwnerHandle: UInt64 = cnstBadHandle; EntMode: Byte = 2;
  PrevEntHandle: UInt64 = cnstBadHandle; NextEntHandle: UInt64 = cnstBadHandle;
  OwnerDWGCode: Word = cntDWGObjCodeUNSUSED; Owner: TsgDXFEntity = nil;
  EntDWGCode: Word = cntDWGObjCodeUNSUSED): TsgDirectExportData;
begin
  Result := cnstDefExportData;
  Result.OwnerHandle := OwnerHandle;
  Result.EntMode := EntMode;
  Result.PrevEntHandle := PrevEntHandle;
  Result.NextEntHandle := NextEntHandle;
  Result.OwnerDWGCode := OwnerDWGCode;
  Result.Owner := Owner;
  Result.EntDWGCode := EntDWGCode;
  Result.UseEntCode := False;
end;

function CreateBitmapGDIPlus(const AImageEnt: TsgDXFImageEnt): TBitmap;
{$IFDEF SG_USEGDIPLUS}
var
  vDestRect: TsgGRect;
  vGraphics: TsgGDIPlusGraphics;
  vAttr: TsgGDIPlusImageAttributes;
  vTransparentColor: Cardinal;
{$ENDIF}
begin
  Result := nil;
{$IFDEF SG_USEGDIPLUS}
  if not (TsgDXFImageEntAccess(AImageEnt).Picture.Graphic is TMetafile) then
  begin
    if TsgDXFImageEntAccess(AImageEnt).FGDIPImage = nil then
      TsgDXFImageEntAccess(AImageEnt).GDIPCreate;
    if TsgDXFImageEntAccess(AImageEnt).FGDIPImage <> nil then
    begin
      Result := TBitmap.Create;
      Result.Width := TsgDXFImageEntAccess(AImageEnt).Picture.Graphic.Width;
      Result.Height := TsgDXFImageEntAccess(AImageEnt).Picture.Graphic.Height;
      Result.Canvas.Brush.Color := clWhite;
      Result.Canvas.FillRect(Rect(0,0,
        Result.Width,Result.Height));

      vDestRect.X := 0;
      vDestRect.Y := 0;
      vDestRect.Width := Result.Width;
      vDestRect.Height :=  Result.Height;

      vGraphics := TsgGDIPlusGraphics.Create(Result.Canvas.Handle);
      try
        vGraphics.InitParams;
        try
          if (TsgDXFImageEntAccess(AImageEnt).Picture.Graphic is TsgBitMap) and (TsgDXFImageEntAccess(AImageEnt).Transparency
            or (TsgBitmapAccess(TsgDXFImageEntAccess(AImageEnt).Picture.Graphic).FROP <> SRCCOPY)) then
          begin
            vAttr := TsgGDIPlusImageAttributes.Create;
            try
              vTransparentColor := ColorRefToARGB(TsgDXFImageEntAccess(AImageEnt).TransparentColor);
              vAttr.SetColorKey(vTransparentColor, vTransparentColor,
                ColorAdjustTypeBitmap);
              if vGraphics.DrawImage(TsgDXFImageEntAccess(AImageEnt).FGDIPImage,
                   vDestRect, 0, 0, vDestRect.Width, vDestRect.Height, vAttr) = OutOfMemory then
                FreeAndNil(Result);
            finally
              vAttr.Free;
            end;
          end
          else
            if vGraphics.DrawImage( TsgDXFImageEntAccess(AImageEnt).FGDIPImage, vDestRect) = OutOfMemory then
              FreeAndNil(Result);
        except
          FreeAndNil(Result);
        end;
      finally
        vGraphics.Free;
      end;
    end;
  end;
{$ENDIF}
end;

function ConvertImageEntToOle(const AImageEnt: TsgDXFImageEnt;
  const AExportCADImage: TsgCADImage;
  const ADoOnOLEExport: TsgExportOLEEvent; const AData: TObject;
  const ADoAssignHandle: Boolean; const AOleList: TList): Boolean;
var
  W: TsgDXFImageEntAccess absolute AImageEnt;
  vOle: TsgDXFOle2Frame;
  vAngle, vAngleY: Double;
  R: Integer;
  vBitmap: TsgBitmapAccess;
  vBitmapBig, vBitmapSmall: TBitmap;
  I, J: Integer;
  vRect: TRect;
  vMetafile: TMetafile;
  vMetafileCanvas: TMetafileCanvas;
  vChunk, vDst: TPoint;
  vROP: Integer;
  vImageHeight, vImageWidth: TFPoint;
  vCountParts: TPoint;
  vDpi: TFPoint;
  vSingX, vSingY: Integer;
  vR: TFRect;
  vFormat: TClipFormat;
  vGr: TGraphic;
  vPictureUpdate: Boolean;
  vBitmapGDIPlus: TBitmap;

  procedure ExportOle(const AGraphic: TGraphic; const AFormat: TClipFormat;
    ASmall, ABitmapSmall: TPoint;
    ADpi: TFPoint; ACol, ARow: Integer);
  var
    vTempPoint, vTempPoint1: TFPoint;
    vIndex: Integer;
    vDWGData: TsgDWGExportDataClass;
  begin
    vOle := TsgDXFOle2Frame.Create;
    try
      vOle.AssignEntity(W);
      if (AData <> nil) and (AData is TsgDWGExportDataClass) then
        vDWGData := TsgDWGExportDataClass(AData)
      else
        vDWGData := nil;
      if ADoAssignHandle then
      begin
        if vDWGData <> nil then
          vIndex := vDWGData.FGroupIndex
        else
          vIndex := 0;
        if W.GroupExists then
          vOle.Handle := W.Group[vIndex].Handle
        else
          vOle.Handle := W.Handle;
      end;
      vOle.Aspect := DVASPECT_CONTENT;
      vOle.BinaryData := CreateSTGMFromImage(AGraphic, AFormat);

      vTempPoint := vR.TopLeft;

      vTempPoint.X := vTempPoint.X + ACol * ASmall.X * ADpi.X;
      vTempPoint.Y := vTempPoint.Y - (ARow * ASmall.Y + ABitmapSmall.Y) * ADpi.Y;

      vTempPoint1.X := vTempPoint.X + ABitmapSmall.X * ADpi.X;
      vTempPoint1.Y := vTempPoint.Y + ABitmapSmall.Y * ADpi.Y;

      vOle.Point := vTempPoint;
      vOle.Point1 := vTempPoint1;

      if Assigned(ADoOnOLEExport) then
        Result := ADoOnOLEExport(vOle, AData);
      if vDWGData <> nil then
        Inc(vDWGData.FGroupIndex);
    finally
      if Assigned(AOleList) then
        AOleList.Add(vOle)
      else
        vOle.Free;
    end;
  end;

begin
  Result := True;
  vPictureUpdate := W.PictureUpdate(AExportCADImage);
{$IFDEF SG_USEGDIPLUS}
    vBitmapGDIPlus := nil;
{$ENDIF}
  try
    if W.Picture = nil then
      Exit;

    vBitmapGDIPlus := CreateBitmapGDIPlus(W);
    if Assigned(vBitmapGDIPlus) then
      vGr := vBitmapGDIPlus
    else
      vGr := W.Picture.Graphic;

    vImageWidth := SubFPoint(W.Point1, W.Point);
    vImageHeight := SubFPoint(W.Point2, W.Point);

    vAngle := GetAngleByPoints(W.Point, W.Point1,
      False, fDoubleResolution ,1, 1);
    vAngleY :=  GetAngleByPoints(W.Point, W.Point2,
      False, fDoubleResolution, 1, 1);

    if sgIsZero(vAngle - 0) then
      vAngle := 0;
    if sgIsZero(vAngleY - 90) then
      vAngleY := 90;

    vR := MakeFRectByPoints( W.Point, W.Point);
    ExpandFRect(vR, W.Point1);
    ExpandFRect(vR, W.Point2);
    ExpandFRect(vR, W.Point3);

    vSingX := 1;
    vSingY := 1;

    vDpi := MakeFPoint(vSingX * (DistanceFVector(vImageWidth) / vGr.Width),
      vSingY * (DistanceFVector(vImageHeight) / vGr.Height));

    if vGr is TMetafile then
    begin
      vFormat := CF_ENHMETAFILE;
      if CheckExportOLEAsMetafile(TMetafile(vGr).Handle) then
      begin
        vChunk := Point(vGr.Width, vGr.Height);
        ExportOle(vGr, vFormat, vChunk, vChunk, vDpi, 0, 0);
        Exit;
      end;
    end
    else
      if (vGr.ClassType = TBitmap) or (vGr is TsgBitmap) then
        vFormat := CF_BITMAP
      else
        vFormat := CF_METAFILEPICT;

    vBitmap := TsgBitmapAccess(TsgBitmap.Create);
    try
      vBitmap.Assign(vGr);
      if IsEqual((Round(vAngle) div 90) * 90, vAngle) then
      begin
        if (vAngle = 0) and (vAngleY = 90) then
        begin
        end
        else
        begin
          R := (Round(vAngle) div 90) * 90;
          if R <> 0 then
          begin
            vBitmap.Rotate(360-R);
          end;
        end;
      end;

      vBitmapBig := TBitmap.Create;
      try
        vBitmapBig.PixelFormat := vBitmap.PixelFormat;
        SetSizeGraphic(vBitmapBig, vBitmap);
        vROP := vBitmap.FROP;
        try
          vBitmap.FROP := SRCCOPY;
          vBitmapBig.Canvas.StretchDraw(vBitmapBig.Canvas.ClipRect, vBitmap);
          if vFormat in [CF_ENHMETAFILE, CF_METAFILEPICT] then
          begin
            vDpi := MakeFPoint(vSingX * (DistanceFVector(vImageWidth) / vBitmapBig.Width),
              vSingY * (DistanceFVector(vImageHeight) / vBitmapBig.Height));
          end;
        finally
          vBitmap.FROP := vROP;
        end;

        vBitmapSmall := TBitmap.Create;
        try
          Result := True;
          vBitmapSmall.PixelFormat := vBitmapBig.PixelFormat;

          vCountParts := GetCountBlocksForOLEExport(vBitmapBig.Width, vBitmapBig.Height,
            vBitmapBig.PixelFormat, vChunk);

          for I := 0 to vCountParts.X do
            for J := 0 to vCountParts.Y do
            begin
              vRect.Left := I * vChunk.X;
              vRect.Top := J * vChunk.Y;
              vRect.Right := vRect.Left + vChunk.X;
              vRect.Bottom := vRect.Top + vChunk.Y;
              if I = vCountParts.X then
                vRect.Right := vRect.Left + vBitmapBig.Width - I * vChunk.X;
              if J = vCountParts.Y then
                vRect.Bottom := vRect.Top + vBitmapBig.Height - J * vChunk.Y;

              vDst.X := vRect.Right - vRect.Left;
              vDst.Y := vRect.Bottom - vRect.Top;
              SetSizeGraphic(vBitmapSmall, vDst.X, vDst.Y);
              BitBlt(vBitmapSmall.Canvas.Handle, 0, 0, vDst.X, vDst.Y,
                vBitmapBig.Canvas.Handle, vRect.Left, vRect.Top, SRCCOPY);
              if vFormat in [CF_ENHMETAFILE, CF_METAFILEPICT] then
              begin
                vMetafile := TMetafile.Create;
                try
                  SetSizeGraphic(vMetafile, vDst.X, vDst.Y);
                  vMetafileCanvas := TMetafileCanvas.Create(vMetafile, 0);
                  try
                    BitBlt(vMetafileCanvas.Handle, 0, 0, vDst.X, vDst.Y,
                      vBitmapSmall.Canvas.Handle, 0, 0, vROP);
                  finally
                    vMetafileCanvas.Free;
                  end;
                  ExportOle(vMetafile, vFormat, vChunk, vDst, vDpi, I, J);
                finally
                  vMetafile.Free;
                end;
              end
              else
                ExportOle(vBitmapSmall, vFormat, vChunk, vDst, vDpi, I, J);
            end;
        finally
          vBitmapSmall.Free;
        end;
      finally
        vBitmapBig.Free;
      end;
    finally
      vBitmap.Free;
    end;
  finally
    if vPictureUpdate then
      W.PictureUpdate(nil);
    if Assigned(vBitmapGDIPlus) then
      vBitmapGDIPlus.Free;
  end;
end;

{ TsgCADDirectExport }

procedure TsgCADDirectExport.AddCustomSummaryInfo(const Key, Value: string);
begin
  if (Key <> '') and (Value <> '') and (FDrwPropCustomSummaryInfo.Count < 10) then
    FDrwPropCustomSummaryInfo.Values[Key] := Value;
end;

procedure TsgCADDirectExport.ApplyBlocksByProc(AProc: TsgApplyBlocksProc;
  Data: TObject = nil);
var
  I: Integer;
  vBlock: TsgDXFBlock;
  vName, vNameUC: string;
begin
  for I := 0 to Converter.Counts[csBlocks] - 1 do
  begin
    vBlock := Converter.Blocks[I];
    if vBlock.Layout = nil then
    begin
      vName := GetCorrectBlockName(vBlock.Name);
      vNameUC := AnsiUpperCase(vName);//for quick names comparing
      if (vNameUC <> GetModelSpaceName) and (vNameUC <> GetPaperSpaceName) and
        (not IsNameInternal(vNameUC)) then
      begin
        if vName = '' then
          vName := IntToStr(TsgNativeUInt(vBlock));
        if not Assigned(FSGBlock) or (vNameUC <> AnsiUpperCase(FSGBlock.Name)) then
          AProc(vBlock, vName, Data, -1);
      end;
    end;
  end;
  if Assigned(FSGBlock) then
    AProc(FSGBlock, FSGBlock.Name, Data);
  for I := 1 to Converter.LayoutsCount - 1 do
    if ExportCADImage.Layouts[I] <> GetPaperLayout then
      AProc(ExportCADImage.Layouts[I].PaperSpaceBlock, sPaperSpace + IntToStr(I), Data, I);
end;

procedure TsgCADDirectExport.ApplyParams(const AExportParams: TsgExportParams);
begin
  inherited ApplyParams(AExportParams);
  Version := TsgDWGVersion(AExportParams.Version);
  DrwPropTitle := AExportParams.Title;
  DrwPropAuthor := AExportParams.Author;
  DrwPropKeywords := AExportParams.Keywords;
  DrwPropSubject := AExportParams.Subjct;
end;

procedure TsgCADDirectExport.Clear;
var
  I: Integer;
begin
  ClearList(FImageDefList);
  FImageDefList.Clear;
  FExportImageFileIndex := 1;
  for I := 0 to FGroupsToFree.Count - 1 do
    TsgDXFEntityEx(FGroupsToFree[I]).GroupClear;
  FGroupsToFree.Clear;
end;

function TsgCADDirectExport.CorrectLineWeight(const ALineWeight: Double;
  ANeedToConvert: Boolean): Integer;
begin
  Result := 5;
end;

constructor TsgCADDirectExport.Create(ACADImage: TsgCADImage);
begin
  inherited Create(ACADImage);
  FCADImage := ACADImage;
  FImageDefList := TList.Create;
  FOutFileInfo := True;
  FConverImageToOLE := True;
  FVersion := acR2000;
  FDrwPropInfo := TStringList.Create;
  FDrwPropCustomSummaryInfo := TStringList.Create;
  FGroupsToFree := TList.Create;
  PrepareDrawingDatabase;
end;

function TsgCADDirectExport.CreateDefaultDimStyle(const Handle: UInt64): TsgDXFDimensionStyle;
var
  vHeadVar: TsgHeadVarStruct;
begin
  Result := TsgDXFDimensionStyle.Create;
  vHeadVar := Converter.HeadVarStruct;
  Result.InitProps(@vHeadVar);
  Result.Handle := Handle;
  Result.DIMTIH := True;
  Result.DIMTOH := True;
  Result.DIMSE1 := False;
  Result.DIMSE2 := False;
  Result.SizeCenterMark := 0;
  Result.DIMSD1 := False;
  Result.DIMSD2 := False;
  Result.TextStyle := Converter.StyleByName(vHeadVar.TextStyle);//!!!
end;

procedure TsgCADDirectExport.CreateDefaultDrawingProp;
begin
  FDrwPropInfo.Clear;
  FDrwPropCustomSummaryInfo.Clear;
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropTitle)] := 'CADSoftTools';
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropSubject)] := '';
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropAuthor)] := '';
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropComments)] := sExporterAuthorInfo;
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropKeywords)] := '';
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropLastSavedBy)] := TsgCADImageAccess(ExportCADImage).FileInfo;
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropRevisionNumber)] := '';
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropHyperlinkBase)] := '';
end;

function TsgCADDirectExport.CreateDefaultViewPort(const AHandle: UInt64): TsgDXFViewport;
begin
  Result := TsgCADImageAccess(ExportCADImage).CreateDefaultViewPort(AHandle);
end;


function TsgCADDirectExport.CreateDefaultVPort(const Handle: UInt64): TsgDXFVPort;
begin
  Result := TsgCADImageAccess(ExportCADImage).CreateDefaultVPort(Handle);
end;

function TsgCADDirectExport.CreateGroup(const E: TsgDXFEntity): Boolean;
var
  vEnt: TsgDXFEntityEx;
begin
  Result := False;
  vEnt := TsgDXFEntityEx(E);
  if vEnt = nil then Exit;
  InitEntityForExport(E);
  if vEnt.Group = nil then
  begin
    Result := vEnt.GroupCreate(Converter);
    if Result then
      FGroupsToFree.Add(vEnt);
  end
  else
    Result := vEnt.Group.Count > 0;
end;

function TsgCADDirectExport.CreateViewPortAsACADWindow(ALayout: TsgDXFLayout;
  AHandle: UInt64): TsgDXFViewport;
var
  vBox: TFRect;
begin
  Result := TsgDXFViewPort.Create;
  Result.Handle := AHandle;
  vBox := ALayout.Box;
  Result.PSpaceCenter := MakeFPoint(0.5 * (vBox.Right + vBox.Left), 0.5 * (vBox.Top + vBox.Bottom), 0);
  Result.PSpaceWidth := vBox.Right - vBox.Left;
  Result.PSpaceHeight := vBox.Top - vBox.Bottom;
  Result.StatusField := 1;
  Result.ThisID := 1;
  Result.MSpaceCenter := Result.PSpaceCenter;
  Result.ViewDirection := MakeFPoint(0, 0, 1);
  Result.ViewTarget := cnstFPointZero;
  Result.Flags := 32800;
  Result.FrontClipPlane := 0;
  Result.BackClipPlane := 0;
  Result.MSpaceHeight := Result.PSpaceHeight;
  Result.ViewTwistAngle := 0;
end;

procedure TsgCADDirectExport.DeleteCustomSummaryInfo(const Key: string);
begin
  FDrwPropCustomSummaryInfo.Values[Key] := '';
end;

destructor TsgCADDirectExport.Destroy;
begin
  ClearList(FImageDefList);
  FImageDefList.Free;
  FDrwPropInfo.Free;
  FDrwPropCustomSummaryInfo.Free;
  FGroupsToFree.Free;
  inherited Destroy;
end;

procedure TsgCADDirectExport.DoExport(const E: TsgDXFEntity;
  const Data: PsgDirectExportData; const AIsTempObject: Boolean);
begin

end;

function TsgCADDirectExport.DoHandle: UInt64;
begin
  Result := cnstBadHandle;
  TsgDXFConverterAccess(Converter).CheckHandle(Result);
end;

function TsgCADDirectExport.ExportGroup(E: TsgDXFEntity; APolyLineDWGCode: Word;
  const AExportData: TsgDirectExportData): Boolean;
var
  vPrevEntHandle, vNextEntHandle, vNextEntHandleSaved: UInt64;
  I, J: Integer;
  vGroup: TsgDXFGroup;
  vExportData: TsgDirectExportData;
  vIsACIS: Boolean;
  vVertex: TsgDXFVertex;
  vDXFPolyline: TsgDXFPolyline;
  vBasePolyLine: TsgCADBasePolyline;
  vExpEnt: TsgDXFEntity;
begin
  Result := False;
  if E = nil then Exit;
  try
    CreateGroup(E);
    vGroup := TsgDXFEntityEx(E).Group;
    DoError(vGroup = nil, sGroupIsNotSupported);
    vIsACIS := E is TsgBrepEntity;
    vNextEntHandleSaved := AExportData.NextEntHandle;
    for I := 0 to vGroup.Count - 1 do
    begin
      if I = 0 then
        vPrevEntHandle := AExportData.PrevEntHandle
      else
        vPrevEntHandle := GetPrevEntHandle(vGroup, I);
      if I < vGroup.Count - 1 then
        vNextEntHandle := GetNextEntHandle(vGroup, I)
      else
        vNextEntHandle := vNextEntHandleSaved;
      vExportData := CreateExportData(AExportData.OwnerHandle, AExportData.EntMode,
        vPrevEntHandle, vNextEntHandle, AExportData.OwnerDWGCode, AExportData.Owner,
        AExportData.EntDWGCode);
      vDXFPolyline := nil;
      vExpEnt := vGroup.Entities[I];
      if vIsACIS and (vExpEnt.EntType in [ceArc, ceCircle, ceEllipse]) then //convert ACIS ACR CIRCILE ELLIPSE to Polyline
      begin
        vExportData.EntDWGCode := APolyLineDWGCode;//cntDWGObjCodePOLYLINE3D;
        vExportData.UseEntCode := True;
        vBasePolyLine := TsgCADBasePolyline(vExpEnt);
        vDXFPolyline := TsgDXFPolyline.Create;
        vDXFPolyline.AssignEntity(vBasePolyLine);
        vDXFPolyline.Clear(True);
        vDXFPolyline.Handle := vBasePolyLine.Handle;
        vDXFPolyline.Point := cnstFPointZero;
        vDXFPolyline.ZThick := vBasePolyLine.ZThick;
        vDXFPolyline.Polyline3D := True;
        vDXFPolyline.Extrusion := cnstExtrusion;
        for J := 0 to vBasePolyLine.PolyPoints.Count - 1 do
        begin
          vVertex := TsgDXFVertex.Create;
          vVertex.Flags := 32;
          vVertex.Point := vBasePolyLine.PolyPoints[J];
          vVertex.Handle := DoHandle;
          vDXFPolyline.AddEntity(vVertex);
        end;
        vDXFPolyline.Closed := IsEqualFPoints(vBasePolyLine.PolyPoints[0],
          vBasePolyLine.PolyPoints[vBasePolyLine.PolyPoints.Count - 1]);
        vExpEnt := vDXFPolyline;
      end;
      DoExport(vExpEnt, @vExportData, vExpEnt = vDXFPolyline);
      vDXFPolyline.Free;
    end;
    Result := vGroup.Count > 0;
  finally
    TsgDXFEntityEx(E).GroupClear;
  end;
end;

function TsgCADDirectExport.ExportImageEntAsExternalFile(W: TsgDXFImageEnt;
  AHandle: UInt64; ADoOnImageEntExport: TsgExportImageEntEvent;
  AData: TObject): Boolean;
const
  cnstExtSupportAutoCAD: array [0..8] of string =
    ('.BMP', '.PNG', '.JPG', '.TIF', '.JPEG', '.GIF', '.PCX', '.EMF', '.WMF');
var
  vImgDef: TsgDXFImageDefExport;
  vFileNameImage: string;
  vDir, vPathDir, vExt: string;
  vImageSize: TFPoint;
begin
  Result := False;
  if (W.Picture = nil) or (W.Picture.Graphic = nil) then     //!!! Exception.Create
    Exit;
  //Save Image
  Inc(FExportImageFileIndex);
  vFileNameImage := FileName + '_' + IntToStr(FExportImageFileIndex);
  vPathDir := PathDir;
  if (vPathDir <> '') and (vPathDir[Length(vPathDir)] = '\') then
    Delete(vPathDir, Length(vPathDir), 1);
  vDir := vPathDir + '\' + FileName;
  if not DirectoryExists(vDir) then
  begin
    try
      Result := CreateDir(vDir);
    except
      Exit;
    end;
  end;
  try
    if (W.Picture.Graphic.ClassType = TBitmap) or
       (W.Picture.Graphic is TsgBitmap) then
    begin
      vExt := '.BMP';
    end
    else
    begin
      vExt := GraphicExtension(TGraphicClass(W.Picture.Graphic.ClassType));
      if (Length(vExt) > 0) and (vExt[1] <> '.') then
        vExt := '.' + vExt;
    end;
    if Length(vExt) = 0 then
      Exit;
    if StrIndex(UpperCase(vExt), cnstExtSupportAutoCAD) > High(cnstExtSupportAutoCAD) then
    begin
      // Conver to support format.
      Exit;
    end;

    vFileNameImage := vFileNameImage+vExt;
    vImageSize := MakeFPoint(W.Picture.Width, W.Picture.Height, 0);
    W.Picture.SaveToFile(vDir + '\' + vFileNameImage);
  except
    Exit;
  end;
  vImgDef := TsgDXFImageDefExport.Create;
  try
    vImgDef.FileName := '.\' + FileName + '\' + vFileNameImage;
    vImgDef.Handle := AHandle;
    vImgDef.ImageEnt := W;
    vImgDef.ImageSize := vImageSize;
    TsgDXFImageEntAccess(W).ImageDefExport := vImgDef;
    if Assigned(ADoOnImageEntExport) then
      Result := ADoOnImageEntExport(W, AData);
  finally
    if Result = True then
      ImageDefList.Add(vImgDef)
    else
      vImgDef.Free;
  end;
end;

function TsgCADDirectExport.ExportImageEntAsOle(W: TsgDXFImageEnt;
  ADoOnOLEExport: TsgExportOLEEvent; AData: TObject;
  ADoAssignHandle: Boolean): Boolean;
begin
  Result := True;
  if ConvertImageEntToOle(W, ExportCADImage, ADoOnOLEExport, AData,
     ADoAssignHandle, nil) then
    SetOleFrameVariable(0);
end;

function TsgCADDirectExport.ExtractName(const AName: string): string;
const
  cnstSharp = '#';
  cnstSpace = ' ';
  cnstAsk = '?';
begin
  Result := AName;
  if Ord(Version) <= Ord(acR14) then
  begin
    if AnsiPos(cnstSharp, Result) > 0 then
      ReplaceAnsi(Result, cnstSharp, '_');
    if AnsiPos(cnstSpace, Result) > 0 then
      ReplaceAnsi(Result, cnstSpace, '_');
  end;
  if AnsiPos(cnstAsk, Result) > 0 then
    ReplaceAnsi(Result, cnstAsk, '_');
end;

function TsgCADDirectExport.GenLTypeDiscriptText(const ALType: TsgDXFLineType;
  var Len: Double): string;
var
  I, vCount: Integer;
  vThick: Double;
  vElement: TsgLTypeElement;

begin
  vCount := ALType.Lines.ElementsCount;
  Len := 0;
  Result := '';
  for I := 0 to vCount - 1 do
  begin
    vElement := ALType.Lines.Elements[I]^;
    vThick := vElement.Dash;
    Len := Len + Abs(vThick);
    if vThick > 0 then
      Result := Result + '_'
    else
      if vThick = 0 then
        Result := Result + '.'
      else
        Result := Result + ' ';
  end;
end;

procedure TsgCADDirectExport.GetCorrectImageVectorData(W: TsgDXFImageEnt;
      var AUVector, AVVector, ASize: TFPoint);
var
  vPointCalc: TFPoint;
begin
  if IsNeedImageDefHandle(W) and Assigned(TsgDXFImageEntAccess(W).ImageDefExport) then
  begin
    ASize := TsgDXFImageDefExport(TsgDXFImageEntAccess(W).ImageDefExport).ImageSize;
    vPointCalc := MultiplyFPoint(W.UVector, W.Size);
    AUVector := MakeFPoint(vPointCalc.X/ASize.X,
      vPointCalc.Y/ASize.X, vPointCalc.Z/ASize.X);
    vPointCalc := MultiplyFPoint(W.VVector, W.Size);
    AVVector :=  MakeFPoint(vPointCalc.X/ASize.Y,
      vPointCalc.Y/ASize.Y, vPointCalc.Z/ASize.Y);
  end
  else
  begin
    AUVector := W.UVector;
    AVVector := W.VVector;
    ASize := W.Size;
  end;
end;

function TsgCADDirectExport.GetConverter: TsgDXFConverter;
begin
  Result := FCADImage.Converter;
end;

function TsgCADDirectExport.GetCorrectBlockName(const AName: string): string;
var
  vPos: Integer;
begin
  vPos := AnsiPos(sInternalDimension, AName);
  if vPos = 0 then
    Result := AName
  else
    Result := sInternalDimension + '0' + Copy(AName, vPos + Length(sInternalDimension), MaxInt);
end;

function TsgCADDirectExport.GetDrwHyperlinkBase: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropHyperlinkBase)];
end;

function TsgCADDirectExport.GetDrwPropAuthor: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropAuthor)];
end;

function TsgCADDirectExport.GetDrwPropComments: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropComments)];
end;

function TsgCADDirectExport.GetDrwPropCustomSummaryInfo: TStringList;
begin
  Result := FDrwPropCustomSummaryInfo;
end;

function TsgCADDirectExport.GetDrwPropKeywords: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropKeywords)];
end;

function TsgCADDirectExport.GetDrwPropSavedBy: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropLastSavedBy)];
end;

function TsgCADDirectExport.GetDrwPropSubject: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropSubject)];
end;

function TsgCADDirectExport.GetDrwPropTitle: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropTitle)];
end;

function TsgCADDirectExport.GetDrwRevisionNumber: string;
begin
  Result := FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropRevisionNumber)];
end;

function TsgCADDirectExport.GetEntityStringValue(ATextEntity: TsgDXFEntity): string;
begin
   case ATextEntity.EntType of
    ceAttdef, ceAttrib:
      Result := TsgDXFAttdef(ATextEntity).Value;
    ceText:
      Result := TsgDXFText(ATextEntity).Text;
    ceMText:
      Result := TsgDXFMText(ATextEntity).Text;
    else
      Result := '';
  end;
end;

function TsgCADDirectExport.GetExportImageIndex(I: TsgDXFImageEnt;
  AIndex: Integer): Integer;
begin
  Result := DXFConv.GetExportImageIndex(I, AIndex, FConverImageToOLE);
end;

function TsgCADDirectExport.GetExtLinMaxMin(ALayout: TsgDXFLayout; AMax,
  AExt: Boolean): TFPoint;
var
  vRect: TFRect;
begin
  Result := cnstFPointZero;
  if ALayout = nil then Exit;
  if ALayout.IsModel then
  begin
    vRect := GetRealBox(ExportCADImage.Extents{ ALayout.Box},
      TsgCADImageAccess(ExportCADImage).GetRealImageMatrix);
    if AExt then
    begin
      if AMax then
        Result := vRect.TopLeft
      else
        Result := vRect.BottomRight;
    end;
      if AMax then
        Result := ALayout.LinMax
      else
        Result := ALayout.LinMin;
  end
  else
  begin
    if AExt then
    begin
      if AMax then
        Result := ALayout.ExtMax
      else
        Result := ALayout.ExtMin;
    end;
      if AMax then
        Result := ALayout.LinMax
      else
        Result := ALayout.LinMin;
  end;
end;

function TsgCADDirectExport.GetExtMax(ALayout: TsgDXFLayout): TFPoint;
begin
  Result := GetExtLinMaxMin(ALayout, True, True);
end;

function TsgCADDirectExport.GetExtMin(ALayout: TsgDXFLayout): TFPoint;
begin
  Result := GetExtLinMaxMin(ALayout, False, True);
end;

function TsgCADDirectExport.GetImageDefHandle(W: TsgCADWipeOut): UInt64;
begin
  if IsNeedImageDefHandle(W) then
  begin
    if TsgDXFImageEntAccess(W).ImageDefExport <> nil then
      Result := TsgDXFImageEntAccess(W).ImageDefExport.Handle
    else
      Result := TsgDXFImageEnt(W).ImageDef.Handle;
  end
  else
    Result := cnstBadHandle;
end;

function TsgCADDirectExport.GetLinMax(ALayout: TsgDXFLayout): TFPoint;
begin
  Result := GetExtLinMaxMin(ALayout, True, False);
end;

function TsgCADDirectExport.GetLinMin(ALayout: TsgDXFLayout): TFPoint;
begin
  Result := GetExtLinMaxMin(ALayout, False, False);
end;

function TsgCADDirectExport.GetModelSpaceName: string;
begin
  if Ord(Version) >= Ord(acR14) then
    Result := sModelSpace
  else
    Result := sModelSpace12;
end;

function TsgCADDirectExport.GetNextEntHandle(Group: TsgDXFEntity;
  Index: Integer; AList: TList): UInt64;
begin
  Result := cnstBadHandle;
end;

function TsgCADDirectExport.GetPaperLayout: TsgDXFLayout;
begin
  Result := nil;
  if ExportCADImage.CurrentLayout <> ExportCADImage.Layouts[0] then
    Result := ExportCADImage.CurrentLayout
  else
    if ExportCADImage.LayoutsCount > 1 then
      Result := ExportCADImage.Layouts[1];
end;

function TsgCADDirectExport.GetPaperSpaceName: string;
begin
  if Ord(Version) >= Ord(acR14) then
    Result := sPaperSpace
  else
    Result := sPaperSpace12;
end;

function TsgCADDirectExport.GetPrevEntHandle(Group: TsgDXFEntity;
  Index: Integer; AList: TList): UInt64;
begin
  Result := cnstBadHandle;
end;

function TsgCADDirectExport.GetRealCountBoundaryPoints(
  W: TsgCADWipeout): Integer;
begin
  Result := W.ClipPointsCount;
  if IsNeedAddPointForBoundary(W) then Inc(Result);
end;

procedure TsgCADDirectExport.InitEntityForExport(const Entity: TsgDXFEntity);
begin
  if (Entity <> nil) and (Entity.EntType = ceImageEnt) then
  begin
    TsgDXFImageEntAccess(Entity).FDirectExportConverImageToOLE := ConverImageToOLE;
    TsgDXFImageEntAccess(Entity).FDirectExportImageFileIndex := ExportImageFileIndex;
  end;
end;

function TsgCADDirectExport.IsNameInternal(const AName: string): Boolean;
begin
  Result := AnsiUpperCase(AName) = 'REDLINE';
end;

function TsgCADDirectExport.IsNeedAddPointForBoundary(
  W: TsgCADWipeout): Boolean;
begin
  Result := (W.ClippingBoundaryType <> 1) and (W.ClipPointsCount > 1) and
    (not IsEqualF2DPoints(W.ClipPoints[0], W.ClipPoints[W.ClipPointsCount - 1]));
end;

function TsgCADDirectExport.IsNeedImageDefHandle(W: TsgCADWipeout): Boolean;
begin
  Result := (W.EntType = ceImageEnt) and ((TsgDXFImageEnt(W).ImageDef <> nil) or
    (TsgDXFImageEntAccess(W).ImageDefExport <> nil));
end;

procedure TsgCADDirectExport.PrepareDrawingDatabase;
begin
  CreateDefaultDrawingProp;
end;

procedure TsgCADDirectExport.PrepareOLEHeader(OLE2: TsgDXFOle2Frame;
  const POleHeader: PsgOle2FrameHeaderData);
begin
  if POleHeader = nil then Exit;
  POleHeader^.Unknown := $5580;
  POleHeader^.Point1 := MakeFPoint(OLE2.Point.X, OLE2.Point.Y, 0.0); //OLE2.Point;
  POleHeader^.Point2 := MakeFPoint(OLE2.Point1.X, OLE2.Point.Y, 0.0);
  POleHeader^.Point3 := MakeFPoint(OLE2.Point1.X, OLE2.Point1.Y, 0.0); //OLE2.Point1;
  POleHeader^.Point4 := MakeFPoint(OLE2.Point.X, OLE2.Point1.Y, 0.0);
  POleHeader^.EntName := TsgNativeUInt(OLE2);
  POleHeader^.TileModeDescriptor := OLE2.TileModeDescriptor xor 1;
  POleHeader^.ReservedInt1 := 256;
  POleHeader^.ReservedInt2 := 2;
  POleHeader^.ReservedWord := 1;
  POleHeader^.ReservedZero := 0;
  POleHeader^.DrawAspect := OLE2.Aspect;
  POleHeader^.Size := Length(OLE2.BinaryData);
end;

procedure TsgCADDirectExport.ProcessExport(Stream: TStream);
begin
end;

procedure TsgCADDirectExport.SaveToStreamCustom(S: TStream);
var
  vMaxHandle: UInt64;
{$IFDEF SGDEL_2006}
  vTempString: string;
{$ENDIF}
begin
  vMaxHandle := Converter.MaxHandle;
  try
    Clear;
{$IFDEF SGDEL_2006}
    if S is TFileStream then //Converter.FileName?
    begin
      FPathDir := ExtractFileDir(TFileStream(S).FileName);
      FFileName := ExtractFileName(TFileStream(S).FileName);
      vTempString := ExtractFileExt(FFileName);
      if Length(vTempString) <> 0 then
        SetLength(FFileName, Length(FFileName) - Length(vTempString));
      FExportImageFileIndex := 1;
      FImageDefList.Count := 0;
    end
    else
{$ENDIF}
    begin
      FPathDir := '';
      FFileName := '';
      FExportImageFileIndex := -1;
      FImageDefList.Count := 0;
    end;
    LoadSGBlock;
    ProcessExport(S);
  finally
    Converter.MaxHandle := vMaxHandle;
  end;
end;

procedure TsgCADDirectExport.SetDrwHyperlinkBase(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropHyperlinkBase)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropAuthor(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropAuthor)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropComments(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropComments)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropKeywords(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropKeywords)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropSavedBy(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropLastSavedBy)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropSubject(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropSubject)] := Value;
end;

procedure TsgCADDirectExport.SetDrwPropTitle(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropTitle)] := Value;
end;

procedure TsgCADDirectExport.SetDrwRevisionNumber(const Value: string);
begin
  FDrwPropInfo.Values[IntToStr(cntXCodeDrwPropRevisionNumber)] := Value;
end;

procedure TsgCADDirectExport.SetOleFrameVariable(const AValue: Integer);
begin

end;

procedure TsgCADDirectExport.SetVersion(const Value: TsgDWGVersion);
begin
  FVersion := Value;
end;

{ TsgDXFImageDefExport }

constructor TsgDXFImageDefExport.Create;
begin
  inherited Create;
  FImageEnt := nil;
end;

destructor TsgDXFImageDefExport.Destroy;
begin
  if FImageEnt <> nil then
    TsgDXFImageEntAccess(FImageEnt).ImageDefExport := nil;
  inherited Destroy;
end;

{ TsgDWGExportDataClass }

constructor TsgDWGExportDataClass.Create;
begin
  inherited Create;
  FBits := nil;
  FOwnerObject := nil;
  FGroup := nil;
  FExportData := CreateExportData;
  FGroupIndex := 0;
end;

constructor TsgDWGExportDataClass.CreateEx(const ABits, AOwnerObject, AGroup: TObject;
  AExportData: TsgDirectExportData);
begin
  Create;
  FBits := ABits;
  FOwnerObject := AOwnerObject;
  FGroup := AGroup;
  FExportData := AExportData;
end;

function TsgDWGExportDataClass.GetPExportData: PsgDirectExportData;
begin
  Result := @FExportData;
end;

end.
