Starts fixing the rendering of documents with negative coords and crazy document sizes

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1513 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2011-02-28 13:39:12 +00:00
parent 78c52d3eeb
commit e29c8ef485
3 changed files with 63 additions and 8 deletions

View File

@ -29,7 +29,7 @@ unit dxfvectorialreader;
interface
uses
Classes, SysUtils,
Classes, SysUtils, Math,
fpvectorial;
type
@ -69,6 +69,9 @@ type
// HEADER data
ANGBASE: Double;
ANGDIR: Integer;
INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint;
// Calculated HEADER data
DOC_OFFSET: T3DPoint;
//
function SeparateString(AString: string; ASeparator: Char): T10Strings;
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
@ -328,6 +331,7 @@ procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
var
i, j: Integer;
CurToken: TDXFToken;
CurField: P3DPoint;
begin
i := 0;
while i < ATokens.Count do
@ -346,8 +350,16 @@ begin
Inc(i);
end
// This indicates the size of the document
else if CurToken.StrValue = '$LIMMAX' then
else if (CurToken.StrValue = '$INSBASE') or
(CurToken.StrValue = '$EXTMIN') or (CurToken.StrValue = '$EXTMAX') or
(CurToken.StrValue = '$LIMMIN') or (CurToken.StrValue = '$LIMMAX') then
begin
if (CurToken.StrValue = '$INSBASE') then CurField := @INSBASE
else if (CurToken.StrValue = '$EXTMIN') then CurField := @EXTMIN
else if (CurToken.StrValue = '$EXTMAX') then CurField := @EXTMAX
else if (CurToken.StrValue = '$LIMMIN') then CurField := @LIMMIN
else if (CurToken.StrValue = '$LIMMAX') then CurField := @LIMMAX;
// Check the next 2 items and verify if they are the values of the size of the document
for j := 0 to 1 do
begin
@ -355,12 +367,12 @@ begin
case CurToken.GroupCode of
10:
begin;
aData.Width := StrToFloat(CurToken.StrValue, FPointSeparator);
CurField^.X := StrToFloat(CurToken.StrValue, FPointSeparator);
Inc(i);
end;
20:
begin
aData.Height := StrToFloat(CurToken.StrValue, FPointSeparator);
CurField^.Y := StrToFloat(CurToken.StrValue, FPointSeparator);
Inc(i);
end;
end;
@ -369,6 +381,37 @@ begin
Inc(i);
end;
// After getting all the data, we can try to make so sense out of it
// Sometimes EXTMIN comes as 10^20 and EXTMAX as -10^20, which makes no sence
// In these cases we need to ignore them.
if (EXTMIN.X > 100000) or (EXTMIN.X < -100000) or (EXTMAX.X > 100000) or (EXTMAX.X < -100000) then
begin
DOC_OFFSET.X := 0;
DOC_OFFSET.Y := 0;
AData.Width := LIMMAX.X;
AData.Height := LIMMAX.Y;
end
else
begin
// The size of the document seams to be given by:
// DOC_SIZE = min(EXTMAX, LIMMAX) - DOC_OFFSET;
// if EXTMIN is <> -infinite then DOC_OFFSET = EXTMIN else DOC_OFFSET = (0, 0)
// We will shift the whole document so that it has only positive coordinates and
// DOC_OFFSET will be utilized for that
if EXTMIN.X > -100 then
begin
DOC_OFFSET.X := EXTMIN.X;
DOC_OFFSET.Y := EXTMIN.Y;
end
else FillChar(DOC_OFFSET, sizeof(T3DPoint), #0);
AData.Width := min(EXTMAX.X, LIMMAX.X) - DOC_OFFSET.X;
AData.Height := min(EXTMAX.Y, LIMMAX.Y) - DOC_OFFSET.Y;
end;
end;
procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
@ -487,6 +530,9 @@ begin
end;
end;
CenterX := CenterX - DOC_OFFSET.X;
CenterY := CenterY - DOC_OFFSET.Y;
{$ifdef FPVECTORIALDEBUG}
WriteLn(Format('Adding Arc Center=%f,%f Radius=%f StartAngle=%f EndAngle=%f',
[CenterX, CenterY, Radius, StartAngle, EndAngle]));

View File

@ -43,6 +43,8 @@ type
X, Y, Z: Double;
end;
P3DPoint = ^T3DPoint;
TSegmentType = (
st2DLine, st2DBezier,
st3DLine, st3DBezier, stMoveTo);

View File

@ -52,6 +52,7 @@ uses
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);
var
Vec: TvVectorialDocument;
CanvasSize: TPoint;
begin
// First check the in input
//if not CheckInput() then Exit;
@ -65,11 +66,17 @@ begin
Vec.ReadFromFile(editFileName.FileName, vfDXF);
// We need to be robust, because sometimes the document size won't be given
if Vec.Width < 100 then Vec.Width := Drawer.Width;
if Vec.Height < 100 then Vec.Height := Drawer.Height;
// also give up drawing everything if we need more then 4MB of RAM for the image
if Vec.Width * spinScale.Value > 1000 then CanvasSize.X := 1000
else if Vec.Width < 100 then CanvasSize.X := Drawer.Width
else CanvasSize.X := Round(Vec.Width * spinScale.Value);
Drawer.Drawing.Width := Round(Vec.Width * spinScale.Value);
Drawer.Drawing.Height := Round(Vec.Height * spinScale.Value);
if Vec.Height * spinScale.Value > 1000 then CanvasSize.Y := 1000
else if Vec.Height < 100 then CanvasSize.Y := Drawer.Height
else CanvasSize.Y := Round(Vec.Height * spinScale.Value);
Drawer.Drawing.Width := CanvasSize.X;
Drawer.Drawing.Height := CanvasSize.Y;
Drawer.Drawing.Canvas.Brush.Color := clWhite;
Drawer.Drawing.Canvas.Brush.Style := bsSolid;
Drawer.Drawing.Canvas.FillRect(0, 0, Drawer.Drawing.Width, Drawer.Drawing.Height);