⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphic.cpp

📁 Evc编的一个在wince5.0上运行的flash播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// 
///////////////////////////////////////////////////////////////
//  Author : Olivier Debon  <odebon@club-internet.fr>
//  

#include "swf.h"

#ifdef RCSID
static char *rcsid = "$Id: graphic.cc,v 1.5 1999/09/03 15:17:40 ode Exp $";
#endif

#include "sqrt.h"

#define FULL_AA

#define PRINT 0

typedef unsigned short TYPE;

static char cmp8[256];	// 8bit colormap

static long
allocColor15(Color color)
{
	return (color.red >> 3)<<10 | (color.green>>3)<<5 | (color.blue>>3);
}

#if 0
static long
allocColor16_646(Color color)
{
	return (color.red >> 2)<<10 | (color.green>>4)<<6 | (color.blue>>2);
}
#endif

static long
allocColor16_565(Color color)
{
	return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3);
}

static long
allocColor24_32(Color color)
{
	return (color.red)<<16 | (color.green)<<8 | color.blue;
}

static long
allocColor8(Color color)
{
	return cmp8[(color.red>>6)<<4 | (color.green>>6)<<2 | (color.blue>>6)];
}

// Public

GraphicDevice::GraphicDevice(FlashDisplay *fd)
{
	int depth;

	flashDisplay = fd;

	bgInitialized = 0;

	// Reset flash refresh flag
	flashDisplay->flash_refresh = 0;

        /* 16 bits, RGB565 */
	redMask = 0xF800;
	greenMask = 0x07E0;
	blueMask = 0x001F;
        bpp = 2;
        depth = 16;

        /* should be the actual window size */
	targetWidth = fd->width;
	targetHeight = fd->height;
        bpl = fd->bpl;

#if PRINT
	printf("Target Width  = %d\n", targetWidth);
	printf("Target Height = %d\n", targetHeight);
#endif

	zoom = FRAC;
	movieWidth = targetWidth;
	movieHeight = targetHeight;

	viewPort.xmin = 0;
	viewPort.xmax = targetWidth-1;
	viewPort.ymin = 0;
	viewPort.ymax = targetHeight-1;

	switch (bpp) {
		case 1:
			allocColor = allocColor8;
			redMask = 0xe0;
			greenMask = 0x18;
			blueMask = 0x07;
			break;
		case 2:
			if (depth == 16) {
				allocColor = allocColor16_565;
			} else
			if (depth == 15) {
				allocColor = allocColor15;
			}
			break;
		case 3:
		case 4:
			allocColor = allocColor24_32;
			break;
	}

	canvasBuffer = (unsigned char *) fd->pixels;

	adjust = new Matrix;
	foregroundColor.red = 0;
	foregroundColor.green = 0;
	foregroundColor.blue = 0;
	foregroundColor.alpha = ALPHA_OPAQUE;

	backgroundColor.red = 0;
	backgroundColor.green = 0;
	backgroundColor.blue = 0;
	backgroundColor.alpha = ALPHA_OPAQUE;

	showMore = 0;

	setClipping(0);	// Reset
	setClipping(1);
 
        /* polygon rasterizer : handle memory errors ! */

        height = targetHeight;
        segs = (Segment **)malloc(height * sizeof(Segment *));
        memset(segs, 0, height * sizeof(Segment *));
        ymin = height;
        ymax = -1;

        seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment));
        seg_pool_cur = seg_pool;
}

GraphicDevice::~GraphicDevice()
{
    free(segs);
    free(seg_pool);
    
    if (adjust) {
        delete adjust;
    }
}

///////////// PLATFORM INDEPENDENT
Color *
GraphicDevice::getColormap(Color *old, long n, Cxform *cxform)
{
	Color *newCmp;

	newCmp = new Color[n];
	if (newCmp == NULL) return NULL;

	if (cxform) {
		for(long i = 0; i < n; i++)
		{
			newCmp[i] = cxform->getColor(old[i]);
			newCmp[i].pixel = allocColor(newCmp[i]);
		}
	} else {
		for(long i = 0; i < n; i++)
		{
			newCmp[i].pixel = allocColor(old[i]);
		}
	}

	return newCmp;
}

///////////// PLATFORM INDEPENDENT
long
GraphicDevice::getHeight()
{
	return targetHeight;
}

///////////// PLATFORM INDEPENDENT
long
GraphicDevice::getWidth()
{
	return targetWidth;
}

///////////// PLATFORM INDEPENDENT
Color
GraphicDevice::getForegroundColor()
{
	return foregroundColor;
}

void
GraphicDevice::setForegroundColor(Color color)
{
	foregroundColor = color;
}

///////////// PLATFORM INDEPENDENT
Color
GraphicDevice::getBackgroundColor()
{
	return backgroundColor;
}

///////////// PLATFORM INDEPENDENT
int
GraphicDevice::setBackgroundColor(Color color)
{
	if (bgInitialized == 0) {
		backgroundColor = color;
		clearCanvas();
		bgInitialized = 1;
		return 1;
	}
	return 0;
}

///////////// PLATFORM INDEPENDENT
void
GraphicDevice::setMovieDimension(long width, long height)
{
	float xAdjust, yAdjust;

	movieWidth = width;
	movieHeight = height;

	xAdjust = (float)targetWidth*zoom/(float)width;
	yAdjust = (float)targetHeight*zoom/(float)height;

	if (xAdjust < yAdjust) {
		adjust->a = xAdjust;
		adjust->d = xAdjust;
                adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2;
		viewPort.ymin = adjust->ty/zoom;
		viewPort.ymax = targetHeight-viewPort.ymin-1;
	} else {
		adjust->a = yAdjust;
		adjust->d = yAdjust;
                adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2;
		viewPort.xmin = adjust->tx/zoom;
		viewPort.xmax = targetWidth-viewPort.xmin-1;
	}

	if (viewPort.xmin < 0) viewPort.xmin = 0;
	if (viewPort.ymin < 0) viewPort.ymin = 0;
	if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1;
	if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1;
}

///////////// PLATFORM INDEPENDENT
void
GraphicDevice::setMovieZoom(int z)
{
	// incoming val is 20-based...
	z *= FRAC;
	z /= 20;
	if (z <= 0 || z > 100 * FRAC) return;
	zoom = z;
	setMovieDimension(movieWidth,movieHeight);
}

///////////// PLATFORM INDEPENDENT
void
GraphicDevice::setMovieOffset(long x, long y)
{
	adjust->tx = -zoom*x;
	adjust->ty = -zoom*y;
}

///////////// PLATFORM INDEPENDENT
void
GraphicDevice::clearCanvas()
{
    TYPE  pixel;
    TYPE *point,*p;
    long                 h, w,n;

    if (!bgInitialized) return;

    pixel = allocColor(backgroundColor);

	// The following allows to test clipping
	//for(point = (TYPE *)canvasBuffer,n=0; n<targetHeight*bpl/2; point++,n++) *point = 0xfe00;

    point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
    w = clip_rect.xmax - clip_rect.xmin;
    h = clip_rect.ymax - clip_rect.ymin;

    while (h--) {
        p = point;
        n = w;
        while (n--) {
            *p++ = pixel;
        }

        point = (TYPE *)((char *)point + bpl);
    }

    flashDisplay->flash_refresh = 1;
    flashDisplay->clip_x = clip_rect.xmin;
    flashDisplay->clip_y = clip_rect.ymin;
    flashDisplay->clip_width  = clip_rect.xmax-clip_rect.xmin;
    flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
}

///////////// PLATFORM INDEPENDENT
long
GraphicDevice::clip(long &y, long &start, long &end)
{
    long xmin,xend;

    if (y < clip_rect.ymin ||
        y >= clip_rect.ymax) return 1;
    if (end <= start)
        return 1;
    xmin = clip_rect.xmin * FRAC;
    xend = clip_rect.xmax * FRAC;

    if (end <= xmin || start >= xend) return 1;

    if (start < xmin) start = xmin;
    if (end > xend) end = xend;

    return 0;
}

#define RED_MASK   0xF800
#define GREEN_MASK 0x07E0
#define BLUE_MASK  0x001F

typedef unsigned short TYPE;

/* alpha = 0 : select c1, alpha = 255 select c2 */
static inline unsigned long mix_alpha(unsigned long c1, 
                                      unsigned long c2, int alpha)
{
	long r1,r2,r;
	long g1,g2,g;
	long b1,b2,b;

	r1 = c1 & RED_MASK;
	r2 = c2 & RED_MASK;
	r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;

	g1 = c1 & GREEN_MASK;
	g2 = c2 & GREEN_MASK;
	g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;

	b1 = c1 & BLUE_MASK;
	b2 = c2 & BLUE_MASK;
	b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;

	return (r|g|b);
}

void
GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end)
{
    register long   n;
    TYPE *line;
    TYPE *point,pixel;
    unsigned int alpha, start_alpha,end_alpha;
    
    if (clip(y,start,end)) return;
    
    line = (TYPE *)(canvasBuffer + bpl*y);
    
    alpha = f->color.alpha;
    pixel = f->color.pixel;
    
    if (alpha == ALPHA_OPAQUE) {

        start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
        end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
        
        start >>= FRAC_BITS;
        end >>= FRAC_BITS;
        
        point = &line[start];

        if (start == end) {
            *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
        } else {
            n = end-start;
            if (start_alpha < 255) {
                *point = mix_alpha(*point, pixel, start_alpha);
                point++;
                n--;
            }
            while (n > 0) {
                *point = pixel;
                point++;
                n--;
            }
            if (end_alpha > 0) {
                *point = mix_alpha(*point, pixel, end_alpha);
            }
        }
    } else {

        start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
        end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);

        start >>= FRAC_BITS;
        end >>= FRAC_BITS;
        
        point = &line[start];
        
        if (start == end) {
            *point = mix_alpha(*point, pixel, 
                               ((start_alpha + end_alpha - 255) * alpha) >> 8);
        } else {
            n = end-start;
            if (start_alpha < 255) {
                *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
                point++;
                n--;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -