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

📄 graphic.cpp

📁 一个GNU的开源软件,基于linux下X-Window的flash播放器,工作稳定,方便移植和修改
💻 CPP
字号:
////////////////////////////////////////////////////////////// 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 RCSIDstatic char *rcsid = "$Id: graphic.cc,v 1.1.1.1 2004/06/04 21:17:05 tgc Exp $";#endif#define PRINT 0// PublicGraphicDevice::GraphicDevice(FlashDisplay *fd){	flashDisplay = fd;	bgInitialized = 0;	// Reset flash refresh flag	flashDisplay->flash_refresh = 0;        /* 16 bits, RGB565 */	redMask = 0xF800;	greenMask = 0x07E0;	blueMask = 0x001F;        /* 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;	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;    }}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] = old[i];			newCmp[i].pixel = allocColor(old[i]);		}	}	return newCmp;}longGraphicDevice::getHeight(){	return targetHeight;}longGraphicDevice::getWidth(){	return targetWidth;}ColorGraphicDevice::getForegroundColor(){	return foregroundColor;}voidGraphicDevice::setForegroundColor(Color color){	foregroundColor = color;}ColorGraphicDevice::getBackgroundColor(){	return backgroundColor;}intGraphicDevice::setBackgroundColor(Color color){	if (bgInitialized == 0) {		backgroundColor = color;		clearCanvas();		bgInitialized = 1;		return 1;	}	return 0;}voidGraphicDevice::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;}voidGraphicDevice::setMovieZoom(int z){	z *= FRAC;	if (z <= 0 || z > 100) return;	zoom = z;	setMovieDimension(movieWidth,movieHeight);}voidGraphicDevice::setMovieOffset(long x, long y){	adjust->tx = -zoom*x;	adjust->ty = -zoom*y;}longGraphicDevice::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;}voidGraphicDevice::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);    }}/* polygon rasteriser */inline Segment *GraphicDevice::allocSeg(){    Segment *seg;    if ( (seg_pool_cur - seg_pool) >= NB_SEGMENT_MAX )        return NULL;    seg = seg_pool_cur++;    return seg;}/* add a segment to the current path */voidGraphicDevice::addSegment(long x1, long y1, long x2, long y2,                          FillStyleDef *f0,                          FillStyleDef *f1,                          int aa){    Segment *seg,**segs;    long dX, X, Y, ymin, ymax, tmp;    FillStyleDef *ff;    if ( y1 == y2 ) {        return;    }    if (y1 < y2) {        ymin = y1;        ymax = y2;        ff = f0;        f0 = f1;        f1 = ff;    } else {        ymin = y2;        ymax = y1;        tmp = x1;        x1 = x2;        x2 = tmp;    }    if (ymax>>FRAC_BITS < clip_rect.ymin) {    	return;    }    if (ymin>>FRAC_BITS > clip_rect.ymax) {    	return;    }    X = x1 << SEGFRAC;    dX = ((x2 - x1)<<SEGFRAC)/(ymax-ymin);    if (ymin < 0) {        X += dX * (-ymin);        ymin = 0;    }    Y = (ymin + (FRAC-1)) & ~(FRAC-1);    if (Y > ymax) {        //printf("Elimine @ y = %d   ymin = %d, ymax = %d\n", Y, ymin, seg->ymax);        return;    }    X += dX * (Y-ymin);    Y >>= FRAC_BITS;    if (Y >= clip_rect.ymax) {        return;    }    seg = allocSeg();    if (seg == NULL) {        return;    }    seg->next = 0;    seg->nextValid = 0;    seg->aa = aa;    seg->ymax = ymax;    seg->x1 = x1;    seg->x2 = x2;    seg->X = X;    seg->dX = dX;    seg->fs[0] = f0;    seg->fs[1] = f1;    if (Y < this->ymin) this->ymin = Y;    ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS;    if (ymax >= this->height) ymax = this->height-1;    if (ymax > this->ymax) this->ymax = ymax;    segs = this->segs;    if (segs[Y] == 0) {        segs[Y] = seg;    } else {        Segment *s,*prev;        prev = 0;        for(s = segs[Y]; s; prev = s, s = s->next) {            if (s->X > seg->X) {                if (prev) {                    prev->next = seg;                    seg->next = s;                } else {                    seg->next = segs[Y];                    segs[Y] = seg;                }                break;            }        }        if (s == 0) {            prev->next = seg;            seg->next = s;        }    }}inline Segment *GraphicDevice::progressSegments(Segment * curSegs, long y){    Segment *seg,*prev;    // Update current segments    seg = curSegs;    prev = 0;    while(seg)    {        if ((y*FRAC) > seg->ymax) {            // Remove this segment, no more valid            if (prev) {                prev->nextValid = seg->nextValid;            } else {                curSegs = seg->nextValid;            }            seg = seg->nextValid;        } else {            seg->X += seg->dX * FRAC;            prev = seg;            seg = seg->nextValid;        }    }    return curSegs;}inline Segment *GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs){    Segment *s,*seg,*prev;    s = curSegs;    prev = 0;    // Check for new segments    for (seg = newSegs; seg; seg=seg->next)    {        // Place it at the correct position according to X        if (curSegs == 0) {            curSegs = seg;            seg->nextValid = 0;        } else {            for(; s; prev = s, s = s->nextValid)            {                if ( s->X > seg->X ||                     ( (s->X == seg->X) &&                        ( (seg->x1 == s->x1 && seg->dX < s->dX) ||                         (seg->x2 == s->x2 && seg->dX > s->dX)                         ))) {                    // Insert before s                    if (prev) {                        seg->nextValid = s;                        prev->nextValid = seg;                    } else {                        seg->nextValid = curSegs;                        curSegs = seg;                    }                    break;                }            }            // Append at the end            if (s == 0) {                prev->nextValid = seg;                seg->nextValid = 0;            }        }        s = seg;    }    return curSegs;}#if 0static voidprintSeg(Segment *seg){    /*    printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg,        seg->X>>SEGFRAC,        seg->right ? seg->right->type: -1,        seg->left ? seg->left->color.red : -1,        seg->left ? seg->left->color.green : -1,        seg->left ? seg->left->color.blue : -1,        seg->right ? seg->right->color.red : -1,        seg->right ? seg->right->color.green : -1,        seg->right ? seg->right->color.blue : -1,        seg->x1, seg->x2, seg->ymin, seg->ymax);    */}#endifinline voidGraphicDevice::renderScanLine(long y, Segment *curSegs){    Segment *seg;    long width;    int fi = 1;    FillStyleDef *f;    width = targetWidth * FRAC;    if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) {        fi = 0;    }    for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid)    {        if (seg->nextValid->X <0) continue;        if ((seg->X>>SEGFRAC) > width) break;        f = seg->fs[fi];        if (f) {            switch (f->type) {                case f_Solid:                    if (seg->aa) {                        fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                    } else  {                        fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                    }                    break;                case f_TiledBitmap:                case f_clippedBitmap:                    fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                    break;                case f_LinearGradient:                    fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                    break;                case f_RadialGradient:                    fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                    break;	        case f_None:		    break;            }        }    }}/* draw the current path */voidGraphicDevice::drawPolygon(void){    long y;    Segment *curSegs,*seg;    // no segments ?     if (this->ymax == -1)        return;    // Foreach scanline    curSegs = 0;    for(y=this->ymin; y <= this->ymax; y++) {                // Make X values progess and remove unuseful segments        curSegs = progressSegments(curSegs, y);                // Add the new segment starting at the y position.        curSegs = newSegments(curSegs, this->segs[y]);                // Render the scanline        if (this->scan_line_func == NULL) {            renderScanLine(y, curSegs);        } else {            for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) {                if (seg->nextValid->X >= seg->X) {                    scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);                }            }        }    }    /* free the segments */    memset(this->segs + this->ymin, 0,            (this->ymax - this->ymin + 1) * sizeof(Segment *));             this->ymax = -1;    this->ymin = this->height;    this->seg_pool_cur = this->seg_pool;}voidGraphicDevice::updateClippingRegion(Rect *rect){	if (!clipping) return;	transformBoundingBox(&clip_rect, adjust, rect, 1);	clip_rect.xmin >>= FRAC_BITS;	clip_rect.xmax >>= FRAC_BITS;	clip_rect.ymin >>= FRAC_BITS;	clip_rect.ymax >>= FRAC_BITS;	clip_rect.xmin-=2;	clip_rect.ymin-=2;	clip_rect.xmax+=2;	clip_rect.ymax+=2;	if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin;	if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin;	if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin;	if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;	if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;	if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;	if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;	if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;}voidGraphicDevice::setClipping(int value){	clipping = value;	if (clipping == 0) {		// Reset region		clip_rect.xmin = viewPort.xmin;		clip_rect.xmax = viewPort.xmax;		clip_rect.ymin = viewPort.ymin;		clip_rect.ymax = viewPort.ymax;	}}// VirtualvoidGraphicDevice::clearCanvas(){}longGraphicDevice::allocColor(Color color){	return 0;}voidGraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end){}voidGraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end){}voidGraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end){}voidGraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end){}voidGraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end){}voidGraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width){}

⌨️ 快捷键说明

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