📄 graphic.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 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 + -