{************************************************************} { 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.