2025-05-12 10:07:51 +03:00

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.