mirror of
http://gitlab.expertsoft.com.ua/git/expertcad
synced 2026-01-11 17:25:39 +02:00
150 lines
3.2 KiB
ObjectPascal
150 lines
3.2 KiB
ObjectPascal
{************************************************************}
|
|
{ Delphi VCL Extensions }
|
|
{ }
|
|
{ Parsing lines by rects }
|
|
{ }
|
|
{ Copyright (c) 2002-2003 SoftGold software company }
|
|
{ }
|
|
{************************************************************}
|
|
|
|
unit Parser;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Classes, Math;
|
|
|
|
type
|
|
PLine = ^TLine;
|
|
TLine = record
|
|
x1, y1, x2, y2: Integer;
|
|
end;
|
|
|
|
PRectangle = ^TRectangle;
|
|
TRectangle = record
|
|
X1, Y1, X2, Y2: Integer;
|
|
end;
|
|
|
|
procedure ClipLine(ALine: TLine; ARect: TRectangle; AParsedLines: TList);
|
|
procedure SwapInts(var A,B);
|
|
|
|
implementation
|
|
|
|
procedure SwapInts(var A,B);
|
|
asm
|
|
MOV ECX,[EAX]
|
|
XCHG ECX,[EDX]
|
|
MOV [EAX],ECX
|
|
end;
|
|
|
|
procedure ClipLine(ALine: TLine; ARect: TRectangle; AParsedLines: TList);
|
|
|
|
function GetYByX(X: Integer): Integer;
|
|
begin
|
|
Result := MaxInt;
|
|
if ((ALine.x1 > X) and (ALine.x2 < X)) or
|
|
((ALine.x1 < X) and (ALine.x2 > X)) then
|
|
Result := ALine.y1 + (ALine.y2 - ALine.y1) * (X - ALine.x1) div
|
|
(ALine.x2 - ALine.x1);
|
|
if (Result < ARect.Y1) or (Result > ARect.Y2) then
|
|
Result := MaxInt;
|
|
end;
|
|
|
|
function GetXByY(Y: Integer): Integer;
|
|
begin
|
|
Result := MaxInt;
|
|
if ((ALine.y1 > Y) and (ALine.y2 < Y)) or
|
|
((ALine.y1 < Y) and (ALine.y2 > Y)) then
|
|
Result := ALine.x1 + (ALine.x2 - ALine.x1) * (Y - ALine.y1)
|
|
div (ALine.y2 - ALine.y1);
|
|
if (Result < ARect.X1) or (Result > ARect.X2) then
|
|
Result := MaxInt;
|
|
end;
|
|
|
|
var
|
|
vInt: Integer;
|
|
P: PLine;
|
|
begin
|
|
vInt := GetYByX(ARect.X1); // left
|
|
if vInt <> MaxInt then
|
|
begin
|
|
New(P);
|
|
P^ := ALine;
|
|
if P.x1 < ARect.X1 then
|
|
begin
|
|
P.x2 := ARect.X1;
|
|
P.y2 := vInt;
|
|
end
|
|
else
|
|
begin
|
|
P.x1 := ARect.X1;
|
|
P.y1 := vInt;
|
|
end;
|
|
AParsedLines.Add(P);
|
|
end;
|
|
|
|
vInt := GetYByX(ARect.X2); // right
|
|
if vInt <> MaxInt then
|
|
begin
|
|
New(P);
|
|
P^ := ALine;
|
|
if P.x1 > ARect.X2 then
|
|
begin
|
|
P.x2 := ARect.X2;
|
|
P.y2 := vInt;
|
|
end
|
|
else
|
|
begin
|
|
P.x1 := ARect.X2;
|
|
P.y1 := vInt;
|
|
end;
|
|
AParsedLines.Add(P);
|
|
end;
|
|
|
|
vInt := GetXByY(ARect.Y1); // top
|
|
if vInt <> MaxInt then
|
|
begin
|
|
New(P);
|
|
P^ := ALine;
|
|
if P.y1 < ARect.Y1 then
|
|
begin
|
|
P.y2 := ARect.Y1;
|
|
P.x2 := vInt;
|
|
end
|
|
else
|
|
begin
|
|
P.y1 := ARect.Y1;
|
|
P.x1 := vInt;
|
|
end;
|
|
AParsedLines.Add(P);
|
|
end;
|
|
|
|
vInt := GetXByY(ARect.Y2); // bottom
|
|
if vInt <> MaxInt then
|
|
begin
|
|
New(P);
|
|
P^ := ALine;
|
|
if P.y1 > ARect.Y2 then
|
|
begin
|
|
P.y2 := ARect.Y2;
|
|
P.x2 := vInt;
|
|
end
|
|
else
|
|
begin
|
|
P.y1 := ARect.Y2;
|
|
P.x1 := vInt;
|
|
end;
|
|
AParsedLines.Add(P);
|
|
end;
|
|
if AParsedLines.Count = 0 then
|
|
if not PtInRect(Rect(ARect.X1 + 1, ARect.Y1 + 1, ARect.X2, ARect.Y2),
|
|
Point(ALine.x1, ALine.y1)) then
|
|
begin
|
|
New(P);
|
|
P^ := ALine;
|
|
AParsedLines.Add(P);
|
|
end;
|
|
end;
|
|
|
|
end.
|