📄 graphic_generic.cc
字号:
////////////////////////////////////////////////////////////// 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"extern unsigned char SQRT[];#define FULL_AA#define PRINT 0typedef unsigned short TYPE;static char cmp8[256]; // 8bit colormaplongallocColor15(Color color){ return (color.red >> 3)<<10 | (color.green>>3)<<5 | (color.blue>>3);}#if 0longallocColor16_646(Color color){ return (color.red >> 2)<<10 | (color.green>>4)<<6 | (color.blue>>2);}#endiflongallocColor16_565(Color color){ return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3);}longallocColor24_32(Color color){ return (color.red)<<16 | (color.green)<<8 | color.blue;}longallocColor8(Color color){ return cmp8[(color.red>>6)<<4 | (color.green>>6)<<2 | (color.blue>>6)];}// PublicGraphicDevice::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 INDEPENDENTColor *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 INDEPENDENTlongGraphicDevice::getHeight(){ return targetHeight;}///////////// PLATFORM INDEPENDENTlongGraphicDevice::getWidth(){ return targetWidth;}///////////// PLATFORM INDEPENDENTColorGraphicDevice::getForegroundColor(){ return foregroundColor;}voidGraphicDevice::setForegroundColor(Color color){ foregroundColor = color;}///////////// PLATFORM INDEPENDENTColorGraphicDevice::getBackgroundColor(){ return backgroundColor;}///////////// PLATFORM INDEPENDENTintGraphicDevice::setBackgroundColor(Color color){ if (bgInitialized == 0) { backgroundColor = color; clearCanvas(); bgInitialized = 1; return 1; } return 0;}///////////// PLATFORM INDEPENDENTvoidGraphicDevice::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 INDEPENDENTvoidGraphicDevice::setMovieZoom(int z){ z *= FRAC; if (z <= 0 || z > 100) return; zoom = z; setMovieDimension(movieWidth,movieHeight);}///////////// PLATFORM INDEPENDENTvoidGraphicDevice::setMovieOffset(long x, long y){ adjust->tx = -zoom*x; adjust->ty = -zoom*y;}///////////// PLATFORM INDEPENDENTvoidGraphicDevice::clearCanvas(){ TYPE pixel; TYPE *point,*p; long h, w,n; if (!bgInitialized) return; pixel = allocColor(backgroundColor); 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 INDEPENDENTlongGraphicDevice::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/* alpha = 0 : select c1, alpha = 255 select c2 */static inline unsigned longmix_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);}voidGraphicDevice::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--; } while (n > 0) { *point = mix_alpha(*point, pixel, alpha); point++; n--; } if (end_alpha > 0) { *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8); } } }}voidGraphicDevice::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 */voidGraphicDevice::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; TYPE *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 = (TYPE *) (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--; } }}voidGraphicDevice::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--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -