📄 uescherrecords.pas
字号:
unit UEscherRecords;
{$IFDEF LINUX}{$INCLUDE ../FLXCOMPILER.INC}{$ELSE}{$INCLUDE ..\FLXCOMPILER.INC}{$ENDIF}
interface
uses XlsMessages, UFlxMessages, UXlsBaseRecords, Classes, SysUtils, Contnrs, UXlsBaseClientData,
UBreakList, UXlsBaseList;
type
TEscherRecordHeader= packed record
Pre, Id: word;
Size: Longint;
end;
TEscherRecord = class;
TEscherClientDataRecord = class;
TEscherClientAnchorRecord = class;
TEscherBStoreRecord = class;
TEscherDgRecord = class;
TEscherSolverContainerRecord = class;
TEscherDggRecord = class;
TEscherContainerRecord=class;
TEscherSpgrContainerRecord=class;
TEscherSPRecord=class;
TEscherOPTRecord= class;
TEscherRecordCache = class (TBaseList)
{$INCLUDE TEscherRecordCacheHdr.inc}
constructor Create;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);
end;
TEscherObjCache = class (TEscherRecordCache)
{$INCLUDE TEscherObjCacheHdr.inc}
procedure ArrangeCopySheet(const SheetInfo: TSheetInfo);
end;
TEscherAnchorCache = class (TEscherRecordCache)
{$INCLUDE TEscherAnchorCacheHdr.inc}
end;
TEscherShapeCache = class (TEscherRecordCache)
{$INCLUDE TEscherShapeCacheHdr.inc}
end;
TEscherOPTCache = class (TEscherRecordCache)
{$INCLUDE TEscherOPTCacheHdr.inc}
end;
TEscherDwgCache = record
Destroying: boolean;
MaxObjId: word;
Dg: TEscherDgRecord;
Solver: TEscherSolverContainerRecord;
Patriarch: TEscherSpgrContainerRecord;
Anchor: TEscherAnchorCache;
Shape: TEscherShapeCache;
Obj: TEscherObjCache;
Blip: TEscherOPTCache;
end;
PEscherDwgCache=^TEscherDwgCache;
TEscherDwgGroupCache = record
BStore: TEscherBStoreRecord;
Dgg: TEscherDggRecord;
end;
PEscherDwgGroupCache=^TEscherDwgGroupCache;
//////////////////////////////////Base records ////////////////////////////
ClassOfTEscherRecord= class of TEscherRecord;
TEscherRecord= class
private
FParent: TEscherContainerRecord;
procedure IncNextPos(var NextPos: integer; const Size: integer; var RealSize: integer; const BreakList: TBreakList);
procedure CheckSplit(const DataStream: TStream; const BreakList: TBreakList);
procedure WriteNewRecord(const DataStream: TStream; const BreakList: TBreakList);
protected
DwgCache: PEscherDwgCache;
DwgGroupCache: PEscherDwgGroupCache;
public
Pre, Id: word;
TotalDataSize, LoadedDataSize: integer;
CopiedTo: TEscherRecord;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; virtual;
function Instance: word;
function Version: word;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); virtual;
procedure AfterCreate; virtual;
procedure Load(var aRecord: TBaseRecord; var aPos: integer); virtual ; abstract;
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); virtual;
function CopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; //this should be non-virtual
function TotalSizeNoSplit: int64;virtual;
function Loaded: boolean;virtual;
function IsContainer(const aPre: word): boolean;
function WaitingClientData(var ClientType: ClassOfTBaseClientData) : boolean; virtual;
procedure AssignClientData(const aClientData: TBaseClientData);virtual;
procedure SplitRecords(var NextPos, RealSize, NextDwg: integer;const BreakList: TBreakList);virtual;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);virtual;
procedure ClearCopiedTo; virtual;
function FindRoot: TEscherRecord;
function FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord; virtual;
function Patriarch: TEscherSpgrContainerRecord;
function CopyDwg(const RowOfs, ColOfs: integer): TEscherRecord;
function CompareRec(const aRecord: TEscherRecord): integer; virtual;//this is used for searching
end;
TEscherRecordList= class (TBaseList)
private
{$INCLUDE TEscherRecordListHdr.inc}
public
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
procedure CopyFrom(const aEscherRecordList: TEscherRecordList; const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer);
function TotalSizeNoSplit: int64;
end;
TEscherDataRecord= class(TEscherRecord)
protected
Data: PArrayOfByte;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
procedure Load(var aRecord: TBaseRecord; var aPos: integer);override;
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
procedure SplitRecords(var NextPos, RealSize, NextDwg: integer; const BreakList: TBreakList);override;
function CompareRec(const aRecord: TEscherRecord): integer;override; //this is used for searching
procedure ClearData;
end;
TEscherContainerRecord=class(TEscherRecord)
protected
FContainedRecords: TEscherRecordList;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; override;
public
property ContainedRecords: TEscherRecordList read FContainedRecords;
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
procedure Load(var aRecord: TBaseRecord; var aPos: integer);override;
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
function WaitingClientData(var ClientType: ClassOfTBaseClientData): boolean;override;
procedure AssignClientData(const aClientData: TBaseClientData);override;
function LastRecord: TEscherRecord;
procedure SplitRecords(var NextPos, RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);override;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);override;
procedure ClearCopiedTo; override;
function FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord; override;
end;
TEscherSpContainerRecord=class(TEscherContainerRecord)
public
SP: TEscherSPRecord;
Opt: TEscherOPTRecord;
ClientAnchor: TEscherClientAnchorRecord;
function Row: integer;
function Col: integer;
end;
TEscherSpgrContainerRecord=class(TEscherContainerRecord)
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
end;
TEscherClientDataRecord= class(TEscherDataRecord)
public
ClientData: TBaseClientData;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache:PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
function Loaded: boolean;override;
function WaitingClientData(var ClientType: ClassOfTBaseClientData): boolean;override;
procedure SplitRecords(var NextPos, RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);override;
procedure AssignClientData(const aClientData: TBaseClientData);override;
procedure ArrangeCopyRowsAndCols(const RowOfs, ColOfs: integer);
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);override;
function ObjId: word;
end;
//////////////////////////////////Other records ////////////////////////////
TEscherSplitMenuRecord= class (TEscherDataRecord)
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
end;
TEscherClientAnchorRecord= class (TEscherDataRecord)
private
Anchor: PClientAnchor;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const aAnchor: TClientAnchor;const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);override;
function AllowCopy(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
function AllowDelete(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; override;
function Row: integer;
function Col: integer;
function GetAnchor: TClientAnchor;
procedure SetAnchor(const aAnchor: TClientAnchor);
end;
TEscherBStoreRecord= class (TEscherContainerRecord)
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
destructor Destroy; override;
procedure AddRef(const BlipPos: integer);
procedure Release(const BlipPos: integer);
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); override;
end;
TEscherBSERecord= class (TEscherDataRecord)
BStorePos: integer;
procedure AddRef;
procedure Release;
function References: LongWord;
function CompareRec(const aRecord: TEscherRecord): integer;override; //search by signature
procedure CopyFromData(const BSEHeader: Pointer; const BlipHeader: TEscherRecordHeader; const BlipData: TStream);
procedure SaveGraphicToStream(const aData:TStream; var aDataType: TXlsImgTypes);
end;
TDg= packed record
ShapeCount: LongWord;
MaxSpId: LongWord;
end;
PDg = ^TDg;
TEscherDgRecord= class(TEscherDataRecord)
private
Dg: PDg;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const csp, cspidCur: LongWord; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
function IncMaxShapeId: LongWord;
procedure DecShapeCount;
end;
TDgg= packed record
MaxShapeId: LongWord;
FIDclCount: LongWord;
ShapesSaved: LongWord;
DwgSaved: LongWord;
end;
PDgg= ^TDgg;
TEscherDggRecord= class(TEscherDataRecord)
public
FDgg: PDgg;
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
end;
PLongWord= ^LongWord;
TEscherSPRecord= class(TEscherDataRecord)
public
ShapeId: PLongWord;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const Pre, aShapeId: LongWord; const Flags: LongWord; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
end;
TEscherSolverContainerRecord = class (TEscherContainerRecord)
public
MaxRuleId: LongWord;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
destructor Destroy; override;
function IncMaxRuleId: LongWord;
procedure CheckMax(const aRuleId: LongWord);
procedure DeleteRef(const Shape: TEscherSPRecord);
procedure FixPointers;
procedure ArrangeCopyRowsAndCols;
end;
TEscherOPTRecord= class (TEscherDataRecord)
private
BlipPtr: array of TEscherBSERecord;
BlipPos: array of LongWord;
FShapeName: WideString;
function GetShapeName: WideString;
function AddImg(const Data: string; const DataType: TXlsImgTypes): integer;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromDataImg(const aPict: string; const aPicType: TXlsImgTypes; const PicName: widestring; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
constructor CreateFromDataNote( const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord; const Dummy: integer=1);
constructor GroupCreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
procedure AfterCreate;override;
property ShapeName: WideString read GetShapeName;
procedure SaveToStream(const DataStream: TStream; const BreakList: TBreakList); override;
function Row: integer;
function Col: integer;
function GetAnchor: TClientAnchor;
procedure SetAnchor(const aAnchor: TClientAnchor);
procedure ChangeRef(const aBSE: TEscherBSERecord);
procedure ReplaceImg(const Data: string; const DataType: TXlsImgTypes);
procedure GetImageFromStream(const Data: TStream; var DataType: TXlsImgTypes);
end;
implementation
uses UXlsClientData,UEscherOtherRecords,UEscherGraphToBSE;
{ TEscherRecordCache }
{$INCLUDE TEscherRecordCacheImp.inc}
constructor TEscherRecordCache.Create;
begin
inherited Create(False) //We don't own the objects
end;
procedure TEscherRecordCache.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer;
const SheetInfo: TSheetInfo; const Forced: boolean);
var
i: integer;
begin
for i:=0 to Count-1 do Items[i].ArrangeInsertRowsAndCols(aRowPos, aRowCount, aColPos, aColCount, SheetInfo, Forced);
end;
{ TEscherObjCache }
{$INCLUDE TEscherObjCacheImp.inc}
{ TEscherAnchorCache }
{$INCLUDE TEscherAnchorCacheImp.inc}
{ TEscherShapeCache }
{$INCLUDE TEscherShapeCacheImp.inc}
{ TEscherSPContainerCache }
{$INCLUDE TEscherOPTCacheImp.inc}
{ TEscherRecord }
procedure TEscherRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);
begin
//Nothing
end;
procedure TEscherRecord.AssignClientData(const aClientData: TBaseClientData);
begin
raise Exception.Create(ErrLoadingEscher);
end;
procedure TEscherRecord.ClearCopiedTo;
begin
CopiedTo:=nil;
end;
function TEscherRecord.CopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
begin
if Self=nil then Result:= nil //for this to work, this can't be a virtual method
else Result:=DoCopyTo(NewDwgCache, RowOfs, ColOfs);
end;
constructor TEscherRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
inherited Create;
LoadedDataSize:=0;
TotalDataSize:=aEscherHeader.Size;
Id:= aEscherHeader.Id;
Pre:= aEscherHeader.Pre;
DwgGroupCache:= aDwgGroupCache;
DwgCache:= aDwgCache;
FParent:=aParent;
end;
function TEscherRecord.DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
var
ERec: TEscherRecordHeader;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -