prune rects

pull/1/head
cosmonaut 2022-07-21 15:32:56 -07:00
parent 3bcb73267c
commit d86e094933
1 changed files with 73 additions and 24 deletions

View File

@ -297,39 +297,86 @@ void Cram_Internal_PlaceRect(RectPackContext *context, Rect *rect, int32_t freeR
context->freeRectangleCount -= 1; context->freeRectangleCount -= 1;
/* now we maybe have new free rectangles! */ /* now we maybe have new free rectangles! */
/* NOTE: free rectangles can overlap. */
/* Left side */ if (rect->y < freeRect.y + freeRect.h && rect->y + rect->h > freeRect.y)
if (rect->x > freeRect.x && rect->x < freeRect.x + freeRect.w)
{ {
newRect = freeRect; /* Left side */
newRect.w = rect->x - freeRect.x; if (rect->x > freeRect.x && rect->x < freeRect.x + freeRect.w)
Cram_Internal_AddFreeRect(context, newRect); {
newRect = freeRect;
newRect.w = rect->x - freeRect.x;
Cram_Internal_AddFreeRect(context, newRect);
}
/* Right side */
if (rect->x + rect->w < freeRect.x + freeRect.w)
{
newRect = freeRect;
newRect.x = rect->x + rect->w;
newRect.w = freeRect.x + freeRect.w - (rect->x + rect->w);
Cram_Internal_AddFreeRect(context, newRect);
}
} }
/* Right side */ if (rect->x < freeRect.x + freeRect.w && rect->x + rect->w > freeRect.x)
if (rect->x + rect->w < freeRect.x + freeRect.w)
{ {
newRect = freeRect; /* Top side */
newRect.x = rect->x + rect->w; if (rect->y > freeRect.y && rect->y < freeRect.y + freeRect.h)
newRect.w = freeRect.x + freeRect.w - (rect->x + rect->w); {
Cram_Internal_AddFreeRect(context, newRect); newRect = freeRect;
} newRect.h = rect->y - freeRect.y;
Cram_Internal_AddFreeRect(context, newRect);
}
/* Top side */ /* Bottom side */
if (rect->y > freeRect.y && rect->y < freeRect.y + freeRect.h) if (rect->y + rect->h < freeRect.y + freeRect.h)
{ {
newRect = freeRect; newRect = freeRect;
newRect.h = rect->y - freeRect.y; newRect.y = rect->y + rect->h;
Cram_Internal_AddFreeRect(context, newRect); newRect.h = freeRect.y + freeRect.h - (rect->y + rect->h);
Cram_Internal_AddFreeRect(context, newRect);
}
} }
}
/* Bottom side */ static inline uint8_t Cram_Internal_Contains(Rect *a, Rect *b)
if (rect->y + rect->h < freeRect.y + freeRect.h) {
return b->x >= a->x &&
b->y >= a->y &&
b->x + b->w <= a->x + a->w &&
b->y + b->h <= a->y + a->h;
}
void Cram_Internal_PruneRects(RectPackContext *context)
{
int32_t i, j;
Rect *a;
Rect *b;
for (i = context->freeRectangleCount - 1; i >= 0; i -= 1)
{ {
newRect = freeRect; a = &context->freeRectangles[i];
newRect.y = rect->y + rect->h;
newRect.h = freeRect.y + freeRect.h - (rect->y + rect->h); for (j = context->freeRectangleCount - 1; j > i; j -= 1)
Cram_Internal_AddFreeRect(context, newRect); {
b = &context->freeRectangles[j];
if (Cram_Internal_Contains(b, a))
{
/* plug the hole */
context->freeRectangles[j] = context->freeRectangles[context->freeRectangleCount - 1];
context->freeRectangleCount -= 1;
break;
}
if (Cram_Internal_Contains(a, b))
{
/* plug the hole */
context->freeRectangles[j] = context->freeRectangles[context->freeRectangleCount - 1];
context->freeRectangleCount -= 1;
}
}
} }
} }
@ -385,6 +432,8 @@ int8_t Cram_Internal_PackRects(RectPackContext *context, Rect *rects, uint32_t n
/* plug the hole */ /* plug the hole */
rectsToPack[bestRectIndex] = rectsToPack[rectsToPackCount - 1]; rectsToPack[bestRectIndex] = rectsToPack[rectsToPackCount - 1];
rectsToPackCount -= 1; rectsToPackCount -= 1;
Cram_Internal_PruneRects(context);
} }
Cram_free(rectsToPack); Cram_free(rectsToPack);