📄 hal_draw.c
字号:
/*
**===========================================================================
** HAL_DRAW.C - This file contains all the routines that begin seDraw...
**---------------------------------------------------------------------------
** Copyright (c) 2000, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_DRAW.C=$Revision: 9 $";
/*-------------------------------------------------------------------------*/
void _Swap(long *pa, long *pb)
{
long t;
t = *pa;
*pa = *pb;
*pb = t;
}
/*-------------------------------------------------------------------------*/
/*
** _Line() should be used only to draw diagonal lines
*/
void _Line(DWORD StartLinearAddress, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color, void (*pSetPixel)(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color))
{
long d, dx, dy;
long Aincr, Bincr, xincr, yincr;
long x, y;
dx = x2 - x1;
if (dx < 0)
dx = -dx;
dy = y2 - y1;
if (dy < 0)
dy = -dy;
if (dx > dy)
{
if (x1 > x2)
{
_Swap(&x1, &x2);
_Swap(&y1, &y2);
}
if (y2 > y1)
yincr = 1;
else
yincr = -1;
dx = x2 - x1;
dy = y2 - y1; /* dy = abs(y2 - y1); */
if (dy < 0)
dy = -dy;
d = 2 * dy - dx;
Aincr = 2 * (dy - dx);
Bincr = 2 * dy;
x = x1;
y = y1;
(*pSetPixel)(StartLinearAddress, BytesPerScanline, x, y, color);
for (x = x1 + 1; x <= x2; ++x)
{
if (d >= 0)
{
y += yincr;
d += Aincr;
}
else
d += Bincr;
(*pSetPixel)(StartLinearAddress, BytesPerScanline, x, y, color);
}
}
else
{
if (y1 > y2)
{
_Swap(&x1, &x2);
_Swap(&y1, &y2);
}
if (x2 > x1)
xincr = 1;
else
xincr = -1;
dy = y2 - y1;
dx = x2 - x1; /* dx = abs(x2 - x1); */
if (dx < 0)
dx = -dx;
d = 2 * dx - dy;
Aincr = 2 * (dx - dy);
Bincr = 2 * dx;
x = x1;
y = y1;
(*pSetPixel)(StartLinearAddress, BytesPerScanline, x, y, color);
for (y = y1 + 1; y <= y2; ++y)
{
if (d >= 0)
{
x += xincr;
d += Aincr;
}
else
d += Bincr;
(*pSetPixel)(StartLinearAddress, BytesPerScanline, x, y, color);
}
}
}
/*-------------------------------------------------------------------------*/
/*
** _Set4Pixels() is used by _Ellipse()
*/
void _Set4Pixels(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, long xc, long yc, DWORD color, void (*pSetPixel)(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color))
{
(*pSetPixel)(StartLinearAddress, BytesPerScanline, (long) xc+x, (long) yc+y, color);
(*pSetPixel)(StartLinearAddress, BytesPerScanline, (long) xc-x, (long) yc+y, color);
(*pSetPixel)(StartLinearAddress, BytesPerScanline, (long) xc+x, (long) yc-y, color);
(*pSetPixel)(StartLinearAddress, BytesPerScanline, (long) xc-x, (long) yc-y, color);
}
/*-------------------------------------------------------------------------*/
void _Ellipse(DWORD StartLinearAddress, int BytesPerScanline, long xc, long yc, long a0, long b0, DWORD color, void (*pSetPixel)(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color))
{
long x = 0;
long y = b0;
long a = a0;
long b = b0;
long Asquared = a * a;
long TwoAsquared = 2 * Asquared;
long Bsquared = b * b;
long TwoBsquared = 2 * Bsquared;
long d;
long dx, dy;
d = Bsquared - Asquared*b + Asquared/4L;
dx = 0;
dy = TwoAsquared * b;
while (dx < dy)
{
_Set4Pixels(StartLinearAddress, BytesPerScanline, x, y, xc, yc, color, pSetPixel);
if (d > 0L)
{
--y;
dy -= TwoAsquared;
d -= dy;
}
++x;
dx += TwoBsquared;
d += Bsquared + dx;
}
d += (3L * (Asquared-Bsquared)/2L - (dx+dy)) / 2L;
while (y >= 0)
{
_Set4Pixels(StartLinearAddress, BytesPerScanline, x, y, xc, yc, color, pSetPixel);
if (d < 0L)
{
++x;
dx += TwoBsquared;
d += dx;
}
--y;
dy -= TwoAsquared;
d += Asquared - dy;
}
}
/*-------------------------------------------------------------------------*/
void _Pixel1bpp(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color)
{
unsigned left;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 8);
#ifdef LINEAR_ADDRESSES_SUPPORTED
BYTE *bpt;
#else
BYTE val;
DWORD bpt;
#endif
StartOffset += StartLinearAddress;
color &= 0x01;
#ifdef LINEAR_ADDRESSES_SUPPORTED
bpt = (BYTE*) StartOffset;
#else
bpt = StartOffset;
#endif
color |= (color << 1);
color |= (color << 2);
color |= (color << 4);
left = 0x80 >> (x & 0x07);
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = (BYTE) ((_READXB(bpt) & ~left) | (color & left));
_WRITEXB(bpt, val);
#endif
}
/*-------------------------------------------------------------------------*/
void _Line1bpp(DWORD StartLinearAddress, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color)
{
long y;
long StartOffset = (long)y1 * BytesPerScanline +
(long)(x1 / 8);
#ifdef LINEAR_ADDRESSES_SUPPORTED
BYTE *bpt;
#else
BYTE val;
DWORD bpt;
#endif
StartOffset += StartLinearAddress;
color &= 0x01;
#ifdef LINEAR_ADDRESSES_SUPPORTED
bpt = (BYTE*) StartOffset;
#else
bpt = StartOffset;
#endif
if (y1 == y2) /* horiz. line */
{
unsigned left,right;
long bytes;
color |= (color << 1);
color |= (color << 2);
color |= (color << 4);
left = 0xFF >> (x1 & 0x07);
bytes = x2/8 - x1/8 - 1;
right = 0xFFFF >> ((x2+1) & 0x07);
if (bytes < 0) /* one byte only */
{
right = 0xFFC0 >> (x1 & 0x07);
left &= right;
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = _READXB(bpt);
val &= ~left;
val |= (color & left);
_WRITEXB(bpt, val);
#endif
return;
}
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = _READXB(bpt);
val &= ~left;
val |= (color & left);
_WRITEXB(bpt, val);
#endif
bpt++;
#ifdef LINEAR_ADDRESSES_SUPPORTED
while (bytes-- > 0)
*bpt++ = (BYTE) color;
*bpt &= ~right;
*bpt |= (color & right);
#else
_asmWriteBytes(bpt, (unsigned) color, (DWORD) bytes);
bpt += bytes;
val = _READXB(bpt);
val &= ~right;
val |= (color & right);
_WRITEXB(bpt, val);
#endif
return;
}
if (x1 == x2) /* vert. line */
{
BYTE BitPosition = (BYTE) (7 - (x1 & 0x07));
BYTE mask = (BYTE) (0x01 << BitPosition);
color <<= BitPosition;
for (y = y1; y < y2; y++, bpt += BytesPerScanline)
{
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~mask;
*bpt |= color;
#else
val = _READXB(bpt);
val &= ~mask;
val |= color;
_WRITEXB(bpt, val);
#endif
}
return;
}
}
/*-------------------------------------------------------------------------*/
void _Pixel2bpp(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color)
{
unsigned left, right;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 4);
#ifdef LINEAR_ADDRESSES_SUPPORTED
BYTE *bpt;
#else
BYTE val;
DWORD bpt;
#endif
StartOffset += StartLinearAddress;
color &= 0x03;
#ifdef LINEAR_ADDRESSES_SUPPORTED
bpt = (BYTE*) StartOffset;
#else
bpt = StartOffset;
#endif
color |= (color << 2);
color |= (color << 4);
left = 0xFF >> ((x & 0x3)*2);
right = 0xFFC0 >> ((x & 0x3)*2);
left &= right;
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = (BYTE) ((_READXB(bpt) & ~left) | (color & left));
_WRITEXB(bpt, val);
#endif
}
/*-------------------------------------------------------------------------*/
void _Line2bpp(DWORD StartLinearAddress, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color)
{
long y;
long StartOffset = (long)y1 * BytesPerScanline +
(long)(x1 / 4);
#ifdef LINEAR_ADDRESSES_SUPPORTED
BYTE *bpt;
#else
BYTE val;
DWORD bpt;
#endif
StartOffset += StartLinearAddress;
color &= 0x03;
#ifdef LINEAR_ADDRESSES_SUPPORTED
bpt = (BYTE*) StartOffset;
#else
bpt = StartOffset;
#endif
if (y1 == y2) /* horiz. line */
{
unsigned left,right;
long bytes;
color |= (color << 2);
color |= (color << 4);
left = 0xFF >> ((x1 & 0x3)*2);
bytes = x2/4 - x1/4 - 1;
right = 0xFFFF >> (((x2+1) & 0x3)*2);
if (bytes < 0) /* one byte only */
{
right = 0xFFC0 >> ((x1 & 0x3) * 2);
left &= right;
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = _READXB(bpt);
val &= ~left;
val |= (color & left);
_WRITEXB(bpt, val);
#endif
return;
}
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~left;
*bpt |= (color & left);
#else
val = _READXB(bpt);
val &= ~left;
val |= (color & left);
_WRITEXB(bpt, val);
#endif
bpt++;
#ifdef LINEAR_ADDRESSES_SUPPORTED
while (bytes-- > 0)
*bpt++ = (BYTE) color;
*bpt &= ~right;
*bpt |= (color & right);
#else
_asmWriteBytes(bpt, (unsigned) color, (DWORD) bytes);
bpt += bytes;
val = _READXB(bpt);
val &= ~right;
val |= (color & right);
_WRITEXB(bpt, val);
#endif
return;
}
if (x1 == x2) /* vert. line */
{
BYTE BitPosition = (BYTE) ((3 - (x1 & 0x3)) <<1);
BYTE mask = (BYTE) (0x3 << BitPosition);
color <<= BitPosition;
for (y = y1; y < y2; y++, bpt += BytesPerScanline)
{
#ifdef LINEAR_ADDRESSES_SUPPORTED
*bpt &= ~mask;
*bpt |= color;
#else
val = _READXB(bpt);
val &= ~mask;
val |= color;
_WRITEXB(bpt, val);
#endif
}
return;
}
}
/*-------------------------------------------------------------------------*/
void _Pixel4bpp(DWORD StartLinearAddress, int BytesPerScanline, long x, long y, DWORD color)
{
unsigned left, right;
long bytes;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 2);
#ifdef LINEAR_ADDRESSES_SUPPORTED
BYTE *bpt;
#else
BYTE val;
DWORD bpt;
#endif
StartOffset += StartLinearAddress;
color &= 0x0f;
#ifdef LINEAR_ADDRESSES_SUPPORTED
bpt = (BYTE*) StartOffset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -