Merge pull request #2443 from realjiangms/fix_region
Incorrect extents calculation in region16_intersect_rect (libfreerdp/codec/region.c)
This commit is contained in:
commit
20433e6f29
@ -132,7 +132,10 @@ static RECTANGLE_16 *region16_extents_noconst(REGION16 *region)
|
||||
|
||||
BOOL rectangle_is_empty(const RECTANGLE_16 *rect)
|
||||
{
|
||||
return (rect->left + rect->top + rect->right + rect->bottom) ? TRUE : FALSE;
|
||||
/* A rectangle with width = 0 or height = 0 should be regarded
|
||||
* as empty.
|
||||
*/
|
||||
return ((rect->left == rect->right) || (rect->top == rect->bottom)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
BOOL region16_is_empty(const REGION16 *region)
|
||||
@ -770,10 +773,21 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
|
||||
usedRects++;
|
||||
dstPtr++;
|
||||
|
||||
newExtents.top = MIN(common.top, newExtents.top);
|
||||
newExtents.left = MIN(common.left, newExtents.left);
|
||||
newExtents.bottom = MAX(common.bottom, newExtents.bottom);
|
||||
newExtents.right = MAX(common.right, newExtents.right);
|
||||
if (rectangle_is_empty(&newExtents))
|
||||
{
|
||||
/* Check if the existing newExtents is empty. If it is empty, use
|
||||
* new common directly. We do not need to check common rectangle
|
||||
* because the rectangles_intersection() ensures that it is not empty.
|
||||
*/
|
||||
newExtents = common;
|
||||
}
|
||||
else
|
||||
{
|
||||
newExtents.top = MIN(common.top, newExtents.top);
|
||||
newExtents.left = MIN(common.left, newExtents.left);
|
||||
newExtents.bottom = MAX(common.bottom, newExtents.bottom);
|
||||
newExtents.right = MAX(common.right, newExtents.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,18 +632,47 @@ static int test_norbert_case() {
|
||||
0, 0, 1920, 1080
|
||||
};
|
||||
RECTANGLE_16 expected_inter_extents = {
|
||||
0, 0, 1920, 1078
|
||||
2, 0, 1920, 1078
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
/*
|
||||
* Consider following as a screen with resolution 1920*1080
|
||||
* | | | | | | |
|
||||
* | |2 |53 |294 |971 |1680 |
|
||||
* | | | | | | |
|
||||
* 0 +=+======================================+======+
|
||||
* | | | |
|
||||
* | | R[0]|
|
||||
* 242 | +-----------+ +------+
|
||||
* | | | | | |
|
||||
* | | | | |
|
||||
* | | R[1]| | R[2]|
|
||||
* 776 | | +-----------+ +------+
|
||||
* | | |
|
||||
* | | R[3]|
|
||||
* 1036 | | +------+
|
||||
* 1040 | +----+
|
||||
* | |R[4]| Union of R[0-4]|
|
||||
* 1078 | +----+ - - - - - - - -+
|
||||
* 1080 |
|
||||
*
|
||||
*
|
||||
* The result is union of R[0] - R[4].
|
||||
* After intersected with the full screen rect, the
|
||||
* result should keep the same.
|
||||
*/
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (!region16_union_rect(®ion, ®ion, &inRectangles[i]))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) )
|
||||
goto out;
|
||||
|
||||
if (!region16_intersect_rect(&intersection, ®ion, &screenRect))
|
||||
goto out;
|
||||
rects = region16_rects(&intersection, &nbRects);
|
||||
@ -660,6 +689,63 @@ out:
|
||||
return retCode;
|
||||
}
|
||||
|
||||
static int test_empty_rectangle() {
|
||||
REGION16 region, intersection;
|
||||
int retCode = -1;
|
||||
int i;
|
||||
|
||||
RECTANGLE_16 emptyRectangles[3] = {
|
||||
{ 0, 0, 0, 0},
|
||||
{ 10, 10, 10, 11},
|
||||
{ 10, 10, 11, 10}
|
||||
};
|
||||
|
||||
RECTANGLE_16 firstRect = {
|
||||
0, 0, 100, 100
|
||||
};
|
||||
RECTANGLE_16 anotherRect = {
|
||||
100, 100, 200, 200
|
||||
};
|
||||
RECTANGLE_16 expected_inter_extents = {
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
region16_init(®ion);
|
||||
region16_init(&intersection);
|
||||
|
||||
/* Check for empty rectangles */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (!rectangle_is_empty(&emptyRectangles[i]))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check for non-empty rectangles */
|
||||
if (rectangle_is_empty(&firstRect))
|
||||
goto out;
|
||||
|
||||
/* Intersect 2 non-intersect rectangle, result should be empty */
|
||||
if (!region16_union_rect(®ion, ®ion, &firstRect))
|
||||
goto out;
|
||||
|
||||
if (!region16_intersect_rect(®ion, ®ion, &anotherRect))
|
||||
goto out;
|
||||
|
||||
if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1) )
|
||||
goto out;
|
||||
|
||||
if (!region16_is_empty(®ion))
|
||||
goto out;
|
||||
|
||||
if (!rectangle_is_empty(region16_extents(&intersection)))
|
||||
goto out;
|
||||
|
||||
retCode = 0;
|
||||
out:
|
||||
region16_uninit(&intersection);
|
||||
region16_uninit(®ion);
|
||||
return retCode;
|
||||
}
|
||||
|
||||
typedef int (*TestFunction)();
|
||||
struct UnitaryTest {
|
||||
@ -680,6 +766,7 @@ struct UnitaryTest tests[] = {
|
||||
{"R1 & R3", test_r1_inter_r3},
|
||||
{"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11},
|
||||
{"norbert case", test_norbert_case},
|
||||
{"empty rectangle case", test_empty_rectangle},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user