I don't understand fixed point arithmetic - this fixed that, I hope
This commit is contained in:
parent
d66aa4de24
commit
3996501cf0
|
@ -5,7 +5,7 @@
|
||||||
#include "gfxobj.h"
|
#include "gfxobj.h"
|
||||||
#include "devctxt.h"
|
#include "devctxt.h"
|
||||||
|
|
||||||
inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax)
|
inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
|
||||||
{
|
{
|
||||||
BYTE rc = 0;
|
BYTE rc = 0;
|
||||||
if (y < ymin)
|
if (y < ymin)
|
||||||
|
@ -19,13 +19,19 @@ inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, I
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax)
|
#define CPX 16 /* clipping precision in bits */
|
||||||
|
|
||||||
|
/* these macros keep the number of bits straight when doing fixed-point multiply & divide */
|
||||||
|
#define M(a, b) ((((a) * (b))) >> CPX)
|
||||||
|
#define D(a, b) (((a) << CPX) / (b))
|
||||||
|
|
||||||
|
static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax)
|
||||||
{
|
{
|
||||||
BYTE outcode1, outcode2;
|
BYTE outcode1, outcode2;
|
||||||
INT64 tmp;
|
INT32 tmp;
|
||||||
|
|
||||||
Log(LDEBUG, "clipping line from (%lld, %lld) to (%lld, %lld) against bounding box (%lld, %lld, %lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16,
|
Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX,
|
||||||
xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16);
|
xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX);
|
||||||
|
|
||||||
/* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */
|
/* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -55,47 +61,47 @@ static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT
|
||||||
}
|
}
|
||||||
if (outcode1 & 0x8)
|
if (outcode1 & 0x8)
|
||||||
{
|
{
|
||||||
tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1));
|
tmp = M(x2 - x1, D(ymin - y1, y2 - y1));
|
||||||
x1 += tmp;
|
x1 += tmp;
|
||||||
y1 = ymin;
|
y1 = ymin;
|
||||||
Log(LDEBUG, "clipped against top to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp);
|
Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp);
|
||||||
}
|
}
|
||||||
else if (outcode1 & 0x4)
|
else if (outcode1 & 0x4)
|
||||||
{
|
{
|
||||||
tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1));
|
tmp = M(x2 - x1, D(ymax - y1, y2 - y1));
|
||||||
x1 += tmp;
|
x1 += tmp;
|
||||||
y1 = ymax;
|
y1 = ymax;
|
||||||
Log(LDEBUG, "clipped against bottom to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp);
|
Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp);
|
||||||
}
|
}
|
||||||
else if (outcode1 & 0x2)
|
else if (outcode1 & 0x2)
|
||||||
{
|
{
|
||||||
tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1));
|
tmp = M(y2 - y1, D(xmax - x1, x2 - x1));
|
||||||
y1 -= tmp;
|
y1 -= tmp;
|
||||||
x1 = xmax;
|
x1 = xmax;
|
||||||
Log(LDEBUG, "clipped against right to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp);
|
Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp);
|
||||||
}
|
}
|
||||||
else if (outcode1 & 0x1)
|
else if (outcode1 & 0x1)
|
||||||
{
|
{
|
||||||
tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1));
|
tmp = M(y2 - y1, D(xmin - x1, x2 - x1));
|
||||||
y1 -= tmp;
|
y1 -= tmp;
|
||||||
x1 = xmin;
|
x1 = xmin;
|
||||||
Log(LDEBUG, "clipped against left to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp);
|
Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log(LDEBUG, "final line is from (%lld, %lld) to (%lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16);
|
Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX);
|
||||||
output[0] = (INT32)x1;
|
output[0] = x1;
|
||||||
output[1] = (INT32)y1;
|
output[1] = y1;
|
||||||
output[2] = (INT32)x2;
|
output[2] = x2;
|
||||||
output[3] = (INT32)y2;
|
output[3] = y2;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
|
static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
|
||||||
{
|
{
|
||||||
INT32 buffer[4];
|
INT32 buffer[4];
|
||||||
if (line_clip(buffer, x1 << 16, y1 << 16, x2 << 16, y2 << 16, pdctxt->cliprect.left << 16, pdctxt->cliprect.top << 16,
|
if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX,
|
||||||
pdctxt->cliprect.right << 16, pdctxt->cliprect.bottom << 16))
|
pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX))
|
||||||
return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> 16, buffer[1] >> 16, buffer[2] >> 16, buffer[3] >> 16, pdctxt->color, pdctxt->rop2);
|
return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user