124 lines
3.2 KiB
Text
124 lines
3.2 KiB
Text
|
#ifndef __SPANNER_H
|
||
|
#define __SPANNER_H
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int x1, x2;
|
||
|
} Span;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int nspans;
|
||
|
Span spans[100];
|
||
|
} SpanLine;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int width;
|
||
|
int height;
|
||
|
int ngaps;
|
||
|
SpanLine* lines;
|
||
|
} Spanner;
|
||
|
/*******************************************************************************
|
||
|
** InvalidateSpanArray
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
InvalidateSpanArray(SpanLine* dst, int x1, int x2)
|
||
|
{
|
||
|
dst->nspans = 1;
|
||
|
dst->spans[0].x1 = x1;
|
||
|
dst->spans[0].x2 = x2;
|
||
|
}
|
||
|
/*******************************************************************************
|
||
|
** ValidateSpanArray
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
ValidateSpanArray(SpanLine* array, int x1, int x2)
|
||
|
{
|
||
|
Span* span = array->spans;
|
||
|
Span* newspan = &array->spans[array->nspans];
|
||
|
|
||
|
for (int n = array->nspans; n--; span++)
|
||
|
{
|
||
|
if (x1 < span->x2 && x2 > span->x1)
|
||
|
{
|
||
|
if (x1 > span->x1)
|
||
|
{
|
||
|
if (x2 < span->x2)
|
||
|
{
|
||
|
newspan->x1 = x2;
|
||
|
newspan->x2 = span->x2;
|
||
|
newspan++;
|
||
|
array->nspans++;
|
||
|
}
|
||
|
span->x2 = x1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (x2 < span->x2)
|
||
|
{
|
||
|
span->x1 = x2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (Span* s = span; s != newspan; s[0] = s[1], s++);
|
||
|
|
||
|
newspan--;
|
||
|
span--;
|
||
|
array->nspans--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
assert(array->nspans >= 0 && array->nspans < 60);
|
||
|
}
|
||
|
/*******************************************************************************
|
||
|
** SpannerInvalidate
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
SpannerInvalidate(Spanner* spanner)
|
||
|
{
|
||
|
spanner->ngaps = spanner->height;
|
||
|
|
||
|
for (int i = 0; i < spanner->height; i++)
|
||
|
{
|
||
|
InvalidateSpanArray(&spanner->lines[i], 0, spanner->width);
|
||
|
}
|
||
|
}
|
||
|
/*******************************************************************************
|
||
|
** SpannerValidate
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
SpannerValidate(Spanner* spanner, int x1, int y1, int x2, int y2)
|
||
|
{
|
||
|
for (int i = y1; i < y2; i++)
|
||
|
{
|
||
|
ValidateSpanArray(&spanner->lines[i], x1, x2);
|
||
|
|
||
|
if (spanner->lines[i].nspans == 0) spanner->ngaps--;
|
||
|
}
|
||
|
}
|
||
|
/*******************************************************************************
|
||
|
** SpannerCreate
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
SpannerCreate(Spanner* spanner, int width, int height)
|
||
|
{
|
||
|
memset(spanner, 0, sizeof(Spanner));
|
||
|
|
||
|
spanner->width = width;
|
||
|
spanner->height = height;
|
||
|
spanner->lines = (SpanLine*) calloc(height, sizeof(SpanLine));
|
||
|
}
|
||
|
/*******************************************************************************
|
||
|
** SpannerDelete
|
||
|
*******************************************************************************/
|
||
|
inline void
|
||
|
SpannerDelete(Spanner* spanner)
|
||
|
{
|
||
|
free(spanner->lines);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|