mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 03:09:11 +02:00
Fixes compiling avisocncvectorialwriter, adds a dimension entity and multiple improvements to fpvtocanvas and the DXF vectorial reader
git-svn-id: trunk@17092 -
This commit is contained in:
parent
5aea0bc565
commit
c0f254d706
@ -36,6 +36,10 @@ var
|
|||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
Str: string;
|
Str: string;
|
||||||
APath: TPath;
|
APath: TPath;
|
||||||
|
CurSegment: T2DSegment;
|
||||||
|
Cur3DSegment: T3DSegment;
|
||||||
|
Cur2DBezierSegment: T2DBezierSegment;
|
||||||
|
Cur3DBezierSegment: T3DBezierSegment;
|
||||||
begin
|
begin
|
||||||
AStrings.Clear;
|
AStrings.Clear;
|
||||||
|
|
||||||
@ -51,25 +55,39 @@ begin
|
|||||||
// levanta a broca
|
// levanta a broca
|
||||||
AStrings.Add('P01 // Sobe a cabeça de gravação');
|
AStrings.Add('P01 // Sobe a cabeça de gravação');
|
||||||
// vai para o ponto inicial
|
// vai para o ponto inicial
|
||||||
|
CurSegment := T2DSegment(APath.Points);
|
||||||
AStrings.Add(Format('G01 X%f Y%f',
|
AStrings.Add(Format('G01 X%f Y%f',
|
||||||
[APath.Points[0].X, APath.Points[0].Y]));
|
[CurSegment.X, CurSegment.Y]));
|
||||||
AStrings.Add('P02 // Abaixa a cabeça de gravação');
|
AStrings.Add('P02 // Abaixa a cabeça de gravação');
|
||||||
|
|
||||||
for j := 1 to APath.Len - 1 do
|
for j := 1 to APath.Len - 1 do
|
||||||
begin
|
begin
|
||||||
case APath.Points[j].SegmentType of
|
CurSegment := T2DSegment(CurSegment.Next);
|
||||||
|
case CurSegment.SegmentType of
|
||||||
st2DLine: AStrings.Add(Format('G01 X%f Y%f',
|
st2DLine: AStrings.Add(Format('G01 X%f Y%f',
|
||||||
[APath.Points[j].X, APath.Points[j].Y]));
|
[CurSegment.X, CurSegment.Y]));
|
||||||
st3DLine: AStrings.Add(Format('G01 X%f Y%f Z%f',
|
st3DLine:
|
||||||
[APath.Points[j].X, APath.Points[j].Y, APath.Points[j].Z]));
|
begin
|
||||||
st2DBezier: AStrings.Add(Format('B02 X%f Y%f X%f Y%f X%f Y%f',
|
Cur3DSegment := T3DSegment(CurSegment);
|
||||||
[APath.Points[j].X2, APath.Points[j].Y2,
|
AStrings.Add(Format('G01 X%f Y%f Z%f',
|
||||||
APath.Points[j].X3, APath.Points[j].Y3,
|
[Cur3DSegment.X, Cur3DSegment.Y, Cur3DSegment.Z]));
|
||||||
APath.Points[j].X, APath.Points[j].Y]));
|
end;
|
||||||
st3DBezier: AStrings.Add(Format('B03 X%f Y%f Z%f X%f Y%f Z%f X%f Y%f Z%f',
|
st2DBezier:
|
||||||
[APath.Points[j].X2, APath.Points[j].Y2, APath.Points[j].Z2,
|
begin
|
||||||
APath.Points[j].X3, APath.Points[j].Y3, APath.Points[j].Z3,
|
Cur2DBezierSegment := T2DBezierSegment(CurSegment);
|
||||||
APath.Points[j].X, APath.Points[j].Y, APath.Points[j].Z]));
|
AStrings.Add(Format('B02 X%f Y%f X%f Y%f X%f Y%f',
|
||||||
|
[Cur2DBezierSegment.X2, Cur2DBezierSegment.Y2,
|
||||||
|
Cur2DBezierSegment.X3, Cur2DBezierSegment.Y3,
|
||||||
|
Cur2DBezierSegment.X, Cur2DBezierSegment.Y]));
|
||||||
|
end;
|
||||||
|
st3DBezier:
|
||||||
|
begin
|
||||||
|
Cur3DBezierSegment := T3DBezierSegment(CurSegment);
|
||||||
|
AStrings.Add(Format('B03 X%f Y%f Z%f X%f Y%f Z%f X%f Y%f Z%f',
|
||||||
|
[Cur3DBezierSegment.X2, Cur3DBezierSegment.Y2, Cur3DBezierSegment.Z2,
|
||||||
|
Cur3DBezierSegment.X3, Cur3DBezierSegment.Y3, Cur3DBezierSegment.Z3,
|
||||||
|
Cur3DBezierSegment.X, Cur3DBezierSegment.Y, Cur3DBezierSegment.Z]));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -29,11 +29,10 @@ unit dxfvectorialreader;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils, Math,
|
||||||
fpvectorial;
|
fpvectorial;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ Used by tcutils.SeparateString }
|
{ Used by tcutils.SeparateString }
|
||||||
T10Strings = array[0..9] of shortstring;
|
T10Strings = array[0..9] of shortstring;
|
||||||
|
|
||||||
@ -70,6 +69,9 @@ type
|
|||||||
// HEADER data
|
// HEADER data
|
||||||
ANGBASE: Double;
|
ANGBASE: Double;
|
||||||
ANGDIR: Integer;
|
ANGDIR: Integer;
|
||||||
|
INSBASE, EXTMIN, EXTMAX, LIMMIN, LIMMAX: T3DPoint;
|
||||||
|
// Calculated HEADER data
|
||||||
|
DOC_OFFSET: T3DPoint;
|
||||||
//
|
//
|
||||||
function SeparateString(AString: string; ASeparator: Char): T10Strings;
|
function SeparateString(AString: string; ASeparator: Char): T10Strings;
|
||||||
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
@ -77,6 +79,7 @@ type
|
|||||||
procedure ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
procedure ReadENTITIES_ARC(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadENTITIES_ARC(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
procedure ReadENTITIES_CIRCLE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadENTITIES_CIRCLE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
|
procedure ReadENTITIES_DIMENSION(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
procedure ReadENTITIES_ELLIPSE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadENTITIES_ELLIPSE(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
procedure ReadENTITIES_TEXT(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure ReadENTITIES_TEXT(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
function GetCoordinateValue(AStr: shortstring): Double;
|
function GetCoordinateValue(AStr: shortstring): Double;
|
||||||
@ -326,8 +329,9 @@ end;
|
|||||||
procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
|
procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
|
||||||
AData: TvVectorialDocument);
|
AData: TvVectorialDocument);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i, j: Integer;
|
||||||
CurToken: TDXFToken;
|
CurToken: TDXFToken;
|
||||||
|
CurField: P3DPoint;
|
||||||
begin
|
begin
|
||||||
i := 0;
|
i := 0;
|
||||||
while i < ATokens.Count do
|
while i < ATokens.Count do
|
||||||
@ -344,10 +348,71 @@ begin
|
|||||||
CurToken := TDXFToken(ATokens.Items[i+1]);
|
CurToken := TDXFToken(ATokens.Items[i+1]);
|
||||||
ANGDIR := StrToInt(CurToken.StrValue);
|
ANGDIR := StrToInt(CurToken.StrValue);
|
||||||
Inc(i);
|
Inc(i);
|
||||||
|
end
|
||||||
|
// This indicates the size of the document
|
||||||
|
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
|
||||||
|
CurToken := TDXFToken(ATokens.Items[i+1]);
|
||||||
|
case CurToken.GroupCode of
|
||||||
|
10:
|
||||||
|
begin;
|
||||||
|
CurField^.X := StrToFloat(CurToken.StrValue, FPointSeparator);
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
20:
|
||||||
|
begin
|
||||||
|
CurField^.Y := StrToFloat(CurToken.StrValue, FPointSeparator);
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Inc(i);
|
Inc(i);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// After getting all the data, we can try to make some 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 > 10000000000) or (EXTMIN.X < -10000000000)
|
||||||
|
or (EXTMAX.X > 10000000000) or (EXTMAX.X < -10000000000) 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;
|
end;
|
||||||
|
|
||||||
procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
|
||||||
@ -360,9 +425,11 @@ begin
|
|||||||
CurToken := TDXFToken(ATokens.Items[i]);
|
CurToken := TDXFToken(ATokens.Items[i]);
|
||||||
if CurToken.StrValue = 'ARC' then ReadENTITIES_ARC(CurToken.Childs, AData)
|
if CurToken.StrValue = 'ARC' then ReadENTITIES_ARC(CurToken.Childs, AData)
|
||||||
else if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData)
|
else if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData)
|
||||||
|
else if CurToken.StrValue = 'DIMENSION' then ReadENTITIES_DIMENSION(CurToken.Childs, AData)
|
||||||
else if CurToken.StrValue = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData)
|
else if CurToken.StrValue = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData)
|
||||||
else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData)
|
else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData)
|
||||||
else if CurToken.StrValue = 'TEXT' then
|
else if CurToken.StrValue = 'TEXT' then ReadENTITIES_TEXT(CurToken.Childs, AData)
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
// ...
|
// ...
|
||||||
end;
|
end;
|
||||||
@ -406,9 +473,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Position fixing for documents with negative coordinates
|
||||||
|
LineStartX := LineStartX - DOC_OFFSET.X;
|
||||||
|
LineStartY := LineStartY - DOC_OFFSET.Y;
|
||||||
|
LineEndX := LineEndX - DOC_OFFSET.X;
|
||||||
|
LineEndY := LineEndY - DOC_OFFSET.Y;
|
||||||
|
|
||||||
// And now write it
|
// And now write it
|
||||||
{$ifdef FPVECTORIALDEBUG}
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
WriteLn(Format('Adding Line from %f,%f to %f,%f', [LineStartX, LineStartY, LineEndX, LineEndY]));
|
// WriteLn(Format('Adding Line from %f,%f to %f,%f', [LineStartX, LineStartY, LineEndX, LineEndY]));
|
||||||
{$endif}
|
{$endif}
|
||||||
AData.StartPath(LineStartX, LineStartY);
|
AData.StartPath(LineStartX, LineStartY);
|
||||||
AData.AddLineToPath(LineEndX, LineEndY);
|
AData.AddLineToPath(LineEndX, LineEndY);
|
||||||
@ -416,6 +489,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Arcs are always counter-clockwise in DXF
|
||||||
|
|
||||||
100 Subclass marker (AcDbCircle)
|
100 Subclass marker (AcDbCircle)
|
||||||
39 Thickness (optional; default = 0)
|
39 Thickness (optional; default = 0)
|
||||||
10 Center point (in OCS) DXF: X value; APP: 3D point
|
10 Center point (in OCS) DXF: X value; APP: 3D point
|
||||||
@ -462,6 +537,18 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// In DXF the EndAngle is always greater then the StartAngle.
|
||||||
|
// If it isn't then sum 360 to it to make sure we don't get wrong results
|
||||||
|
if EndAngle < StartAngle then EndAngle := EndAngle + 360;
|
||||||
|
|
||||||
|
// Position fixing for documents with negative coordinates
|
||||||
|
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]));
|
||||||
|
{$endif}
|
||||||
AData.AddCircularArc(CenterX, CenterY, CenterZ, Radius, StartAngle, EndAngle);
|
AData.AddCircularArc(CenterX, CenterY, CenterZ, Radius, StartAngle, EndAngle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -506,10 +593,175 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Position fixing for documents with negative coordinates
|
||||||
|
CircleCenterX := CircleCenterX - DOC_OFFSET.X;
|
||||||
|
CircleCenterY := CircleCenterY - DOC_OFFSET.Y;
|
||||||
|
|
||||||
AData.AddCircle(CircleCenterX, CircleCenterY,
|
AData.AddCircle(CircleCenterX, CircleCenterY,
|
||||||
CircleCenterZ, CircleRadius);
|
CircleCenterZ, CircleRadius);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
Group codes Description
|
||||||
|
100 Subclass marker (AcDbDimension)
|
||||||
|
2 Name of the block that contains the entities that make up the dimension picture
|
||||||
|
10 Definition point (in WCS) DXF: X value; APP: 3D point
|
||||||
|
20, 30 DXF: Y and Z values of definition point (in WCS)
|
||||||
|
11 Middle point of dimension text (in OCS) DXF: X value; APP: 3D point
|
||||||
|
21, 31 DXF: Y and Z values of middle point of dimension text (in OCS)
|
||||||
|
70 Dimension type.
|
||||||
|
Values 0-6 are integer values that represent the dimension type.
|
||||||
|
Values 32, 64, and 128 are bit values, which are added to the integer values
|
||||||
|
(value 32 is always set in R13 and later releases).
|
||||||
|
0 = Rotated, horizontal, or vertical; 1 = Aligned;
|
||||||
|
2 = Angular; 3 = Diameter; 4 = Radius;
|
||||||
|
5 = Angular 3 point; 6 = Ordinate;
|
||||||
|
32 = Indicates that the block reference (group code 2) is referenced by this dimension only.
|
||||||
|
64 = Ordinate type. This is a bit value (bit 7) used only with integer value 6.
|
||||||
|
If set, ordinate is X-type; if not set, ordinate is Y-type.
|
||||||
|
128 = This is a bit value (bit 8) added to the other group 70 values
|
||||||
|
if the dimension text has been positioned at a user-defined location
|
||||||
|
rather than at the default location.
|
||||||
|
71 Attachment point:
|
||||||
|
1 = Top left; 2 = Top center; 3 = Top right;
|
||||||
|
4 = Middle left; 5 = Middle center; 6 = Middle right;
|
||||||
|
7 = Bottom left; 8 = Bottom center; 9 = Bottom right
|
||||||
|
72 Dimension text line spacing style (optional):
|
||||||
|
1(or missing) = At least (taller characters will override)
|
||||||
|
2 = Exact (taller characters will not override)
|
||||||
|
41 Dimension text line spacing factor (optional):
|
||||||
|
Percentage of default (3-on-5) line spacing to be applied. Valid values range from 0.25 to 4.00.
|
||||||
|
42 Actual measurement (optional; read-only value)
|
||||||
|
1 Dimension text explicitly entered by the user. Optional; default is the measurement.
|
||||||
|
If null or "<>", the dimension measurement is drawn as the text,
|
||||||
|
if " " (one blank space), the text is suppressed. Anything else is drawn as the text.
|
||||||
|
53 The optional group code 53 is the rotation angle of the dimension
|
||||||
|
text away from its default orientation (the direction of the dimension line) (optional).
|
||||||
|
51 All dimension types have an optional 51 group code, which indicates the
|
||||||
|
horizontal direction for the dimension entity. The dimension entity determines
|
||||||
|
the orientation of dimension text and lines for horizontal, vertical, and
|
||||||
|
rotated linear dimensions.
|
||||||
|
This group value is the negative of the angle between the OCS X axis
|
||||||
|
and the UCS X axis. It is always in the XY plane of the OCS.
|
||||||
|
210 Extrusion direction (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector
|
||||||
|
220, 230 DXF: Y and Z values of extrusion direction (optional)
|
||||||
|
3 Dimension style name
|
||||||
|
|
||||||
|
Aligned Dimension Group Codes
|
||||||
|
|
||||||
|
100 Subclass marker (AcDbAlignedDimension)
|
||||||
|
12 Insertion point for clones of a dimension-Baseline and Continue (in OCS) DXF: X value; APP: 3D point
|
||||||
|
22, 32 DXF: Y and Z values of insertion point for clones of a dimension-Baseline and Continue (in OCS)
|
||||||
|
13 Definition point for linear and angular dimensions (in WCS) DXF: X value; APP: 3D point
|
||||||
|
23, 33 DXF: Y and Z values of definition point for linear and angular dimensions (in WCS)
|
||||||
|
14 Definition point for linear and angular dimensions (in WCS) DXF: X value; APP: 3D point
|
||||||
|
24, 34 DXF: Y and Z values of definition point for linear and angular dimensions (in WCS)
|
||||||
|
|
||||||
|
|--text--|->10,20
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
X->14,24 X->13,23
|
||||||
|
}
|
||||||
|
procedure TvDXFVectorialReader.ReadENTITIES_DIMENSION(ATokens: TDXFTokens;
|
||||||
|
AData: TvVectorialDocument);
|
||||||
|
var
|
||||||
|
CurToken: TDXFToken;
|
||||||
|
i: Integer;
|
||||||
|
// DIMENSION
|
||||||
|
BaseLeft, BaseRight, DimensionRight, DimensionLeft, TmpPoint: T3DPoint;
|
||||||
|
IsAlignedDimension: Boolean = False;
|
||||||
|
begin
|
||||||
|
// Initial values
|
||||||
|
BaseLeft.X := 0;
|
||||||
|
BaseLeft.Y := 0;
|
||||||
|
BaseRight.X := 0;
|
||||||
|
BaseRight.X := 0;
|
||||||
|
DimensionRight.X := 0;
|
||||||
|
DimensionRight.Y := 0;
|
||||||
|
DimensionLeft.X := 0;
|
||||||
|
DimensionLeft.Y := 0;
|
||||||
|
|
||||||
|
for i := 0 to ATokens.Count - 1 do
|
||||||
|
begin
|
||||||
|
// Now read and process the item name
|
||||||
|
CurToken := TDXFToken(ATokens.Items[i]);
|
||||||
|
|
||||||
|
// Avoid an exception by previously checking if the conversion can be made
|
||||||
|
if CurToken.GroupCode in [10, 20, 30, 11, 21, 31, 13, 23, 33, 14, 24, 34] then
|
||||||
|
begin
|
||||||
|
CurToken.FloatValue := StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
|
||||||
|
end;
|
||||||
|
|
||||||
|
case CurToken.GroupCode of
|
||||||
|
10: DimensionRight.X := CurToken.FloatValue;
|
||||||
|
20: DimensionRight.Y := CurToken.FloatValue;
|
||||||
|
30: DimensionRight.Z := CurToken.FloatValue;
|
||||||
|
13: BaseRight.X := CurToken.FloatValue;
|
||||||
|
23: BaseRight.Y := CurToken.FloatValue;
|
||||||
|
33: BaseRight.Z := CurToken.FloatValue;
|
||||||
|
14: BaseLeft.X := CurToken.FloatValue;
|
||||||
|
24: BaseLeft.Y := CurToken.FloatValue;
|
||||||
|
34: BaseLeft.Z := CurToken.FloatValue;
|
||||||
|
100:
|
||||||
|
begin
|
||||||
|
if CurToken.StrValue = 'AcDbAlignedDimension' then IsAlignedDimension := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// And now write it
|
||||||
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
|
// WriteLn(Format('Adding Line from %f,%f to %f,%f', [LineStartX, LineStartY, LineEndX, LineEndY]));
|
||||||
|
{$endif}
|
||||||
|
if IsAlignedDimension then
|
||||||
|
begin
|
||||||
|
// Now make sure that we actually that BaseLeft is to the left of BaseRight
|
||||||
|
if BaseRight.X < BaseLeft.X then
|
||||||
|
begin
|
||||||
|
TmpPoint := BaseRight;
|
||||||
|
BaseRight := BaseLeft;
|
||||||
|
BaseLeft := TmpPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Now check if we are a horizontal or vertical dimension
|
||||||
|
|
||||||
|
// horizontal
|
||||||
|
//
|
||||||
|
//DL____ DR
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// BL BR
|
||||||
|
if DimensionRight.X = BaseRight.X then
|
||||||
|
begin
|
||||||
|
DimensionLeft.X := BaseLeft.X;
|
||||||
|
DimensionLeft.Y := DimensionRight.Y;
|
||||||
|
end
|
||||||
|
// vertical
|
||||||
|
//
|
||||||
|
// BL ----|DR
|
||||||
|
// BR --|DL
|
||||||
|
//
|
||||||
|
// In this case we invert then DR and DL
|
||||||
|
else if DimensionRight.Y = BaseLeft.Y then
|
||||||
|
begin
|
||||||
|
DimensionLeft := DimensionRight;
|
||||||
|
DimensionRight.Y := BaseRight.Y;
|
||||||
|
end
|
||||||
|
// vertical
|
||||||
|
//
|
||||||
|
// BL ----|DL
|
||||||
|
// BR --|DR
|
||||||
|
//
|
||||||
|
else if DimensionRight.Y = BaseRight.Y then
|
||||||
|
begin
|
||||||
|
DimensionLeft.X := DimensionRight.X;
|
||||||
|
DimensionLeft.Y := BaseLeft.Y;
|
||||||
|
end;
|
||||||
|
|
||||||
|
AData.AddAlignedDimension(BaseLeft, BaseRight, DimensionLeft, DimensionRight);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
100 Subclass marker (AcDbEllipse)
|
100 Subclass marker (AcDbEllipse)
|
||||||
10 Center point (in WCS) DXF: X value; APP: 3D point
|
10 Center point (in WCS) DXF: X value; APP: 3D point
|
||||||
@ -547,6 +799,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Position fixing for documents with negative coordinates
|
||||||
|
CenterX := CenterX - DOC_OFFSET.X;
|
||||||
|
CenterY := CenterY - DOC_OFFSET.Y;
|
||||||
|
|
||||||
//
|
//
|
||||||
AData.AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle);
|
AData.AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle);
|
||||||
end;
|
end;
|
||||||
@ -614,6 +870,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Position fixing for documents with negative coordinates
|
||||||
|
PosX := PosX - DOC_OFFSET.X;
|
||||||
|
PosY := PosY - DOC_OFFSET.Y;
|
||||||
|
|
||||||
//
|
//
|
||||||
AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str);
|
AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str);
|
||||||
end;
|
end;
|
||||||
|
@ -39,6 +39,12 @@ const
|
|||||||
STR_WINMETAFILE_EXTENSION = '.wmf';
|
STR_WINMETAFILE_EXTENSION = '.wmf';
|
||||||
|
|
||||||
type
|
type
|
||||||
|
T3DPoint = record
|
||||||
|
X, Y, Z: Double;
|
||||||
|
end;
|
||||||
|
|
||||||
|
P3DPoint = ^T3DPoint;
|
||||||
|
|
||||||
TSegmentType = (
|
TSegmentType = (
|
||||||
st2DLine, st2DBezier,
|
st2DLine, st2DBezier,
|
||||||
st3DLine, st3DBezier, stMoveTo);
|
st3DLine, st3DBezier, stMoveTo);
|
||||||
@ -159,6 +165,17 @@ type
|
|||||||
procedure CalculateBoundingRectangle;
|
procedure CalculateBoundingRectangle;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
}
|
||||||
|
|
||||||
|
{ TvAlignedDimension }
|
||||||
|
|
||||||
|
TvAlignedDimension = class(TvEntity)
|
||||||
|
public
|
||||||
|
// Mandatory fields
|
||||||
|
BaseLeft, BaseRight, DimensionLeft, DimensionRight: T3DPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TvCustomVectorialWriter = class;
|
TvCustomVectorialWriter = class;
|
||||||
@ -216,6 +233,8 @@ type
|
|||||||
procedure AddCircle(ACenterX, ACenterY, ACenterZ, ARadius: Double);
|
procedure AddCircle(ACenterX, ACenterY, ACenterZ, ARadius: Double);
|
||||||
procedure AddCircularArc(ACenterX, ACenterY, ACenterZ, ARadius, AStartAngle, AEndAngle: Double);
|
procedure AddCircularArc(ACenterX, ACenterY, ACenterZ, ARadius, AStartAngle, AEndAngle: Double);
|
||||||
procedure AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle: Double);
|
procedure AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle: Double);
|
||||||
|
// Dimensions
|
||||||
|
procedure AddAlignedDimension(BaseLeft, BaseRight, DimLeft, DimRight: T3DPoint);
|
||||||
{ properties }
|
{ properties }
|
||||||
property PathCount: Integer read GetPathCount;
|
property PathCount: Integer read GetPathCount;
|
||||||
property Paths[Index: Cardinal]: TPath read GetPath;
|
property Paths[Index: Cardinal]: TPath read GetPath;
|
||||||
@ -642,6 +661,19 @@ begin
|
|||||||
FEntities.Add(lEllipse);
|
FEntities.Add(lEllipse);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TvVectorialDocument.AddAlignedDimension(BaseLeft, BaseRight,
|
||||||
|
DimLeft, DimRight: T3DPoint);
|
||||||
|
var
|
||||||
|
lDim: TvAlignedDimension;
|
||||||
|
begin
|
||||||
|
lDim := TvAlignedDimension.Create;
|
||||||
|
lDim.BaseLeft := BaseLeft;
|
||||||
|
lDim.BaseRight := BaseRight;
|
||||||
|
lDim.DimensionLeft := DimLeft;
|
||||||
|
lDim.DimensionRight := DimRight;
|
||||||
|
FEntities.Add(lDim);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Convenience method which creates the correct
|
Convenience method which creates the correct
|
||||||
writer object for a given vector graphics document format.
|
writer object for a given vector graphics document format.
|
||||||
|
@ -11,7 +11,7 @@ uses
|
|||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
Graphics, LCLIntf,
|
Graphics, LCLIntf,
|
||||||
{$else}
|
{$else}
|
||||||
fpcanvas,
|
fpcanvas, fpimage,
|
||||||
{$endif}
|
{$endif}
|
||||||
fpvectorial;
|
fpvectorial;
|
||||||
|
|
||||||
@ -25,6 +25,10 @@ procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
{$ifndef Windows}
|
||||||
|
{$define FPVECTORIALDEBUG}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
|
function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
|
||||||
var
|
var
|
||||||
sinus, cosinus : Extended;
|
sinus, cosinus : Extended;
|
||||||
@ -97,6 +101,17 @@ procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
|
|||||||
ADest: TFPCustomCanvas;
|
ADest: TFPCustomCanvas;
|
||||||
{$endif}
|
{$endif}
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
|
||||||
|
|
||||||
|
function CoordToCanvasX(ACoord: Double): Integer;
|
||||||
|
begin
|
||||||
|
Result := Round(ADestX + AmulX * ACoord);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CoordToCanvasY(ACoord: Double): Integer;
|
||||||
|
begin
|
||||||
|
Result := Round(ADestY + AmulY * ACoord);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i, j, k: Integer;
|
i, j, k: Integer;
|
||||||
PosX, PosY: Integer; // Not modified by ADestX, etc
|
PosX, PosY: Integer; // Not modified by ADestX, etc
|
||||||
@ -113,7 +128,15 @@ var
|
|||||||
CurEntity: TvEntity;
|
CurEntity: TvEntity;
|
||||||
CurCircle: TvCircle;
|
CurCircle: TvCircle;
|
||||||
CurEllipse: TvEllipse;
|
CurEllipse: TvEllipse;
|
||||||
|
//
|
||||||
CurArc: TvCircularArc;
|
CurArc: TvCircularArc;
|
||||||
|
FinalStartAngle, FinalEndAngle, tmpAngle: double;
|
||||||
|
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
|
||||||
|
IntStartAngle, IntAngleLength, IntTmp: Integer;
|
||||||
|
//
|
||||||
|
CurDim: TvAlignedDimension;
|
||||||
|
Points: array of TPoint;
|
||||||
|
UpperDim, LowerDim: T3DPoint;
|
||||||
begin
|
begin
|
||||||
{$ifdef FPVECTORIALDEBUG}
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
WriteLn(':>DrawFPVectorialToCanvas');
|
WriteLn(':>DrawFPVectorialToCanvas');
|
||||||
@ -121,6 +144,7 @@ begin
|
|||||||
|
|
||||||
PosX := 0;
|
PosX := 0;
|
||||||
PosY := 0;
|
PosY := 0;
|
||||||
|
ADest.Brush.Style := bsClear;
|
||||||
|
|
||||||
ADest.MoveTo(ADestX, ADestY);
|
ADest.MoveTo(ADestX, ADestY);
|
||||||
|
|
||||||
@ -138,17 +162,11 @@ begin
|
|||||||
case CurSegment.SegmentType of
|
case CurSegment.SegmentType of
|
||||||
stMoveTo:
|
stMoveTo:
|
||||||
begin
|
begin
|
||||||
ADest.MoveTo(
|
ADest.MoveTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
||||||
Round(ADestX + AMulX * Cur2DSegment.X),
|
|
||||||
Round(ADestY + AMulY * Cur2DSegment.Y)
|
|
||||||
);
|
|
||||||
end;
|
end;
|
||||||
st2DLine, st3DLine:
|
st2DLine, st3DLine:
|
||||||
begin
|
begin
|
||||||
ADest.LineTo(
|
ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
|
||||||
Round(ADestX + AMulX * Cur2DSegment.X),
|
|
||||||
Round(ADestY + AMulY * Cur2DSegment.Y)
|
|
||||||
);
|
|
||||||
end;
|
end;
|
||||||
{ To draw a bezier we need to divide the interval in parts and make
|
{ To draw a bezier we need to divide the interval in parts and make
|
||||||
lines between this parts }
|
lines between this parts }
|
||||||
@ -164,9 +182,7 @@ begin
|
|||||||
t := k / CurveLength;
|
t := k / CurveLength;
|
||||||
CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * Cur2DBSegment.X2 + 3 * t * t * (1 - t) * Cur2DBSegment.X3 + t * t * t * Cur2DBSegment.X);
|
CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * Cur2DBSegment.X2 + 3 * t * t * (1 - t) * Cur2DBSegment.X3 + t * t * t * Cur2DBSegment.X);
|
||||||
CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * Cur2DBSegment.Y2 + 3 * t * t * (1 - t) * Cur2DBSegment.Y3 + t * t * t * Cur2DBSegment.Y);
|
CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * Cur2DBSegment.Y2 + 3 * t * t * (1 - t) * Cur2DBSegment.Y3 + t * t * t * Cur2DBSegment.Y);
|
||||||
ADest.LineTo(
|
ADest.LineTo(CoordToCanvasX(CurX), CoordToCanvasY(CurY));
|
||||||
Round(ADestX + AMulX * CurX),
|
|
||||||
Round(ADestY + AMulY * CurY));
|
|
||||||
end;
|
end;
|
||||||
PosX := Round(Cur2DBSegment.X);
|
PosX := Round(Cur2DBSegment.X);
|
||||||
PosY := Round(Cur2DBSegment.Y);
|
PosY := Round(Cur2DBSegment.Y);
|
||||||
@ -183,10 +199,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
CurCircle := CurEntity as TvCircle;
|
CurCircle := CurEntity as TvCircle;
|
||||||
ADest.Ellipse(
|
ADest.Ellipse(
|
||||||
Round(ADestX + AmulX * (CurCircle.CenterX - CurCircle.Radius)),
|
CoordToCanvasX(CurCircle.CenterX - CurCircle.Radius),
|
||||||
Round(ADestY + AMulY * (CurCircle.CenterY - CurCircle.Radius)),
|
CoordToCanvasY(CurCircle.CenterY - CurCircle.Radius),
|
||||||
Round(ADestX + AmulX * (CurCircle.CenterX + CurCircle.Radius)),
|
CoordToCanvasX(CurCircle.CenterX + CurCircle.Radius),
|
||||||
Round(ADestY + AMulY * (CurCircle.CenterY + CurCircle.Radius))
|
CoordToCanvasY(CurCircle.CenterY + CurCircle.Radius)
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
else if CurEntity is TvEllipse then
|
else if CurEntity is TvEllipse then
|
||||||
@ -198,16 +214,155 @@ begin
|
|||||||
begin
|
begin
|
||||||
CurArc := CurEntity as TvCircularArc;
|
CurArc := CurEntity as TvCircularArc;
|
||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
// ToDo: Consider a X axis inversion
|
||||||
|
// If the Y axis is inverted, then we need to mirror our angles as well
|
||||||
|
BoundsLeft := CoordToCanvasX(CurArc.CenterX - CurArc.Radius);
|
||||||
|
BoundsTop := CoordToCanvasY(CurArc.CenterY - CurArc.Radius);
|
||||||
|
BoundsRight := CoordToCanvasX(CurArc.CenterX + CurArc.Radius);
|
||||||
|
BoundsBottom := CoordToCanvasY(CurArc.CenterY + CurArc.Radius);
|
||||||
|
{if AMulY > 0 then
|
||||||
|
begin}
|
||||||
|
FinalStartAngle := CurArc.StartAngle;
|
||||||
|
FinalEndAngle := CurArc.EndAngle;
|
||||||
|
{end
|
||||||
|
else // AMulY is negative
|
||||||
|
begin
|
||||||
|
// Inverting the angles generates the correct result for Y axis inversion
|
||||||
|
if CurArc.EndAngle = 0 then FinalStartAngle := 0
|
||||||
|
else FinalStartAngle := 360 - 1* CurArc.EndAngle;
|
||||||
|
if CurArc.StartAngle = 0 then FinalEndAngle := 0
|
||||||
|
else FinalEndAngle := 360 - 1* CurArc.StartAngle;
|
||||||
|
end;}
|
||||||
|
IntStartAngle := Round(16*FinalStartAngle);
|
||||||
|
IntAngleLength := Round(16*(FinalEndAngle - FinalStartAngle));
|
||||||
|
// On Gtk2 and Carbon, the Left really needs to be to the Left of the Right position
|
||||||
|
// The same for the Top and Bottom
|
||||||
|
// On Windows it works fine either way
|
||||||
|
// On Gtk2 if the positions are inverted then the arcs are screwed up
|
||||||
|
// In Carbon if the positions are inverted, then the arc is inverted
|
||||||
|
if BoundsLeft > BoundsRight then
|
||||||
|
begin
|
||||||
|
IntTmp := BoundsLeft;
|
||||||
|
BoundsLeft := BoundsRight;
|
||||||
|
BoundsRight := IntTmp;
|
||||||
|
end;
|
||||||
|
if BoundsTop > BoundsBottom then
|
||||||
|
begin
|
||||||
|
IntTmp := BoundsTop;
|
||||||
|
BoundsTop := BoundsBottom;
|
||||||
|
BoundsBottom := IntTmp;
|
||||||
|
end;
|
||||||
// Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer);
|
// Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer);
|
||||||
ADest.Arc(
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
Round(ADestX + AmulX * (CurArc.CenterX - CurArc.Radius)),
|
WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
|
||||||
Round(ADestY + AmulY * (CurArc.CenterY - CurArc.Radius)),
|
[CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
|
||||||
Round(ADestX + AmulX * (CurArc.CenterX + CurArc.Radius)),
|
|
||||||
Round(ADestY + AmulY * (CurArc.CenterY + CurArc.Radius)),
|
|
||||||
Round(16*CurArc.StartAngle),
|
|
||||||
Round(16*CurArc.EndAngle - CurArc.StartAngle)
|
|
||||||
);
|
|
||||||
{$endif}
|
{$endif}
|
||||||
|
ADest.Arc(
|
||||||
|
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
|
||||||
|
IntStartAngle, IntAngleLength
|
||||||
|
);
|
||||||
|
// Debug info
|
||||||
|
// {$define FPVECTORIALDEBUG}
|
||||||
|
// {$ifdef FPVECTORIALDEBUG}
|
||||||
|
// WriteLn(Format('Drawing Arc x1y1=%d,%d x2y2=%d,%d start=%d end=%d',
|
||||||
|
// [BoundsLeft, BoundsTop, BoundsRight, BoundsBottom, IntStartAngle, IntAngleLength]));
|
||||||
|
// {$endif}
|
||||||
|
{ ADest.TextOut(CoordToCanvasX(CurArc.CenterX), CoordToCanvasY(CurArc.CenterY),
|
||||||
|
Format('R=%d S=%d L=%d', [Round(CurArc.Radius*AMulX), Round(FinalStartAngle),
|
||||||
|
Abs(Round((FinalEndAngle - FinalStartAngle)))]));
|
||||||
|
ADest.Pen.Color := TColor($DDDDDD);
|
||||||
|
ADest.Rectangle(
|
||||||
|
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom);
|
||||||
|
ADest.Pen.Color := clBlack;}
|
||||||
|
{$endif}
|
||||||
|
end
|
||||||
|
else if CurEntity is TvAlignedDimension then
|
||||||
|
begin
|
||||||
|
CurDim := CurEntity as TvAlignedDimension;
|
||||||
|
//
|
||||||
|
// Draws this shape:
|
||||||
|
// vertical horizontal
|
||||||
|
// ___
|
||||||
|
// | | or ---| X cm
|
||||||
|
// | --|
|
||||||
|
// Which marks the dimension
|
||||||
|
ADest.MoveTo(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y));
|
||||||
|
ADest.LineTo(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y));
|
||||||
|
ADest.LineTo(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y));
|
||||||
|
ADest.LineTo(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y));
|
||||||
|
// Now the arrows
|
||||||
|
// horizontal
|
||||||
|
SetLength(Points, 3);
|
||||||
|
if CurDim.DimensionRight.Y = CurDim.DimensionLeft.Y then
|
||||||
|
begin
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
ADest.Brush.Color := clBlack;
|
||||||
|
{$else}
|
||||||
|
ADest.Brush.FPColor := colBlack;
|
||||||
|
{$endif}
|
||||||
|
ADest.Brush.Style := bsSolid;
|
||||||
|
// Left arrow
|
||||||
|
Points[0] := Point(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y));
|
||||||
|
Points[1] := Point(Points[0].X + 7, Points[0].Y - 3);
|
||||||
|
Points[2] := Point(Points[0].X + 7, Points[0].Y + 3);
|
||||||
|
ADest.Polygon(Points);
|
||||||
|
// Right arrow
|
||||||
|
Points[0] := Point(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y));
|
||||||
|
Points[1] := Point(Points[0].X - 7, Points[0].Y - 3);
|
||||||
|
Points[2] := Point(Points[0].X - 7, Points[0].Y + 3);
|
||||||
|
ADest.Polygon(Points);
|
||||||
|
ADest.Brush.Style := bsClear;
|
||||||
|
// Dimension text
|
||||||
|
Points[0].X := CoordToCanvasX((CurDim.DimensionLeft.X+CurDim.DimensionRight.X)/2);
|
||||||
|
Points[0].Y := CoordToCanvasY(CurDim.DimensionLeft.Y);
|
||||||
|
LowerDim.X := CurDim.DimensionRight.X-CurDim.DimensionLeft.X;
|
||||||
|
ADest.Font.Size := 10;
|
||||||
|
ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [LowerDim.X]));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
ADest.Brush.Color := clBlack;
|
||||||
|
{$else}
|
||||||
|
ADest.Brush.FPColor := colBlack;
|
||||||
|
{$endif}
|
||||||
|
ADest.Brush.Style := bsSolid;
|
||||||
|
// There is no upper/lower preference for DimensionLeft/Right, so we need to check
|
||||||
|
if CurDim.DimensionLeft.Y > CurDim.DimensionRight.Y then
|
||||||
|
begin
|
||||||
|
UpperDim := CurDim.DimensionLeft;
|
||||||
|
LowerDim := CurDim.DimensionRight;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
UpperDim := CurDim.DimensionRight;
|
||||||
|
LowerDim := CurDim.DimensionLeft;
|
||||||
|
end;
|
||||||
|
// Upper arrow
|
||||||
|
Points[0] := Point(CoordToCanvasX(UpperDim.X), CoordToCanvasY(UpperDim.Y));
|
||||||
|
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y - Round(AMulY*3));
|
||||||
|
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y - Round(AMulY*3));
|
||||||
|
ADest.Polygon(Points);
|
||||||
|
// Lower arrow
|
||||||
|
Points[0] := Point(CoordToCanvasX(LowerDim.X), CoordToCanvasY(LowerDim.Y));
|
||||||
|
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y + Round(AMulY*3));
|
||||||
|
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y + Round(AMulY*3));
|
||||||
|
ADest.Polygon(Points);
|
||||||
|
ADest.Brush.Style := bsClear;
|
||||||
|
// Dimension text
|
||||||
|
Points[0].X := CoordToCanvasX(CurDim.DimensionLeft.X);
|
||||||
|
Points[0].Y := CoordToCanvasY((CurDim.DimensionLeft.Y+CurDim.DimensionRight.Y)/2);
|
||||||
|
LowerDim.Y := CurDim.DimensionRight.Y-CurDim.DimensionLeft.Y;
|
||||||
|
if LowerDim.Y < 0 then LowerDim.Y := -1 * LowerDim.Y;
|
||||||
|
ADest.Font.Size := 10;
|
||||||
|
ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [LowerDim.Y]));
|
||||||
|
end;
|
||||||
|
SetLength(Points, 0);
|
||||||
|
{ // Debug info
|
||||||
|
ADest.TextOut(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y), 'BR');
|
||||||
|
ADest.TextOut(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y), 'DR');
|
||||||
|
ADest.TextOut(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y), 'DL');
|
||||||
|
ADest.TextOut(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y), 'BL');}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -215,10 +370,16 @@ begin
|
|||||||
for i := 0 to ASource.GetTextCount - 1 do
|
for i := 0 to ASource.GetTextCount - 1 do
|
||||||
begin
|
begin
|
||||||
CurText := ASource.GetText(i);
|
CurText := ASource.GetText(i);
|
||||||
ADest.Font.Height := Round(AmulY * CurText.FontSize);
|
ADest.Font.Size := Round(AmulX * CurText.FontSize);
|
||||||
ADest.Pen.Style := psSolid;
|
ADest.Pen.Style := psSolid;
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
ADest.Pen.Color := clBlack;
|
ADest.Pen.Color := clBlack;
|
||||||
ADest.TextOut(Round(CurText.X), Round(CurText.Y), CurText.Value);
|
{$else}
|
||||||
|
ADest.Pen.FPColor := colBlack;
|
||||||
|
{$endif}
|
||||||
|
ADest.Brush.Style := bsClear;
|
||||||
|
LowerDim.Y := CurText.Y + CurText.FontSize;
|
||||||
|
ADest.TextOut(CoordToCanvasX(CurText.X), CoordToCanvasY(LowerDim.Y), CurText.Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifdef FPVECTORIALDEBUG}
|
{$ifdef FPVECTORIALDEBUG}
|
||||||
|
Loading…
Reference in New Issue
Block a user