📄 hal_draw.c
字号:
/*
**===========================================================================
** HAL_DRAW.C - This file contains all the routines that begin seDraw...
**---------------------------------------------------------------------------
** Copyright (c) 1997, 1998 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#ifdef INTEL
#include <stdio.h>
#endif
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
extern LPHAL_STRUCT HalInfoArray[MAX_DEVICE];
static const char Revision[] = "HAL_DRAW.C=$Revision: 4 $";
/*-------------------------------------------------------------------------*/
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 StartLogicalAddr, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color, void (*pSetPixel)(DWORD StartLogicalAddr, 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)(StartLogicalAddr, BytesPerScanline, x, y, color);
for (x = x1 + 1; x <= x2; ++x)
{
if (d >= 0)
{
y += yincr;
d += Aincr;
}
else
d += Bincr;
(*pSetPixel)(StartLogicalAddr, 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)(StartLogicalAddr, BytesPerScanline, x, y, color);
for (y = y1 + 1; y <= y2; ++y)
{
if (d >= 0)
{
x += xincr;
d += Aincr;
}
else
d += Bincr;
(*pSetPixel)(StartLogicalAddr, BytesPerScanline, x, y, color);
}
}
}
/*-------------------------------------------------------------------------*/
/*
** Set4Pixels() is used by Ellipse()
*/
void Set4Pixels(DWORD StartLogicalAddr, int BytesPerScanline, long x, long y, long xc, long yc, DWORD color, void (*pSetPixel)(DWORD StartLogicalAddr, int BytesPerScanline, long x, long y, DWORD color))
{
(*pSetPixel)(StartLogicalAddr, BytesPerScanline, (long) xc+x, (long) yc+y, color);
(*pSetPixel)(StartLogicalAddr, BytesPerScanline, (long) xc-x, (long) yc+y, color);
(*pSetPixel)(StartLogicalAddr, BytesPerScanline, (long) xc+x, (long) yc-y, color);
(*pSetPixel)(StartLogicalAddr, BytesPerScanline, (long) xc-x, (long) yc-y, color);
}
/*-------------------------------------------------------------------------*/
void Ellipse(DWORD StartLogicalAddr, int BytesPerScanline, long xc, long yc, long a0, long b0, DWORD color, void (*pSetPixel)(DWORD StartLogicalAddr, 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(StartLogicalAddr, 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(StartLogicalAddr, BytesPerScanline, x, y, xc, yc, color, pSetPixel);
if (d < 0L)
{
++x;
dx += TwoBsquared;
d += dx;
}
--y;
dy -= TwoAsquared;
d += Asquared - dy;
}
}
/*-------------------------------------------------------------------------*/
void Pixel1bpp(DWORD StartLogicalAddr, int BytesPerScanline, long x, long y, DWORD color)
{
UINT left, right;
long bytes;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 8);
BYTE *bpt;
/* for 1bpp, 2bpp, 4bpp & 8bpp:
* bitpos = (PixelsPerByte - x % PixelsPerByte -1)*BitsPerPixel
* for 15bpp & 16 bpp mode, bitpos = 0
*/
StartOffset += StartLogicalAddr;
color &= 0x01;
bpt = (BYTE*) StartOffset;
if (color == 1)
color = 0xFF;
left = 0xFF >> (x & 0x7);
bytes = (x+1)/8 - x/8 - 1;
right = 0xFF >> ((x+1) & 0x7);
right = ~right;
if (bytes < 0)
left &= right;
*bpt &= ~left;
*bpt |= (color & left);
}
/*-------------------------------------------------------------------------*/
/*
** For horizontal/vertical lines only
*/
void Line1bpp(DWORD StartLogicalAddr, int BytesPerScanline,long x1,long y1,long x2,long y2, DWORD color)
{
long y;
long StartOffset = (long)y1 * BytesPerScanline + (long)(x1 / 8);
BYTE *bpt;
/* for 1bpp, 2bpp, 4bpp & 8bpp:
* bitpos = (PixelsPerByte - x % PixelsPerByte -1)*BitsPerPixel
* for 15bpp & 16 bpp mode, bitpos = 0
*/
StartOffset += StartLogicalAddr;
color &= 0x01;
bpt = (BYTE*) StartOffset;
if (y1 == y2) /* horiz. line */
{
UINT left,right;
long bytes;
++x2; /* include the last point in the line */
if (color == 1)
color = 0xFF;
left = 0xFF >> (x1 & 0x7);
bytes = x2/8 - x1/8 - 1;
right = 0xFF >> (x2 & 0x7);
right = ~right;
if (bytes < 0) /* one byte only */
{
left &= right;
*bpt &= ~left;
*bpt |= (color & left);
return;
}
*bpt &= ~left;
*bpt |= (color & left);
bpt++;
while (bytes-- > 0)
*bpt++ = (BYTE) color;
*bpt &= ~right;
*bpt |= (color & right);
return;
}
if (x1 == x2) /* vert. line */
{
BYTE BitPosition = (BYTE) (7 - (x1 & 0x7));
BYTE mask = (BYTE) (0x1 << BitPosition);
color <<= BitPosition;
for (y = y1; y < y2; y++, bpt += BytesPerScanline)
{
*bpt &= ~mask;
*bpt |= color;
}
return;
}
}
/*-------------------------------------------------------------------------*/
void Pixel2bpp(DWORD StartLogicalAddr, int BytesPerScanline, long x, long y, DWORD color)
{
UINT left, right;
long bytes;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 4);
BYTE *bpt;
/* for 1bpp, 2bpp, 4bpp & 8bpp:
* bitpos = (PixelsPerByte - x % PixelsPerByte -1)*BitsPerPixel
* for 15bpp & 16 bpp mode, bitpos = 0
*/
StartOffset += StartLogicalAddr;
color &= 0x03;
bpt = (BYTE*) StartOffset;
color |= (color << 2);
color |= (color << 4);
left = 0xFF >> ((x & 0x3)*2);
bytes = (x+1)/4 - x/4 - 1;
right = 0xFF >> (((x+1) & 0x3)*2);
right = ~right;
if (bytes < 0)
left &= right;
*bpt &= ~left;
*bpt |= (color & left);
}
/*-------------------------------------------------------------------------*/
/*
** For horizontal/vertical lines only
*/
void Line2bpp(DWORD StartLogicalAddr, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color)
{
long y;
long StartOffset = (long)y1 * BytesPerScanline +
(long)(x1 / 4);
BYTE *bpt;
/* for 1bpp, 2bpp, 4bpp & 8bpp:
* bitpos = (PixelsPerByte - x % PixelsPerByte -1)*BitsPerPixel
* for 15bpp & 16 bpp mode, bitpos = 0
*/
StartOffset += StartLogicalAddr;
color &= 0x03;
bpt = (BYTE*) StartOffset;
if (y1 == y2) /* horiz. line */
{
UINT left,right;
long bytes;
++x2; /* include the last point in the line */
color |= (color << 2);
color |= (color << 4);
left = 0xFF >> ((x1 & 0x3)*2);
bytes = x2/4 - x1/4 - 1;
right = 0xFF >> ((x2 & 0x3)*2);
right = ~right;
if (bytes < 0) /* one byte only */
{
left &= right;
*bpt &= ~left;
*bpt |= (color & left);
return;
}
*bpt &= ~left;
*bpt |= (color & left);
bpt++;
while (bytes-- > 0)
*bpt++ = (BYTE) color;
*bpt &= ~right;
*bpt |= (color & right);
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)
{
*bpt &= ~mask;
*bpt |= color;
}
return;
}
}
/*-------------------------------------------------------------------------*/
void Pixel4bpp(DWORD StartLogicalAddr, int BytesPerScanline, long x, long y, DWORD color)
{
UINT left, right;
long bytes;
long StartOffset = (long)y * BytesPerScanline + (long)(x / 2);
BYTE *bpt;
/* for 1bpp, 2bpp, 4bpp & 8bpp:
* bitpos = (PixelsPerByte - x % PixelsPerByte -1)*BitsPerPixel
* for 15bpp & 16 bpp mode, bitpos = 0
*/
StartOffset += StartLogicalAddr;
color &= 0x0f;
bpt = (BYTE*) StartOffset;
color |= (color << 4);
left = 0xFF >> ((x & 0x1)*4);
bytes = (x+1)/2 - x/2 - 1;
right = 0xFF >> (((x+1) & 0x1)*4);
right = ~right;
if (bytes < 0)
left &= right;
*bpt &= ~left;
*bpt |= (color & left);
}
/*-------------------------------------------------------------------------*/
/*
** For horizontal/vertical lines only
*/
void Line4bpp(DWORD StartLogicalAddr, int BytesPerScanline, long x1, long y1, long x2, long y2, DWORD color)
{
long y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -