📄 genfunc.c
字号:
rem -= xdelta;
y1 += yinc;
}
if (psd->ClipPoint(psd, x1, y1))
psd->DrawPixel(psd, x1, y1, psd->gr_foreground);
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;
}
if (psd->ClipPoint(psd, x1, y1))
psd->DrawPixel(psd, x1, y1, psd->gr_foreground);
if(bDrawLastPoint && y1 == y2)
break;
}
}
}
/* Draw a horizontal line from x1 to and including x2 in the
* foreground color, applying clipping if necessary.
*/
static void drawrow(PSD psd, int x1, int x2, int y)
{
int temp;
/* reverse endpoints if necessary*/
if (x1 > x2) {
temp = x1;
x1 = x2;
x2 = temp;
}
/* clip to physical device*/
if ( psd->doclip) {
if ( (x2 < psd->clipminx) || ( x1 >= psd->clipmaxx) )
return;
if ( (y < psd->clipminy) || (y >= psd->clipmaxy) )
return;
if (x2 < psd->clipminx)
return ;
if (x1 >= psd->clipmaxx)
return;
if (x1 < psd->clipminx)
x1 = psd->clipminx;
if (x2 >= psd->clipmaxx)
x2 = psd->clipmaxx - 1;
} else {
if ( (x2 < 0) || ( x1 >= psd->xres) )
return;
if ( (y < 0) || (y >= psd->yres) )
return;
if (x1 < 0)
x1 = 0;
if (x2 >= psd->xres)
x2 = psd->xres - 1;
}
psd->DrawHLine(psd, x1, y, x2-x1+1, psd->gr_foreground);
}
/*
* Draw a vertical line from y1 to and including y2 in the
* foreground color, applying clipping if necessary.
*/
static void drawcol(PSD psd, int x,int y1,int y2)
{
int temp;
/* reverse endpoints if necessary*/
if (y1 > y2) {
temp = y1;
y1 = y2;
y2 = temp;
}
/* clip to physical device*/
if ( psd->doclip) {
if ( (x < psd->clipminx) || ( x >= psd->clipmaxx) )
return;
if ( (y2 < psd->clipminy) || (y1 >= psd->clipmaxy) )
return;
if (y1 < psd->clipminy)
y1 = psd->clipminy;
if (y2 >= psd->clipmaxy)
y2 = psd->clipmaxy - 1;
} else {
if ( (x < 0) || ( x >= psd->xres) )
return;
if ( (y2 < 0) || (y1 >= psd->yres) )
return;
if (y1 < 0)
y1 = 0;
if (y2 >= psd->yres)
y2 = psd->yres - 1;
}
psd->DrawVLine(psd, x, y1, y2-y1+1, psd->gr_foreground);
}
#if 0
void generate_palette(GAL_Color *pal, int num)
{
GAL_Color black = { 0, 0, 0, 0 };
GAL_Color white = { 255, 255, 255, 0 };
GAL_Color blue = { 0, 0, 255, 0 };
GAL_Color yellow = { 255, 255, 0, 0 };
int i, depth, N;
int rnum, gnum, bnum;
int rmask, gmask, bmask;
/* handle small palettes */
if (num == 0) return;
pal[0] = black; if (num == 1) return;
pal[1] = white; if (num == 2) return;
pal[2] = blue; if (num == 3) return;
pal[3] = yellow; if (num == 4) return;
/* handle large palettes. */
depth = 0; /* work out depth so that (1 << depth) >= num */
for (N = num-1; N > 0; N /= 2) {
depth++;
}
gnum = (depth + 2) / 3; /* green has highest priority */
rnum = (depth + 1) / 3; /* red has second highest priority */
bnum = (depth + 0) / 3; /* blue has lowest priority */
gmask = (1 << gnum) - 1;
rmask = (1 << rnum) - 1;
bmask = (1 << bnum) - 1;
for (i=0; i < num; i++) {
/* When num < (1 << depth), we interpolate the values so
* that we still get a good range. There's probably a
* better way...
*/
int j = i * ((1 << depth) - 1) / (num - 1);
int r, g, b;
b = j & bmask; j >>= bnum;
r = j & rmask; j >>= rnum;
g = j & gmask;
pal[i].r = r * 0xffff / rmask;
pal[i].g = g * 0xffff / gmask;
pal[i].b = b * 0xffff / bmask;
pal[i].a = 0;
}
}
#endif
//==================draw a circle =====================================
static inline void setpixel(PSD psd, int x, int y, int c)
{
if( psd->ClipPoint (psd, x, y))
psd->DrawPixel(psd, x, y, c);
}
static void setcirclepixels(PSD psd, int x, int y, int sx, int sy, int c)
{
if ( psd->doclip ) {
int z = MAX (x, y);
if (sx - z < psd->clipminx || sx + z >= psd->clipmaxx || sy - z < psd->clipminy || sy + z >= psd->clipmaxy) {
/* use setpixel clipping */
setpixel(psd, sx + x, sy + y, c);
setpixel(psd, sx - x, sy + y, c);
setpixel(psd, sx + x, sy - y, c);
setpixel(psd, sx - x, sy - y, c);
setpixel(psd, sx + y, sy + x, c);
setpixel(psd, sx - y, sy + x, c);
setpixel(psd, sx + y, sy - x, c);
setpixel(psd, sx - y, sy - x, c);
return;
}
}
psd->DrawPixel(psd, sx + x, sy + y, c);
psd->DrawPixel(psd, sx - x, sy + y, c);
psd->DrawPixel(psd, sx + x, sy - y, c);
psd->DrawPixel(psd, sx - x, sy - y, c);
psd->DrawPixel(psd, sx + y, sy + x, c);
psd->DrawPixel(psd, sx - y, sy + x, c);
psd->DrawPixel(psd, sx + y, sy - x, c);
psd->DrawPixel(psd, sx - y, sy - x, c);
}
void native_gen_circle(PSD psd, int sx, int sy, int r, int c)
{
int x, y, d;
if (r < 1) {
setpixel(psd, sx, sy, c);
return;
}
if (psd->doclip){
if (sx + r < psd->clipminx) return;
if (sx - r >= psd->clipmaxx) return;
if (sy + r < psd->clipminy) return;
if (sy - r >= psd->clipmaxy) return;
}
x = 0;
y = r;
d = 1 - r;
setcirclepixels(psd, x, y, sx, sy, c);
while (x < y) {
if (d < 0)
d += x * 2 + 3;
else {
d += x * 2 - y * 2 + 5;
y--;
}
x++;
setcirclepixels(psd, x, y, sx, sy, c);
}
}
//=================================scale box =================================================
/* scalebox comes from SVGALib, Copyright 1993 Harm Hanemaayer */
typedef unsigned char uchar;
/* We use the 32-bit to 64-bit multiply and 64-bit to 32-bit divide of the */
/* 386 (which gcc doesn't know well enough) to efficiently perform integer */
/* scaling without having to worry about overflows. */
#ifdef USE_ASM
static inline int muldiv64(int m1, int m2, int d)
{
/* int32 * int32 -> int64 / int32 -> int32 */
int result;
__asm__(
"imull %%edx\n\t"
"idivl %3\n\t"
: "=a"(result) /* out */
: "a"(m1), "d"(m2), "g"(d) /* in */
: "ax", "dx" /* mod */
);
return result;
}
#else
static inline int muldiv64 (int m1, int m2, int d)
{
long long int mul = (long long int) m1 * m2;
return (int) (mul / d);
}
#endif
/* This is a DDA-based algorithm. */
/* Iteration over target bitmap. */
int native_gen_scalebox (PSD psd, int w1, int h1, void *_dp1, int w2, int h2, void *_dp2)
{
uchar *dp1 = _dp1;
uchar *dp2 = _dp2;
int xfactor;
int yfactor;
if (w2 == 0 || h2 == 0)
return 0;
xfactor = muldiv64(w1, 65536, w2); /* scaled by 65536 */
yfactor = muldiv64(h1, 65536, h2); /* scaled by 65536 */
switch ((psd->bpp + 7) / 8) {
case 1:
{
int y, sy;
sy = 0;
for (y = 0; y < h2;) {
int sx = 0;
uchar *dp2old = dp2;
int x;
x = 0;
#if 0
while (x < w2 - 8) {
*(dp2 + x) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 1) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 2) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 3) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 4) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 5) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 6) = *(dp1 + (sx >> 16));
sx += xfactor;
*(dp2 + x + 7) = *(dp1 + (sx >> 16));
sx += xfactor;
x += 8;
}
#endif
while (x < w2) {
*(dp2 + x) = *(dp1 + (sx >> 16));
sx += xfactor;
x++;
}
dp2 += w2;
y++;
while (y < h2) {
int l;
int syint = sy >> 16;
sy += yfactor;
if ((sy >> 16) != syint)
break;
/* Copy identical lines. */
l = dp2 - dp2old;
memcpy(dp2, dp2old, l);
dp2old = dp2;
dp2 += l;
y++;
}
dp1 = (uchar *)_dp1 + (sy >> 16) * w1;
}
}
break;
case 2:
{
int y, sy;
sy = 0;
for (y = 0; y < h2;) {
int sx = 0;
uchar *dp2old = dp2;
int x;
x = 0;
/* This can be greatly optimized with loop */
/* unrolling; omitted to save space. */
while (x < w2) {
*(unsigned short *) (dp2 + x * 2) =
*(unsigned short *) (dp1 + (sx >> 16) * 2);
sx += xfactor;
x++;
}
dp2 += w2 * 2;
y++;
while (y < h2) {
int l;
int syint = sy >> 16;
sy += yfactor;
if ((sy >> 16) != syint)
break;
/* Copy identical lines. */
l = dp2 - dp2old;
memcpy(dp2, dp2old, l);
dp2old = dp2;
dp2 += l;
y++;
}
dp1 = (uchar *)_dp1 + (sy >> 16) * w1 * 2;
}
}
break;
case 3:
{
int y, sy;
sy = 0;
for (y = 0; y < h2;) {
int sx = 0;
uchar *dp2old = dp2;
int x;
x = 0;
/* This can be greatly optimized with loop */
/* unrolling; omitted to save space. */
while (x < w2) {
*(unsigned short *) (dp2 + x * 3) =
*(unsigned short *) (dp1 + (sx >> 16) * 3);
*(unsigned char *) (dp2 + x * 3 + 2) =
*(unsigned char *) (dp1 + (sx >> 16) * 3 + 2);
sx += xfactor;
x++;
}
dp2 += w2 * 3;
y++;
while (y < h2) {
int l;
int syint = sy >> 16;
sy += yfactor;
if ((sy >> 16) != syint)
break;
/* Copy identical lines. */
l = dp2 - dp2old;
memcpy(dp2, dp2old, l);
dp2old = dp2;
dp2 += l;
y++;
}
dp1 = (uchar *)_dp1 + (sy >> 16) * w1 * 3;
}
}
break;
case 4:
{
int y, sy;
sy = 0;
for (y = 0; y < h2;) {
int sx = 0;
uchar *dp2old = dp2;
int x;
x = 0;
/* This can be greatly optimized with loop */
/* unrolling; omitted to save space. */
while (x < w2) {
*(unsigned *) (dp2 + x * 4) =
*(unsigned *) (dp1 + (sx >> 16) * 4);
sx += xfactor;
x++;
}
dp2 += w2 * 4;
y++;
while (y < h2) {
int l;
int syint = sy >> 16;
sy += yfactor;
if ((sy >> 16) != syint)
break;
/* Copy identical lines. */
l = dp2 - dp2old;
memcpy(dp2, dp2old, l);
dp2old = dp2;
dp2 += l;
y++;
}
dp1 = (uchar *)_dp1 + (sy >> 16) * w1 * 4;
}
}
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -