📄 shape.cpp
字号:
StyleList *sl;
ShapeParser sp1,*sp=&sp1;
BitParser *b;
Matrix mat,*matrix;
mat = (*gd->adjust) * (*matrix1);
matrix = &mat;
sp->reverse = (mat.a * mat.d) < 0;
curLineStyle = NULL;
curNbLineStyles = 0;
curFillStyle = NULL;
curNbFillStyles = 0;
sp->style_list = NULL;
sp->shape = shape;
sp->gd = gd;
sp->matrix = matrix;
sp->cxform = cxform;
sp->dict = shape->dict;
if (shapeAction == ShapeGetRegion) {
gd->scan_line_func = scan_line_func;
gd->scan_line_func_id = id;
} else {
gd->scan_line_func = NULL;
}
b = &sp->bit_parser;
InitBitParser(b,shape->file_ptr);
if (shape->getStyles) {
// ShapeWithStyle
curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha);
if (curFillStyle == NULL) return;
curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha);
if (curLineStyle == NULL) return;
sl = new StyleList;
if (sl == NULL) return;
sl->next = NULL;
sl->newFillStyles = curFillStyle;
sl->nbNewFillStyles = curNbFillStyles;
sl->newLineStyles = curLineStyle;
sl->nbNewLineStyles = curNbLineStyles;
sp->style_list = sl;
if (shapeAction == ShapeDraw) {
prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
}
}
InitBits(b);
sp->m_nFillBits = (U16) GetBits(b,4);
sp->m_nLineBits = (U16) GetBits(b,4);
l = 0;
f0 = 0;
f1 = 0;
firstPoint = 1;
lastX = 0;
lastY = 0;
sp->curPath.nb_edges = 0;
sp->first_line = NULL;
sp->last_line = NULL;
for(;;) {
if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break;
switch (sr->type)
{
case shapeNonEdge:
if (sr->flags & flagsNewStyles) {
curFillStyle = sr->newFillStyles;
curNbFillStyles = sr->nbNewFillStyles;
curLineStyle = sr->newLineStyles;
curNbLineStyles = sr->nbNewLineStyles;
sl = new StyleList;
sl->next = sp->style_list;
sl->newFillStyles = sr->newFillStyles;
sl->nbNewFillStyles = sr->nbNewFillStyles;
sl->newLineStyles = sr->newLineStyles;
sl->nbNewLineStyles = sr->nbNewLineStyles;
sp->style_list = sl;
if (shapeAction == ShapeDraw) {
prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
}
}
if (sr->flags & flagsFill0) {
if (sr->fillStyle0) {
if (curFillStyle) {
f0 = &curFillStyle[sr->fillStyle0-1];
} else {
f0 = &shape->defaultFillStyle;
}
} else {
f0 = 0;
}
}
if (sr->flags & flagsFill1) {
if (sr->fillStyle1) {
if (curFillStyle) {
f1 = &curFillStyle[sr->fillStyle1-1];
} else {
f1 = &shape->defaultFillStyle;
}
} else {
f1 = 0;
}
}
if (sr->flags & flagsLine) {
if (sr->lineStyle) {
l = &curLineStyle[sr->lineStyle-1];
} else {
l = 0;
}
}
if (sr->flags & flagsMoveTo) {
if (sp->curPath.nb_edges == 0) {
/* if no edges, draw the polygon, then the lines */
flushPaths(sp);
}
newPath(sp, sr->x, sr->y);
firstPoint = 0;
lastX = sr->x;
lastY = sr->y;
#if PRINT
printf("---------\nX,Y = %4d,%4d\n", sr->x/20, sr->y/20);
#endif
}
break;
case shapeCurve:
// Handle Bezier Curves !!!
if (firstPoint) {
newPath(sp, 0, 0);
firstPoint = 0;
}
{
long newX,newY,ctrlX,ctrlY;
ctrlX = lastX+sr->ctrlX;
ctrlY = lastY+sr->ctrlY;
newX = ctrlX+sr->anchorX;
newY = ctrlY+sr->anchorY;
#if 1
addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l);
#else
addLine(sp, newX, newY, f0, f1, l);
#endif
lastX = newX;
lastY = newY;
}
break;
case shapeLine:
if (firstPoint) {
newPath(sp, 0, 0);
firstPoint = 0;
}
lastX += sr->dX;
lastY += sr->dY;
addLine(sp, lastX, lastY, f0, f1, l);
#if PRINT
printf(" X, Y = %4d,%4d\n", lastX/20, lastY/20);
#endif
break;
}
}
/* XXX: should test if there is something to draw */
flushPaths(sp);
/* free the styles */
while (sp->style_list) {
StyleList *sl;
sl=sp->style_list;
sp->style_list = sl->next;
if (shapeAction == ShapeDraw) {
clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles);
}
delete[] sl->newFillStyles;
delete[] sl->newLineStyles;
delete sl;
}
}
static void
prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform,
FillStyleDef *ftab, long n)
{
long fs;
FillStyleDef *f;
for(fs = 0; fs < n; fs++)
{
f = ftab + fs;
switch (f->type)
{
case f_None:
break;
case f_Solid:
if (cxform) {
f->color = cxform->getColor(f->color);
}
f->color.pixel = gd->allocColor(f->color);
break;
case f_LinearGradient:
case f_RadialGradient:
{
Matrix mat;
int n,r,l;
long red, green, blue, alpha;
long dRed, dGreen, dBlue, dAlpha;
long min,max;
Matrix *m;
mat = *(matrix) * f->matrix;
// Compute inverted matrix
f->gradient.imat = mat.invert();
/* renormalize the matrix */
m=&f->gradient.imat;
if (f->type == f_LinearGradient) {
m->a = m->a * FRAC * (1/128.0) * 65536.0;
m->b = m->b * FRAC * (1/128.0) * 65536.0;
m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0);
} else {
m->a = m->a * FRAC * (1/64.0) * 65536.0;
m->b = m->b * FRAC * (1/64.0) * 65536.0;
m->c = m->c * FRAC * (1/64.0) * 65536.0;
m->d = m->d * FRAC * (1/64.0) * 65536.0;
m->tx = (long) (m->tx * (1/64.0) * 65536.0);
m->ty = (long) (m->ty * (1/64.0) * 65536.0);
}
// Reset translation in inverted matrix
f->gradient.has_alpha = 0;
// Build a 256 color ramp
f->gradient.ramp = new Color[256];
if (f->gradient.ramp == NULL) {
// Invalidate fill style
f->type = f_None;
continue;
}
// Store min and max
min = f->gradient.ratio[0];
max = f->gradient.ratio[f->gradient.nbGradients-1];
for(r=0; r < f->gradient.nbGradients-1; r++)
{
Color start,end;
l = f->gradient.ratio[r+1]-f->gradient.ratio[r];
if (l == 0) continue;
if (cxform) {
start = cxform->getColor(f->gradient.color[r]);
end = cxform->getColor(f->gradient.color[r+1]);
} else {
start = f->gradient.color[r];
end = f->gradient.color[r+1];
}
if (start.alpha != ALPHA_OPAQUE ||
end.alpha != ALPHA_OPAQUE) {
f->gradient.has_alpha = 1;
}
dRed = end.red - start.red;
dGreen = end.green - start.green;
dBlue = end.blue - start.blue;
dAlpha = end.alpha - start.alpha;
dRed = (dRed<<16)/l;
dGreen = (dGreen<<16)/l;
dBlue = (dBlue<<16)/l;
dAlpha = (dAlpha<<16)/l;
red = start.red <<16;
green = start.green <<16;
blue = start.blue <<16;
alpha = start.alpha <<16;
for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) {
f->gradient.ramp[n].red = red>>16;
f->gradient.ramp[n].green = green>>16;
f->gradient.ramp[n].blue = blue>>16;
f->gradient.ramp[n].alpha = alpha>>16;
f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]);
red += dRed;
green += dGreen;
blue += dBlue;
alpha += dAlpha;
}
}
for(n=0; n<min; n++) {
f->gradient.ramp[n].pixel = f->gradient.ramp[min].pixel;
f->gradient.ramp[n].alpha = f->gradient.ramp[min].alpha;
}
for(n=max; n<256; n++) {
f->gradient.ramp[n].pixel = f->gradient.ramp[max].pixel;
f->gradient.ramp[n].alpha = f->gradient.ramp[max].alpha;
}
}
break;
case f_TiledBitmap:
case f_clippedBitmap:
if (f->bitmap) {
Matrix *m;
f->cmap = gd->getColormap(f->bitmap->colormap,
f->bitmap->nbColors, cxform);
if (f->cmap == NULL) {
/* Get the normal cmap anyway */
f->cmap = f->bitmap->colormap;
}
f->bitmap_matrix = *(matrix) * f->matrix;
f->bitmap_matrix = f->bitmap_matrix.invert();
m=&f->bitmap_matrix;
m->a = m->a * FRAC * 65536.0;
m->b = m->b * FRAC * 65536.0;
m->c = m->c * FRAC * 65536.0;
m->d = m->d * FRAC * 65536.0;
m->tx = (long) (m->tx * 65536.0);
m->ty = (long) (m->ty * 65536.0);
f->alpha_table = NULL;
if (f->bitmap->alpha_buf && cxform) {
unsigned char *alpha_table;
int i;
alpha_table = (unsigned char *)malloc (256);
if (alpha_table != NULL) {
for(i=0;i<256;i++) {
alpha_table[i] = cxform->getAlpha(i);
}
}
f->alpha_table = alpha_table;
}
}
break;
}
}
}
static void
clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n)
{
long fs;
FillStyleDef *f;
for(fs = 0; fs < n; fs++)
{
f = ftab + fs;
switch (f->type)
{
case f_Solid:
break;
case f_LinearGradient:
case f_RadialGradient:
if (f->gradient.ramp) {
delete f->gradient.ramp;
}
break;
case f_TiledBitmap:
case f_clippedBitmap:
if (f->bitmap) {
if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
if (f->alpha_table) free(f->alpha_table);
}
break;
case f_None:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -