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 + -
显示快捷键?