?? draw.c
字號:
/*
* Drawing Layer
*
*
* COPYRIGHT (c) 2001 - 2010.
* emTech System Corporation.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE.
*/
/* Huangf emcore@263.net
*/
#include "emGUI.h"
static void
extendrow(int y,int x1,int y1,int x2,int y2, int *minxptr,int *maxxptr);
void GrLine(
WndID id,
GC_ID gc,
int x1,
int y1,
int x2,
int y2,
boolean bDrawLastPoint
)
{
int c, mode;
unsigned short *pmem;
int xdelta; /* width of rectangle around line */
int ydelta; /* height of rectangle around line */
int xinc; /* increment for moving x coordinate */
int yinc; /* increment for moving y coordinate */
int rem; /* current remainder */
c = gc->fcolor;
mode = gc->mode;
pmem = WndDrawMemory(id);
if (pmem == NULL){
return ;
}
if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0)
return;
/* change to absolute cood */
x1 += id->left;
x2 += id->left;
y1 += id->top;
y2 += id->top;
if (x1 == x2){
DrawVertLine(
pmem,
x1,
y1,
y2,
c,
mode
);
return;
}
if (y1 == y2){
DrawHorzLine(
pmem,
x1,
y1,
x2,
c,
mode
);
return;
}
/* The line may be partially obscured. Do the draw line algorithm
* checking each point against the clipping regions.
*/
xdelta = x2 - x1;
ydelta = y2 - y1;
if (xdelta < 0) xdelta = -xdelta;
if (ydelta < 0) ydelta = -ydelta;
xinc = (x2 > x1) ? 1 : -1;
yinc = (y2 > y1) ? 1 : -1;
DrawPixel(
pmem,
x1,
y1,
c,
mode
);
if (xdelta >= ydelta) {
rem = xdelta / 2;
for(;;) {
if(!bDrawLastPoint && x1 == x2)
break;
x1 += xinc;
rem += ydelta;
if (rem >= xdelta) {
rem -= xdelta;
y1 += yinc;
}
DrawPixel(
pmem,
x1,
y1,
c,
mode
);
if(bDrawLastPoint && x1 == x2)
break;
}
}
else {
rem = ydelta / 2;
for(;;) {
if(!bDrawLastPoint && y1 == y2)
break;
y1 += yinc;
rem += xdelta;
if (rem >= ydelta) {
rem -= ydelta;
x1 += xinc;
}
DrawPixel(
pmem,
x1,
y1,
c,
mode
);
if(bDrawLastPoint && y1 == y2)
break;
}
}
}
void GrPoint(
WndID id,
GC_ID gc,
int x,
int y
)
{
int c, mode;
unsigned short *pmem;
if (x < 0 || y < 0)
return;
pmem = WndDrawMemory(id);
if (pmem == NULL){
return;
}
x += id->left;
y += id->top;
c = gc->fcolor;
mode = gc->mode;
DrawPixel(
pmem,
x,
y,
c,
mode
);
}
void GrRect(
WndID id,
GC_ID gc,
int x,
int y,
int width,
int height
)
{
int maxx;
int maxy;
int mode;
unsigned short *pmem;
int c;
pmem = WndDrawMemory(id);
if (pmem == NULL){
return;
}
c = gc->fcolor;
mode = gc->mode;
if (width <= 0 || height <= 0)
return;
x += id->left;
y += id->top;
maxx = x + width - 1;
maxy = y + height - 1;
DrawHorzLine(
pmem,
x,
y,
maxx,
c,
mode
);
if (height > 1)
DrawHorzLine(
pmem,
x,
maxx,
maxy,
c,
mode
);
if (height < 3)
return;
y++;
maxy--;
DrawVertLine(pmem, x, y, maxy, c, mode);
if (width > 1)
DrawVertLine(
pmem,
maxx,
y,
maxy,
c,
mode
);
}
void GrFillRect(
WndID id,
GC_ID gc,
int x,
int y,
int width,
int height
)
{
int x1, y1;
int c;
unsigned short *pmem;
if (id == NULL){
return;
}
if (x < 0 || y < 0 || width < 0 || height < 0){
return;
}
x1 = x + width;
y1 = y + height;
c = gc->fcolor;
pmem = WndDrawMemory(id);
FillRect(
pmem,
x,
y,
x1,
y1,
c
);
}
void GrPoly(
WndID wId,
GID gId,
int count,
LPPOINT points
)
{
int firstx;
int firsty;
int didline;
unsigned short *pmem;
int c, mode;
pmem = WndDrawMemory(wId);
if (pmem == NULL){
return;
}
if (count < 2)
return;
c = gId->fcolor;
mode = gId->mode;
firstx = points->x;
firsty = points->y;
didline = FALSE;
while (count-- > 1) {
if (didline && (gId->mode == GR_XOR))
DrawPixel(pmem, points->x + wId->left, points->y + wId->top, c, mode);
GrLine(wId, gId, points[0].x, points[0].y, points[1].x, points[1].y, TRUE);
points++;
didline = TRUE;
}
if (gId->mode == GR_XOR) {
points--;
if (points->x == firstx && points->y == firsty){
DrawPixel(pmem, points->x + wId->left, points->y + wId->top, c, mode);
}
}
}
/*
* Fill a polygon in the foreground color, applying clipping if necessary.
* The last point may be a duplicate of the first point, but this is
* not required.
* Note: this routine currently only correctly fills convex polygons.
*/
void
GrFillPoly(
WndID wId,
GID gId,
int count,
LPPOINT points)
{
LPPOINT pp; /* current point */
int miny; /* minimum row */
int maxy; /* maximum row */
int minx; /* minimum column */
int maxx; /* maximum column */
int i; /* counter */
unsigned short *pmem;
int c, mode;
pmem = WndDrawMemory(wId);
if (pmem == NULL){
return;
}
if (count <= 0)
return;
c = gId->fcolor;
mode = gId->mode;
/* First determine the minimum and maximum rows for the polygon. */
pp = points;
miny = pp->y;
maxy = pp->y;
for (i = count; i-- > 0; pp++) {
if (miny > pp->y)
miny = pp->y;
if (maxy < pp->y)
maxy = pp->y;
}
if (miny < 0)
miny = 0;
/*
if (maxy >= psd->yvirtres)
maxy = psd->yvirtres - 1;
*/
if (miny > maxy)
return;
/* Now for each row, scan the list of points and determine the
* minimum and maximum x coordinate for each line, and plot the row.
* The last point connects with the first point automatically.
*/
for (; miny <= maxy; miny++) {
minx = 0x0FFFFFFF;
maxx = 0x00000000;
pp = points;
for (i = count; --i > 0; pp++)
extendrow(miny, pp[0].x, pp[0].y, pp[1].x, pp[1].y, &minx, &maxx);
extendrow(miny, pp[0].x, pp[0].y, points[0].x, points[0].y, &minx, &maxx);
if (minx <= maxx){
DrawHorzLine(pmem, minx + wId->left, miny + wId->top, maxx + wId->left, c, mode);
}
}
}
/* Utility routine for filling polygons. Find the intersection point (if
* any) of a horizontal line with an arbitrary line, and extend the current
* minimum and maximum x values as needed to include the intersection point.
* Input parms:
* y row to check for intersection
* x1, y1 first endpoint
* x2, y2 second enpoint
* minxptr address of current minimum x
* maxxptr address of current maximum x
*/
static void
extendrow(
int y,
int x1,
int y1,
int x2,
int y2,
int *minxptr,
int *maxxptr
)
{
int x; /* x coordinate of intersection */
long num; /* numerator of fraction */
/* First make sure the specified line segment includes the specified
* row number. If not, then there is no intersection.
*/
if (((y < y1) || (y > y2)) && ((y < y2) || (y > y1)))
return;
/* If a horizontal line, then check the two endpoints. */
if (y1 == y2) {
if (*minxptr > x1)
*minxptr = x1;
if (*minxptr > x2)
*minxptr = x2;
if (*maxxptr < x1)
*maxxptr = x1;
if (*maxxptr < x2)
*maxxptr = x2;
return;
}
/* If a vertical line, then check the x coordinate. */
if (x1 == x2) {
if (*minxptr > x1)
*minxptr = x1;
if (*maxxptr < x1)
*maxxptr = x1;
return;
}
/* An arbitrary line. Calculate the intersection point using the
* formula x = x1 + (y - y1) * (x2 - x1) / (y2 - y1).
*/
num = ((long) (y - y1)) * (x2 - x1);
x = x1 + num / (y2 - y1);
if (*minxptr > x)
*minxptr = x;
if (*maxxptr < x)
*maxxptr = x;
}
/*
* Draw a rectangular area using the current clipping region and the
* specified bit map. This differs from rectangle drawing in that the
* rectangle is drawn using the foreground color and possibly the background
* color as determined by the bit map. Each row of bits is aligned to the
* next bitmap word boundary (so there is padding at the end of the row).
* The background bit values are only written if the gr_usebg flag
* is set.
*/
void
GrBitmap(
WndID win,
GID gc,
int x,
int y,
int width,
int height,
MWIMAGEBITS *imagebits
)
{
int minx;
int maxx;
MWIMAGEBITS bitvalue = 0; /* bitmap word value */
int bitcount; /* number of bits left in bitmap word */
GrFillRect(win, gc, x, y, width, height);
minx = x;
maxx = x + width - 1;
bitcount = 0;
while (height > 0) {
if (bitcount <= 0) {
bitcount = MWIMAGE_BITSPERIMAGE;
bitvalue = *imagebits++;
}
if (MWIMAGE_TESTBIT(bitvalue)){
GrPoint(win, gc, x, y);
}
bitvalue = MWIMAGE_SHIFTBIT(bitvalue);
bitcount--;
if (x++ == maxx) {
x = minx;
y++;
height--;
bitcount = 0;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -