graphic.cpp
来自「Evc编的一个在wince5.0上运行的flash播放器」· C++ 代码 · 共 1,329 行 · 第 1/3 页
CPP
1,329 行
while (n > 0) {
*point = mix_alpha(*point, pixel, alpha);
point++;
n--;
}
if (end_alpha > 0) {
*point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
}
}
}
}
void
GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line,*point;
TYPE pixel;
unsigned int alpha;
if (clip(y,start,end)) return;
start >>= FRAC_BITS;
end >>= FRAC_BITS;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
n = end-start;
pixel = f->color.pixel;
alpha = f->color.alpha;
if (alpha == ALPHA_OPAQUE) {
while (n--) {
*point = pixel;
point++;
}
} else {
while (n--) {
*point = mix_alpha(*point, pixel, alpha);
point++;
}
}
}
/* 16 bit assumed... easy to change */
void
GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
{
int n;
long x1,y1,dx,dy;
Matrix *m = &f->bitmap_matrix;
Bitmap *b = f->bitmap;
unsigned char *pixels;
unsigned short *p;
Color *cmap;
long pixbpl;
TYPE pixel;
int offset;
unsigned char *alpha_table;
/* safety test) */
if (!b) return;
if (clip(y,start,end)) return;
start /= FRAC;
end /= FRAC;
n = end - start;
p = (unsigned short *) (this->canvasBuffer + this->bpl*y + start * 2);
/* the coordinates in the image are normalized to 16 bits */
x1 = (long) (m->a * start + m->b * y + m->tx);
y1 = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
pixels = b->pixels;
pixbpl = b->bpl;
cmap = f->cmap;
if (b->alpha_buf == NULL) {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
*p = pixel;
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else if (f->alpha_table) {
alpha_table = f->alpha_table;
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
}
}
/* XXX: clipping should be better handled */
void
GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end)
{
long dr,r,v,r2;
register long n;
TYPE *line;
TYPE *point;
Color *cp,*ramp;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
r = (long) (m->a * start + m->b * y + m->tx);
dr = (long) (m->a);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
r2 = r + n * dr;
if ( ((r | r2) & ~255) == 0 ) {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
} else {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
}
}
///////////// PLATFORM INDEPENDENT
void
GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end)
{
long X,dx,r,Y,dy;
long dist2;
register long n;
Color *cp,*ramp;
TYPE *line;
TYPE *point;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
X = (long) (m->a * start + m->b * y + m->tx);
Y = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start == end) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
} else {
if (start_alpha < 255) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
point++;
X += dx;
Y += dy;
n--;
}
#endif /* FULL_AA */
while (n>0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = (TYPE)ramp[r].pixel;
point++;
X += dx;
Y += dy;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
}
}
#endif /* FULL_AA */
} else {
while (n--) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
cp = &ramp[r];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
X += dx;
Y += dy;
}
}
}
void
GraphicDevice::drawBox(long x1, long y1, long x2, long y2)
{
int i;
for(i=0;i<FRAC*2;i++) {
drawLine(x1+i, y1+i, x2-i, y1+i, 0);
drawLine(x1+i, y2-i, x2-i, y2-i, 0);
drawLine(x1+i, y1+i+1, x1+i, y2-i-1, 0);
drawLine(x2-i, y1+i+1, x2-i, y2-i-1, 0);
}
}
/* XXX: should use polygon rasterizer to handle width */
/* XXX: handle only 16 bit case */
/* XXX: must be clipped */
void
GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width)
{
int n,adr,dx,dy,sx,color;
register int a;
register unsigned short *pp;
int alpha;
#if 0
x1 = (x1 + (FRAC/2)) >> FRAC_BITS;
y1 = (y1 + (FRAC/2)) >> FRAC_BITS;
x2 = (x2 + (FRAC/2)) >> FRAC_BITS;
y2 = (y2 + (FRAC/2)) >> FRAC_BITS;
#else
x1 = (x1) >> FRAC_BITS;
y1 = (y1) >> FRAC_BITS;
x2 = (x2) >> FRAC_BITS;
y2 = (y2) >> FRAC_BITS;
#endif
if (y1 > y2 || (y1 == y2 && x1 > x2)) {
long tmp;
tmp=x1;
x1=x2;
x2=tmp;
tmp=y1;
y1=y2;
y2=tmp;
}
if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
if (x1 == x2 && y1 == y2) return; // Bad !!!
if (y1 < clip_rect.ymin && y1 != y2) {
x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
y1 = clip_rect.ymin;
}
if (y2 > clip_rect.ymax && y1 != y2) {
x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
y2 = clip_rect.ymax;
}
if (x1 < x2) {
if (x1 < clip_rect.xmin && x1 != x2) {
y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
x1 = clip_rect.xmin;
}
if (x2 > clip_rect.xmax && x1 != x2) {
y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
x2 = clip_rect.xmax;
}
}
if (x1 > x2) {
if (x2 < clip_rect.xmin && x2 != x1) {
y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
x2 = clip_rect.xmin;
}
if (x1 > clip_rect.xmax && x2 != x1) {
y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
x1 = clip_rect.xmax;
}
}
// Check again
if (x1 == x2 && y1 == y2) return;
if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
sx=bpl >> 1;
adr=(y1 * sx + x1);
pp = (unsigned short *)canvasBuffer + adr;
dx = x2 - x1;
dy = y2 - y1;
color = allocColor16_565(foregroundColor);
alpha = foregroundColor.alpha;
if (alpha == ALPHA_OPAQUE) {
#define PUTPIXEL() \
{ \
*pp=color; \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?