UnionRect not ignoring empty input rectangle
Summary
The function UnionRect(R, R1,R2)
calculates the union of the input rectangles R1 and R2 and returns the result in rectangle R.
However, when one of the input rectangles, R1 or R2, is (0,0,0,0) then the top/left corner of the unioned rectangle is (0, 0). Such a rectangle is "empty" as tested by the function IsRectEmpty
. It would be expected that empty rectangles as input parameters are ignored in the calculation.
System Information
- Operating system: Windows
- Processor architecture: x86-64
- Compiler version: FPC main, ccb19859
- Device: Computer
Steps to reproduce
The following example program calculates the union of the rectangles (0,0,0,0) and (10, 10, 20, 30). The function UnionRect
in unit types
reports the union the be (0, 0, 20, 30), but I would expect it to be equal to the non-empty rectangle.
Using the function UnionRect
from the Windows api yields the correct result. Delphi, however, has the same bug as FPC and reports the result as (0, 0, 20, 30).
Example Project
program Project1;
uses
Types;
var
R1, R2, R3: TRect;
begin
R1 := Rect(0, 0, 0, 0);
R2 := Rect(10, 10, 20, 30);
Types.UnionRect(R3, R1, R2);
WriteLn('Left=', R3.Left, ' Top=', R3.Top, ' Right=', R3.Right, ' Bottom=', R3.Bottom);
end.
Possible fixes
The following modified function fixes the issue:
function UnionRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
var
lRect: TRect;
begin
if IsRectEmpty(R1) then
lRect := R2
else
if IsRectEmpty(R2) then
lRect := R1
else
begin
lRect:=R1;
if R2.Left<R1.Left then
lRect.Left:=R2.Left;
if R2.Top<R1.Top then
lRect.Top:=R2.Top;
if R2.Right>R1.Right then
lRect.Right:=R2.Right;
if R2.Bottom>R1.Bottom then
lRect.Bottom:=R2.Bottom;
end;
if IsRectEmpty(lRect) then
begin
FillChar(Rect,SizeOf(Rect),0);
UnionRect:=false;
end
else
begin
Rect:=lRect;
UnionRect:=true;
end;
end;