upiwin/src/fbprimitive.c

151 lines
2.8 KiB
C
Raw Normal View History

2019-12-07 23:37:21 -07:00
#include <string.h>
#include <alloca.h>
2019-12-06 23:26:13 -07:00
#include "wintype.h"
2019-12-07 23:45:32 -07:00
#include "log.h"
2019-12-06 23:26:13 -07:00
#include "fbinit.h"
2019-12-07 23:37:21 -07:00
#include "fontengine.h"
#include "fbprimitive.h"
2019-12-06 23:26:13 -07:00
inline static PUINT16 loc_from_coords(INT32 x, INT32 y)
{
return Fb_Ptr + (y * Fb_Info->width) + x;
}
UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor)
{
UINT16 rc;
PUINT16 loc = loc_from_coords(x, y);
rc = *loc;
if (xor)
*loc ^= color;
else
*loc = color;
return rc;
}
void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
INT32 tmp;
INT32 dx = x2 - x1;
INT32 dy = y2 - y1;
2019-12-07 13:07:59 -07:00
/* uses Bresenham's line algorithm with fixed-point arithmetic */
2019-12-06 23:26:13 -07:00
if (ABS(dx) < ABS(dy))
{
if (y1 > y2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
x1 <<= 16;
dx = (dx << 16) / dy;
while (y1 <= y2)
{
Fb_setpixel(x1 >> 16, y1, color, xor);
x1 += dx;
y1++;
}
}
else
{
if (x1 > x2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = -dx;
dy = -dy;
}
y1 <<= 16;
dy = dx ? (dy << 16) / dx : 0;
while (x1 <= x2)
{
Fb_setpixel(x1, y1 >> 16, color, xor);
y1 += dy;
x1++;
}
}
}
void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
Fb_line(x1, y1, x2, y1, color, xor);
Fb_line(x2, y1 + 1, x2, y2 - 1, color, xor);
Fb_line(x1, y2, x2, y2, color, xor);
Fb_line(x1, y1 + 1, x1, y2 - 1, color, xor);
2019-12-06 23:26:13 -07:00
}
void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
{
INT32 tmp;
PUINT16 ps, p;
if (x1 > x2)
{
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (y1 > y2)
{
tmp = y1;
y1 = y2;
y2 = tmp;
}
ps = loc_from_coords(x1, y1);
for (; y1 <= y2; y1++)
{
p = ps;
for (tmp = x1; tmp <= x2; tmp++)
{
if (xor)
*p++ ^= color;
else
*p++ = color;
}
ps += Fb_Info->width;
}
}
static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits)
{
INT32 i, j;
BYTE b;
PUINT16 dptr, lbuf;
2019-12-07 23:41:55 -07:00
Log(LDEBUG, "internal_textout(%d, %d, %d, %d, bits)", x, y, width, height);
if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height))
return;
dptr = loc_from_coords(x, y);
lbuf = (PUINT16)alloca(width * sizeof(UINT16));
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
b = *gsbits++;
2019-12-07 23:41:55 -07:00
lbuf[j] = ((UINT16)(b >> 3) & 0x1F) << 11;
lbuf[j] |= ((UINT16)(b >> 2) & 0x3F) << 5;
lbuf[j] |= ((UINT16)(b >> 3) & 0x1F);
}
memcpy(dptr, lbuf, width * sizeof(UINT16));
dptr += Fb_Info->width;
}
}
void Fb_textout(INT32 x, INT32 y, PCSTR pstr)
{
FontEng_do_text_out(x, y, pstr, internal_textout);
}