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

📄 shape.cpp

📁 Evc编的一个在wince5.0上运行的flash播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 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: shape.cc,v 1.5 1999/09/10 13:08:52 ode Exp $";
#endif

#define PRINT 0

#define ABS(v) ((v) < 0 ? -(v) : (v))

static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);

static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n);

static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
                      ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);

// Constructor

Shape::Shape(long id, int level) : Character(ShapeType, id)
{
    defLevel = level;

    defaultFillStyle.type = f_Solid;
    defaultFillStyle.color.red = 0;
    defaultFillStyle.color.green = 0;
    defaultFillStyle.color.blue = 0;
    defaultFillStyle.color.alpha = ALPHA_OPAQUE;

    defaultLineStyle.width = 0;

    // This is to force a first update
    lastMat.a = 0;
    lastMat.d = 0;
    shape_size += sizeof(Shape);
    shape_nb ++;

    file_ptr = NULL;
    getStyles = 0;
    getAlpha = 0;
}

Shape::~Shape()
{
	if (file_ptr) {
		free(file_ptr);
	}
}

void
Shape::setBoundingBox(Rect rect)
{
    boundary = rect;
}

void
Shape::getBoundingBox(Rect *bb, DisplayListEntry *e)
{
    *bb =  boundary;
}

int
Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
{
    //printf("TagId = %d\n", getTagId());
    //if (getTagId() != 220) return 0;

    if (cxform) {
        defaultFillStyle.color = cxform->getColor(gd->getForegroundColor());
    } else {
        defaultFillStyle.color = gd->getForegroundColor();
    }
    defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color);

    drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0);
    return 0;
}

void
Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
{
    gd->setClipping(0);
    drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func);
    gd->setClipping(1);
}

/************************************************************************/

/* create a new path */

static void newPath(ShapeParser *shape,
                    long x, long y)
{
    Path *p;
    long x1,y1;

    p=&shape->curPath;
    
    x1 = shape->matrix->getX(x, y);
    y1 = shape->matrix->getY(x, y);

    p->lastX = x1;
    p->lastY = y1;

    p->nb_edges = 0;
    p->nb_segments = 0;
}


static void addSegment1(ShapeParser *shape,
                        long x, long y,
                        FillStyleDef *f0,
                        FillStyleDef *f1,
                        LineStyleDef *l)
{
    Path *p;
    p=&shape->curPath;

    if (l) {
        /* a line is defined ... it will be drawn later */
        LineSegment *ls;

        ls = new LineSegment;
	if (ls != NULL) {
		ls->l = l;
		ls->x1 = p->lastX;
		ls->y1 = p->lastY;
		ls->x2 = x;
		ls->y2 = y;
		ls->first = (p->nb_segments == 0);
		ls->next = NULL;
		if (shape->last_line == NULL) {
		    shape->first_line = ls;
		} else {
		    shape->last_line->next = ls;
		}
		shape->last_line = ls;
	}
    }

    /* anti antialiasing not needed if line */
    if (!shape->reverse) {
        shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1);
    } else {
        shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1);
    }

    p->lastX = x;
    p->lastY = y;

    p->nb_segments++;
}


static void addLine(ShapeParser *shape, long x, long y,
                    FillStyleDef *f0,
                    FillStyleDef *f1,
                    LineStyleDef *l)
{
    long x1,y1;
    Path *p;

    p=&shape->curPath;

    x1 = shape->matrix->getX(x, y);
    y1 = shape->matrix->getY(x, y);
    
    addSegment1(shape,x1,y1,f0,f1,l);

    p->nb_edges++;
}


// This is based on Divide and Conquer algorithm.

#define BFRAC_BITS  0
#define BFRAC       (1 << BFRAC_BITS)

static void
bezierBuildPoints (ShapeParser *s,
                   int subdivisions,
                   long a1X, long a1Y,
                   long cX, long cY,
                   long a2X, long a2Y)
{
    long c1X,c1Y;
    long c2X,c2Y;
    long X,Y;
    long xmin,ymin,xmax,ymax;

    if (subdivisions != 0) {

        /* find the bounding box */

        if (a1X < cX) {
            xmin = a1X;
            xmax = cX;
        } else {
            xmin = cX;
            xmax = a1X;
        }
        if (a2X < xmin) xmin = a2X;
        if (a2X > xmax) xmax = a2X;
        
        if (a1Y < cY) {
            ymin = a1Y;
            ymax = cY;
        } else {
            ymin = cY;
            ymax = a1Y;
        }
        if (a2Y < ymin) ymin = a2Y;
        if (a2Y > ymax) ymax = a2Y;
    
        if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) {
            // Control point 1
            c1X = (a1X+cX) >> 1;
            c1Y = (a1Y+cY) >> 1;
            
            // Control point 2
            c2X = (a2X+cX) >> 1;
            c2Y = (a2Y+cY) >> 1;
            
            // New point
            X = (c1X+c2X) >> 1;
            Y = (c1Y+c2Y) >> 1;
            
            subdivisions--;

            bezierBuildPoints(s, subdivisions, 
                              a1X, a1Y, c1X, c1Y, X, Y);
            bezierBuildPoints(s, subdivisions, 
                              X, Y, c2X, c2Y, a2X, a2Y);
            
            return;
        }
    }
            
    addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS, 
                (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l);
}

/* this code is broken, but useful to get something */
static void flushPaths(ShapeParser *s)
{
    LineSegment *ls;
    LineStyleDef *l;
    long nx,ny,nn,w;
    GraphicDevice *gd = s->gd;

    /* draw the filled polygon */
    gd->drawPolygon();
    
    /* draw the lines */
    ls = s->first_line;
    if (ls != NULL) {
        do {
            l = ls->l;

#if 0
            printf("line %d %d %d %d width=%d\n",
                   ls->x1, ls->y1, ls->x2, ls->y2, l->width);
#endif

            /* XXX: this width is false, but it is difficult (and expensive)
               to have the correct one */
            w = ABS((long)(s->matrix->a * l->width));

            if (w <= ((3*FRAC)/2)) {
	    	w = FRAC;
	    }
#ifdef THIN_LINES
            if (w <= ((3*FRAC)/2)) {
                // draw the thin lines only in shapeAction == shapeDraw
                if (gd->scan_line_func == NULL) {
                    gd->setForegroundColor(l->fillstyle.color);
                    gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w);
                }
            } else {
#else
	    {
#endif
                /* compute the normal vector */
                
                nx = -(ls->y2 - ls->y1);
                ny = (ls->x2 - ls->x1);
                
                /* normalize & width */
                nn = 2 * (long) sqrt(nx * nx + ny * ny);
                
#define UL ls->x1 + nx -ny, ls->y1 + ny +nx
#define UR ls->x2 + nx +ny, ls->y2 + ny -nx
#define LL ls->x1 - nx -ny, ls->y1 - ny +nx
#define LR ls->x2 - nx +ny, ls->y2 - ny -nx

                if (nn > 0) {
                    nx = (nx * w) / nn;
                    ny = (ny * w) / nn;
                    
                    /* top segment */
                    gd->addSegment(UL, UR, NULL, &l->fillstyle, 1);
                    
                    /* bottom segment */
                    gd->addSegment(LL, LR, &l->fillstyle, NULL, 1);
                
                    /* right segment */
                    gd->addSegment(UR, LR, &l->fillstyle, NULL, 1);
                
                    /* left segment */
                    gd->addSegment(UL, LL, NULL, &l->fillstyle, 1);
                
                    /* draw the line polygon */
                    gd->drawPolygon();
                }
            }
                
            ls = ls->next;
        } while (ls != NULL);
        
        /* delete the line structures */

        ls = s->first_line;
        while (ls != NULL) {
            LineSegment *ls1;
            ls1 = ls->next;
            delete ls;
            ls = ls1;
        }

        /* reset the line pointers */
        s->first_line = NULL;
        s->last_line = NULL;
    }
}


static void addBezier(ShapeParser *shape, 
                      long ctrlX1, long ctrlY1,
                      long newX1, long newY1,
                      FillStyleDef *f0,
                      FillStyleDef *f1,
                      LineStyleDef *l)
{
    long newX,newY,ctrlX,ctrlY;
    Path *p;

    p=&shape->curPath;

    /* note: we do the matrix multiplication before calculating the
       bezier points (faster !) */

    ctrlX = shape->matrix->getX(ctrlX1, ctrlY1);
    ctrlY = shape->matrix->getY(ctrlX1, ctrlY1);
    newX = shape->matrix->getX(newX1, newY1);
    newY = shape->matrix->getY(newX1, newY1);

    shape->f0 = f0;
    shape->f1 = f1;
    shape->l = l;

    bezierBuildPoints(shape, 3,
                      p->lastX<<BFRAC_BITS,p->lastY<<BFRAC_BITS,
                      ctrlX<<BFRAC_BITS,ctrlY<<BFRAC_BITS,
                      newX<<BFRAC_BITS,newY<<BFRAC_BITS);

    p->nb_edges++;
}

/***********************************************************************/


/* bit parser */

static void InitBitParser(struct BitParser *b,U8 *buf) 
{
    b->ptr = buf;
}

static void InitBits(struct BitParser *b)
{
    // Reset the bit position and buffer.

⌨️ 快捷键说明

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