📄 render_shape.c.svn-base
字号:
#include <math.h>#include <stdlib.h>#include <assert.h>#include "config.h"#include "render_shape.h"#include "render_rend.h"#include "bitmap_def.h"#include "base_types.h"#include "cxform.h"#include "matrix.h"#include "rect.h"#include "xwin_pub.h"#include "instance.h"#if WITH_DMALLOC#include <dmalloc.h>#endifextern player_t *player_p;extern struct savearea *currentpic;#define PRINT 0#define ABS(v) ((v) < 0 ? -(v) : (v))ShapeDef shapedef;//shapedef=(ShapeDef *)malloc(sizeof(ShapeDef));void prepareStyles(GraphicDevice *gd2, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);void clearStyles(GraphicDevice *gd2, FillStyleDef *f, long n);void drawShape(GraphicDevice *gd2, Matrix *matrix1, Cxform *cxform, Shape *shape,ShapeDef *shapedef,ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);void shapeGetBoundingBox(Shape *shape,Rect *bb) { *bb = shape->ShapeBounds;}//shape渲染的入口程序int shapeexecute(GraphicDevice *gd2,Shape *shape, Matrix *matrix, Cxform *cxform) { //ShapeDef *shapedef; //shapedef=(ShapeDef *)malloc(sizeof(ShapeDef)); //if(!shapedef) shapedef.defaultFillStyle.FillStyleType = f_Solid; shapedef.defaultFillStyle.Color.Red = 0; shapedef.defaultFillStyle.Color.Green = 0; shapedef.defaultFillStyle.Color.Blue = 0; shapedef.defaultFillStyle.Color.Alpha = ALPHA_OPAQUE; shapedef.defaultLineStyle.Width = 0; // This is to force a first update shapedef.lastMat.ScaleX = 0; shapedef.lastMat.ScaleY = 0; //shapedef.getStyles = 0; shapedef.getAlpha = 0; if (cxform) { //printf("to cxform side\n"); shapedef.defaultFillStyle.Color = getColor(cxform,getForegroundColor(gd2)); } else { shapedef.defaultFillStyle.Color = getForegroundColor(gd2); } shapedef.defaultFillStyle.Color.pixel = allocColor16(gd2,shapedef.defaultFillStyle.Color); // //printf("to execute \n"); //printf("sscalex is %f,sscaley is %f,srotateskew0 is %f,srotateskew1 is %f,stranslatex is %ld,stranslatey is %ld,\n",matrix->ScaleX,matrix->ScaleY,matrix->RotateSkew0,matrix->RotateSkew1,matrix->TranslateX,matrix->TranslateY); drawShape(gd2, matrix, cxform, shape,&shapedef, ShapeDraw, NULL, 0); return 0;}voidshapeGetRegion(GraphicDevice *gd2, Shape *shape,Matrix *matrix, void *id, ScanLineFunc scan_line_func) { setClipping(gd2,0); //drawShape(gd2,matrix,0,shape,ShapeGetRegion,id,scan_line_func); setClipping(gd2,1);}// 开始一条新的路径static void newPath(ShapeParser *shape,long x,long y ) { Path *p; long x1,y1; p=&shape->curPath; //printf("Scalex is %f scaley is %f Rota0 is %f rota1 is %f tx is %ld ty is %ld\n",shape->matrix->ScaleX,\ shape->matrix->ScaleY,shape->matrix->RotateSkew0,shape->matrix->RotateSkew1,shape->matrix->TranslateX,shape->matrix->TranslateY); x1 = getX(shape->matrix,x, y); y1 = getY(shape->matrix,x, y); p->lastX = x1; p->lastY = y1; //printf("newpath p->lastX is %ld p->lastY is %ld\n",p->lastX, p->lastY); 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; //printf("x is %ld y is %ld \n",x,y); //printf("in addsegment1\n"); if (l) { /* a line is defined ... it will be drawn later */ LineSegment *ls; ls = (LineSegment*) malloc(sizeof(struct 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; } } // //printf("addsegment1 red is %d green is %d blue is %d\n",l->ColorRGB.Red,l->ColorRGB.Green,l->ColorRGB.Blue); /* anti antialiasing not needed if line */ if (!shape->reverse) { // printf("1lastx is %ld last y is %ld x is %ld y is %ld\n",p->lastX,p->lastY,x,y); addSegment(shape->gd,p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1); } else { // printf("2lastx is %ld last y is %ld x is %ld y is %ld\n",p->lastX,p->lastY,x,y); addSegment(shape->gd,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 = getX(shape->matrix,x, y); y1 = getY(shape->matrix,x, y); //printf("aaaaaaaaaaa x1 is %ld y1 is %ld\n",x1,y1); 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 voidbezierBuildPoints (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);}/* 画出当前路径 */void flushPaths(ShapeParser *s){ GraphicDevice *gd2; LineSegment *ls,*lls; struct LineStyle *l; FillStyleDef *linefill; long nx,ny,nn,w; linefill=0; linefill=(FillStyleDef *)malloc(sizeof(FillStyleDef)); linefill->FillStyleType = f_Solid; gd2 = s->gd; drawPolygon(gd2); // return ; ls = s->first_line; if (ls != NULL) { do { l = ls->l; linefill->Color=l->RendColor; w = ABS((long)(s->matrix->ScaleX*l->Width)); if (w <= ((3*FRAC)/2)) { w = FRAC; }#ifdef THIN_LINES if (w <= ((3*FRAC)/2)) { if (gd2->scan_line_func == NULL) { setForegroundColor(gd2,l->fillstyle.color); drawLine(gd2,ls->x1, ls->y1, ls->x2, ls->y2, w); } } else {#else {#endif nx = -(ls->y2 - ls->y1); ny = (ls->x2 - ls->x1); 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; addSegment(gd2,UL, UR, NULL, linefill, 1); addSegment(gd2,LL, LR, linefill, NULL, 1); addSegment(gd2,UR, LR, linefill, NULL, 1); addSegment(gd2,UL, LL, NULL, linefill, 1); drawPolygon1(gd2); } } ls = ls->next; } while (ls != NULL) ; lls = s->first_line; while (lls != NULL) { LineSegment *ls1; assert(lls); //printf("lls is %p\n",lls); ls1 = lls->next; free(lls); lls = ls1; } s->first_line = NULL; s->last_line = NULL; } // printf("out of flushpath\n"); if(linefill) free(linefill);}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 = getX(shape->matrix,ctrlX1, ctrlY1); ctrlY = getY(shape->matrix,ctrlX1, ctrlY1); newX = getX(shape->matrix,newX1, newY1); newY = getY(shape->matrix,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++;}//主要的shape处理和渲染函数void drawShape(GraphicDevice *gd2, Matrix *matrix1, Cxform *cxform, Shape *shape,ShapeDef *shapedef, ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func) { int loop; int endshape; struct StyleChangeRecord *st; struct CurvedEdgeRecord *stc; struct StraightEdgeRecord *sts; LineStyleDef *l; FillStyleDef *f0; FillStyleDef *f1; ShapeRecord sr1,*sr = &sr1; int firstPoint; long lastX,lastY; LineStyleDef *curLineStyle; long curNbLineStyles; FillStyleDef *curFillStyle; long curNbFillStyles; StyleList *sl; ShapeParser sp1,*sp=&sp1; // BitParser *b; Matrix mat,*matrix; mat = MatrixMulti((gd2->adjust) , (matrix1)); matrix = &mat; sp->reverse = (mat.ScaleX * mat.RotateSkew1) < 0; endshape=0; curLineStyle = NULL; curNbLineStyles = 0; curFillStyle = NULL; curNbFillStyles = 0; sp->style_list = NULL; sp->shape = shape; sp->gd = gd2; sp->matrix = matrix; sp->cxform = cxform; // sp->dict = shape->dict; if (shapeAction == ShapeGetRegion) { gd2->scan_line_func = scan_line_func; gd2->scan_line_func_id = id; } else { gd2->scan_line_func = NULL; } if (shapedef->getStyles) { curNbFillStyles=shape->FillStylesP->count; if (curNbFillStyles > 0) { curFillStyle=(FillStyleDef *)malloc(curNbFillStyles*sizeof(FillStyleDef)); if (curFillStyle == NULL) return; for(loop=0;loop<curNbFillStyles;loop++) curFillStyle[loop]=shape->FillStylesP->FillStyles[loop]; }; curNbLineStyles=shape->LineStylesP->count; if (curNbLineStyles > 0) { curLineStyle=(LineStyleDef *)malloc(curNbLineStyles*sizeof(LineStyleDef)); if (curLineStyle == NULL) return; for(loop=0;loop<curNbLineStyles;loop++) { curLineStyle[loop]=shape->LineStylesP->LineStyles[loop]; curLineStyle[loop].RendColor=curLineStyle[loop].ColorRGB; curLineStyle[loop].RendColor.Alpha=255; if (cxform) curLineStyle[loop].RendColor = getColor(cxform,curLineStyle[loop].RendColor); curLineStyle[loop].RendColor.pixel=allocColor16(gd2,curLineStyle[loop].RendColor); } }; //if (curLineStyle == NULL) return; sl = (StyleList*)malloc(sizeof(StyleList)); if (sl == NULL) return; sl->next = NULL; sl->newFillStyles = curFillStyle; sl->nbNewFillStyles = curNbFillStyles; sl->newLineStyles = curLineStyle; sl->nbNewLineStyles = curNbLineStyles; sp->style_list = sl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -