{Notationen:
   _color    :TColor
   _fd       :Double
   _s        :String
   _a        :Array Of
             mdp     :TMetaDatPoints (=Array of TMetaDatPoint)
             p       :Array Of TPoint
   _(x)      :Extended
             md      :TMetaDaten (_xmd)
                     i        : TMetaDat Ini (_xmdi)
                              t: TMetaDat Ini Typ (_xmdit)
                     p:TMataDatPoint (_xmdp)
             c       :TCanvas (_xc)
}
unit metafile;

interface
uses graphics,sysutils,windows,turbo;
type
  TMetaDatIniTyp=(mditEllipse,mditPolygon,mditPolyline);
  TMetaDatIni=packed record
    typ_mdit:TMetaDatIniTyp;
    brush_color:tcolor;
    pen_color:Tcolor;
    pen_width_fd:double;
  end;
  TMetaDatPoint=packed record
    x_fd,y_fd:Double;
  end;
  TMetaDatPoints=packed array of TMetaDatPoint;
  TMetaDat=packed record
    ini_xmdi:TMetaDatIni;
    points_amdp:TMetaDatPoints;
  end;
  TMetaDaten=packed array of TMetaDat;

  EMetaFileError=class(exception);

type TBMetaFile=class
  metafile_xmd:TMetaDaten;
  procedure LoadFromFile(filename_s:string);
  procedure DrawEx(canvas_xc:TCanvas;x_i,y_i,width_i,height_i,helligkeit_i:integer);
  constructor create;
end;


implementation

constructor TBMetaFile.create;
begin
  setlength(metafile_xmd,0);
end;
procedure TBMetaFile.LoadFromFile(filename_s:string);
var datei:file;
    temp_i,i,j:integer;
begin
  AssignFile(datei,FileName_s);
  Reset(datei,1);
  try
    BlockRead(datei,temp_i,sizeof(temp_i));
    if temp_i<>7 then
      raise EMetaFileError.create('Ungültiger Dateicode: '+IntToStr(temp_i));
    BlockRead(datei,temp_i,sizeof(temp_i));
    setlength(metafile_xmd,temp_i);
    for i:=0 to temp_i-1 do begin
      blockread(datei,metafile_xmd[i].ini_xmdi,sizeof(metafile_xmd[i].ini_xmdi));
      BlockRead(datei,temp_i,sizeof(temp_i));
      SetLength(metafile_xmd[i].points_amdp,temp_i);
      for j:=0 to temp_i-1 do begin
        blockread(datei,metafile_xmd[i].points_amdp[j],sizeof(metafile_xmd[i].points_amdp[j]));
      end;
    end;
  finally
    CloseFile(datei);
  end;
end;

procedure TBMetaFile.DrawEx(canvas_xc:TCanvas;x_i,y_i,width_i,height_i,helligkeit_i:integer);
var i,j:integer;
    points_ap:array of TPoint;
    xp,yp:integer;
    function XPosToXPos(const x_fd:double):integer;
    begin
      result:=trunc(width_i/x_fd)+xp;
    end;
    function YPosToYPos(const y_fd:double):integer;
    begin
      result:=trunc(height_i/y_fd)+yp;
    end;
begin
xp:=x_i;
yp:=y_i;
for i:=0 to high(metafile_xmd) do begin
  Canvas_xc.brush.Color:= SetHelligkeit(metafile_xmd[i].ini_xmdi.brush_color,helligkeit_i);
  if metafile_xmd[i].ini_xmdi.brush_color = clNone then
    canvas_xc.brush.Style:=bsClear
   else
    canvas_xc.brush.Style:=bsSolid;
  canvas_xc.pen.Color:=SetHelligkeit(metafile_xmd[i].ini_xmdi.pen_color,helligkeit_i);
  if (metafile_xmd[i].ini_xmdi.pen_color = clnone)or(metafile_xmd[i].ini_xmdi.pen_width_fd=0) then
    canvas_xc.pen.Style:=psClear
   else
    canvas_xc.pen.Style:=psSolid;
  canvas_xc.pen.Width:=trunc(sqrt(width_i*height_i) / metafile_xmd[i].ini_xmdi.pen_width_fd);
  case metafile_xmd[i].ini_xmdi.typ_mdit of
    mditEllipse: begin
                   canvas_xc.Ellipse(XPosToXPos( metafile_xmd[i].points_amdp[0].x_fd),YPosToYPos(metafile_xmd[i].points_amdp[0].y_fd),XPosToXPos(metafile_xmd[i].points_amdp[1].x_fd),YPosToYPos(metafile_xmd[i].points_amdp[1].y_fd));
                 end;
    mditPolygon: begin
                   setlength(points_ap,length(metafile_xmd[i].points_amdp));
                   for j:=0 to high(metafile_xmd[i].points_amdp) do begin
                     points_ap[j].x:=XPosToXPos(metafile_xmd[i].points_amdp[j].x_fd);
                     points_ap[j].y:=YPosToYPos(metafile_xmd[i].points_amdp[j].y_fd);
                   end;
                   canvas_xc.Polygon(points_ap);
                 end;
    mditPolyline: begin
                   setlength(points_ap,length(metafile_xmd[i].points_amdp));
                   for j:=0 to high(metafile_xmd[i].points_amdp) do begin
                     points_ap[j].x:=XPosToXPos(metafile_xmd[i].points_amdp[j].x_fd);
                     points_ap[j].y:=YPosToYPos(metafile_xmd[i].points_amdp[j].y_fd);
                   end;
                   canvas_xc.Polyline(points_ap);
                 end;
  end;
end;
end;
end.
