home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / Updates / Flash / flashplayer / flashlib / c++ / shape < prev    next >
Encoding:
Text File  |  2000-03-24  |  31.9 KB  |  1,256 lines

  1. /////////////////////////////////////////////////////////////
  2. // Flash Plugin and Player
  3. // Copyright (C) 1998,1999 Olivier Debon
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. //
  19. ///////////////////////////////////////////////////////////////
  20. //  Author : Olivier Debon  <odebon@club-internet.fr>
  21. //
  22.  
  23. #include "swf.h"
  24.  
  25. #if defined(RISCOS)
  26. #include "math.h"
  27. #endif
  28.  
  29. #include <time.h>
  30.  
  31. #ifdef RCSID
  32. static char *rcsid = "$Id: shape.cc,v 1.5 1999/09/10 13:08:52 ode Exp $";
  33. #endif
  34.  
  35. #define PRINT 0
  36.  
  37. #define ABS(v) ((v) < 0 ? -(v) : (v))
  38.  
  39. static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);
  40.  
  41. static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n);
  42.  
  43. static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
  44.                       ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);
  45.  
  46. // Constructor
  47.  
  48. Shape::Shape(long id, int level) : Character(ShapeType, id)
  49. {
  50.     defLevel = level;
  51.  
  52.     defaultFillStyle.type = f_Solid;
  53.     defaultFillStyle.color.red = 0;
  54.     defaultFillStyle.color.green = 0;
  55.     defaultFillStyle.color.blue = 0;
  56.     defaultFillStyle.color.alpha = ALPHA_OPAQUE;
  57.  
  58.     defaultLineStyle.width = 0;
  59.  
  60.     // This is to force a first update
  61.     lastMat.a = 0;
  62.     lastMat.d = 0;
  63.     shape_size += sizeof(Shape);
  64.     shape_nb ++;
  65.  
  66.     file_ptr = NULL;
  67.     getStyles = 0;
  68.     getAlpha = 0;
  69. }
  70.  
  71. Shape::~Shape()
  72. {
  73.     if (file_ptr) {
  74.         free(file_ptr);
  75.     }
  76. }
  77.  
  78. void
  79. Shape::setBoundingBox(Rect rect)
  80. {
  81.     boundary = rect;
  82. }
  83.  
  84. void
  85. Shape::getBoundingBox(Rect *bb, DisplayListEntry *e)
  86. {
  87.     *bb =  boundary;
  88. }
  89.  
  90. int
  91. Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
  92. {
  93.     //printf("TagId = %d\n", getTagId());
  94.     //if (getTagId() != 220) return 0;
  95.     if (cxform) {
  96.         defaultFillStyle.color = cxform->getColor(gd->getForegroundColor());
  97.     } else {
  98.         defaultFillStyle.color = gd->getForegroundColor();
  99.     }
  100.     defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color);
  101.  
  102.     drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0);
  103.  
  104.     return 0;
  105. }
  106.  
  107. void
  108. Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
  109. {
  110.     gd->setClipping(0);
  111.     drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func);
  112.     gd->setClipping(1);
  113. }
  114.  
  115. /************************************************************************/
  116.  
  117. /* create a new path */
  118.  
  119. static void newPath(ShapeParser *shape,
  120.                     long x, long y)
  121. {
  122.     Path *p;
  123.     long x1,y1;
  124.  
  125.     p=&shape->curPath;
  126.  
  127.     x1 = shape->matrix->getX(x, y);
  128.     y1 = shape->matrix->getY(x, y);
  129.  
  130.     p->lastX = x1;
  131.     p->lastY = y1;
  132.  
  133.     p->nb_edges = 0;
  134.     p->nb_segments = 0;
  135. }
  136.  
  137.  
  138. static void addSegment1(ShapeParser *shape,
  139.                         long x, long y,
  140.                         FillStyleDef *f0,
  141.                         FillStyleDef *f1,
  142.                         LineStyleDef *l)
  143. {
  144.     Path *p;
  145.     p=&shape->curPath;
  146.  
  147.     if (l) {
  148.         /* a line is defined ... it will be drawn later */
  149.         LineSegment *ls;
  150.  
  151.         ls = new LineSegment;
  152.     if (ls != NULL) {
  153.         ls->l = l;
  154.         ls->x1 = p->lastX;
  155.         ls->y1 = p->lastY;
  156.         ls->x2 = x;
  157.         ls->y2 = y;
  158.         ls->first = (p->nb_segments == 0);
  159.         ls->next = NULL;
  160.         if (shape->last_line == NULL) {
  161.             shape->first_line = ls;
  162.         } else {
  163.             shape->last_line->next = ls;
  164.         }
  165.         shape->last_line = ls;
  166.     }
  167.     }
  168.  
  169.     /* anti antialiasing not needed if line */
  170.     if (!shape->reverse) {
  171.         shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1);
  172.     } else {
  173.         shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1);
  174.     }
  175.  
  176.     p->lastX = x;
  177.     p->lastY = y;
  178.  
  179.     p->nb_segments++;
  180. }
  181.  
  182.  
  183. static void addLine(ShapeParser *shape, long x, long y,
  184.                     FillStyleDef *f0,
  185.                     FillStyleDef *f1,
  186.                     LineStyleDef *l)
  187. {
  188.     long x1,y1;
  189.     Path *p;
  190.  
  191.     p=&shape->curPath;
  192.  
  193.     x1 = shape->matrix->getX(x, y);
  194.     y1 = shape->matrix->getY(x, y);
  195.  
  196.     addSegment1(shape,x1,y1,f0,f1,l);
  197.  
  198.     p->nb_edges++;
  199. }
  200.  
  201.  
  202. // This is based on Divide and Conquer algorithm.
  203.  
  204. #define BFRAC_BITS  0
  205. #define BFRAC       (1 << BFRAC_BITS)
  206.  
  207. static void
  208. bezierBuildPoints (ShapeParser *s,
  209.                    int subdivisions,
  210.                    long a1X, long a1Y,
  211.                    long cX, long cY,
  212.                    long a2X, long a2Y)
  213. {
  214.     long c1X,c1Y;
  215.     long c2X,c2Y;
  216.     long X,Y;
  217.     long xmin,ymin,xmax,ymax;
  218.  
  219.     if (subdivisions != 0) {
  220.  
  221.         /* find the bounding box */
  222.  
  223.         if (a1X < cX) {
  224.             xmin = a1X;
  225.             xmax = cX;
  226.         } else {
  227.             xmin = cX;
  228.             xmax = a1X;
  229.         }
  230.         if (a2X < xmin) xmin = a2X;
  231.         if (a2X > xmax) xmax = a2X;
  232.  
  233.         if (a1Y < cY) {
  234.             ymin = a1Y;
  235.             ymax = cY;
  236.         } else {
  237.             ymin = cY;
  238.             ymax = a1Y;
  239.         }
  240.         if (a2Y < ymin) ymin = a2Y;
  241.         if (a2Y > ymax) ymax = a2Y;
  242.  
  243.         if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) {
  244.             // Control point 1
  245.             c1X = (a1X+cX) >> 1;
  246.             c1Y = (a1Y+cY) >> 1;
  247.  
  248.             // Control point 2
  249.             c2X = (a2X+cX) >> 1;
  250.             c2Y = (a2Y+cY) >> 1;
  251.  
  252.             // New point
  253.             X = (c1X+c2X) >> 1;
  254.             Y = (c1Y+c2Y) >> 1;
  255.  
  256.             subdivisions--;
  257.  
  258.             bezierBuildPoints(s, subdivisions,
  259.                               a1X, a1Y, c1X, c1Y, X, Y);
  260.             bezierBuildPoints(s, subdivisions,
  261.                               X, Y, c2X, c2Y, a2X, a2Y);
  262.  
  263.             return;
  264.         }
  265.     }
  266.  
  267.     addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS,
  268.                 (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l);
  269. }
  270.  
  271. /* this code is broken, but useful to get something */
  272. static void flushPaths(ShapeParser *s)
  273. {
  274.     LineSegment *ls;
  275.     LineStyleDef *l;
  276.     long nx,ny,nn,w;
  277.     GraphicDevice *gd = s->gd;
  278.  
  279.     /* draw the filled polygon */
  280.     gd->drawPolygon();
  281.  
  282.     /* draw the lines */
  283.     ls = s->first_line;
  284.     if (ls != NULL) {
  285.         do {
  286.             l = ls->l;
  287.  
  288. #if 0
  289.             printf("line %d %d %d %d width=%d\n",
  290.                    ls->x1, ls->y1, ls->x2, ls->y2, l->width);
  291. #endif
  292.  
  293.             /* XXX: this width is false, but it is difficult (and expensive)
  294.                to have the correct one */
  295.             w = ABS((long)(s->matrix->a * l->width));
  296.  
  297.             if (w <= ((3*FRAC)/2)) {
  298.             w = FRAC;
  299.         }
  300. #ifdef THIN_LINES
  301.             if (w <= ((3*FRAC)/2)) {
  302.                 // draw the thin lines only in shapeAction == shapeDraw
  303.                 if (gd->scan_line_func == NULL) {
  304.                     gd->setForegroundColor(l->fillstyle.color);
  305.                     gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w);
  306.                 }
  307.             } else {
  308. #else
  309.         {
  310. #endif
  311.                 /* compute the normal vector */
  312.  
  313.                 nx = -(ls->y2 - ls->y1);
  314.                 ny = (ls->x2 - ls->x1);
  315.  
  316.                 /* normalize & width */
  317. #if 1
  318.                 if (nx == 0) {
  319.                   nn = 2 * (ny < 0 ? -ny : ny);
  320.                 } else if (ny == 0) {
  321.                   nn = 2 * (nx < 0 ? -nx : nx);
  322.                 } else {
  323.                   long arg = nx * nx + ny * ny;
  324.                   if (arg < 0) {
  325.                     // overrun
  326.                     nn = 2 * 65535;
  327.                   } else {
  328.                     nn = 2 * (long) sqrt(arg);
  329.                   }
  330.                 }
  331. #else
  332.                 nn = 2 * (long) sqrt(nx * nx + ny * ny);
  333. #endif
  334.  
  335. #define UL ls->x1 + nx -ny, ls->y1 + ny +nx
  336. #define UR ls->x2 + nx +ny, ls->y2 + ny -nx
  337. #define LL ls->x1 - nx -ny, ls->y1 - ny +nx
  338. #define LR ls->x2 - nx +ny, ls->y2 - ny -nx
  339.  
  340.                 if (nn > 0) {
  341.                     nx = (nx * w) / nn;
  342.                     ny = (ny * w) / nn;
  343.  
  344.                     /* top segment */
  345.                     gd->addSegment(UL, UR, NULL, &l->fillstyle, 1);
  346.  
  347.                     /* bottom segment */
  348.                     gd->addSegment(LL, LR, &l->fillstyle, NULL, 1);
  349.  
  350.                     /* right segment */
  351.                     gd->addSegment(UR, LR, &l->fillstyle, NULL, 1);
  352.  
  353.                     /* left segment */
  354.                     gd->addSegment(UL, LL, NULL, &l->fillstyle, 1);
  355.  
  356.                     /* draw the line polygon */
  357.                     gd->drawPolygon();
  358.                 }
  359.             }
  360.  
  361.             ls = ls->next;
  362.         } while (ls != NULL);
  363.  
  364.         /* delete the line structures */
  365.  
  366.         ls = s->first_line;
  367.         while (ls != NULL) {
  368.             LineSegment *ls1;
  369.             ls1 = ls->next;
  370.             delete ls;
  371.             ls = ls1;
  372.         }
  373.  
  374.         /* reset the line pointers */
  375.         s->first_line = NULL;
  376.         s->last_line = NULL;
  377.     }
  378. }
  379.  
  380.  
  381. static void addBezier(ShapeParser *shape,
  382.                       long ctrlX1, long ctrlY1,
  383.                       long newX1, long newY1,
  384.                       FillStyleDef *f0,
  385.                       FillStyleDef *f1,
  386.                       LineStyleDef *l)
  387. {
  388.     long newX,newY,ctrlX,ctrlY;
  389.     Path *p;
  390.  
  391.     p=&shape->curPath;
  392.  
  393.     /* note: we do the matrix multiplication before calculating the
  394.        bezier points (faster !) */
  395.  
  396.     ctrlX = shape->matrix->getX(ctrlX1, ctrlY1);
  397.     ctrlY = shape->matrix->getY(ctrlX1, ctrlY1);
  398.     newX = shape->matrix->getX(newX1, newY1);
  399.     newY = shape->matrix->getY(newX1, newY1);
  400.  
  401.     shape->f0 = f0;
  402.     shape->f1 = f1;
  403.     shape->l = l;
  404.  
  405.     bezierBuildPoints(shape, 3,
  406.                       p->lastX<<BFRAC_BITS,p->lastY<<BFRAC_BITS,
  407.                       ctrlX<<BFRAC_BITS,ctrlY<<BFRAC_BITS,
  408.                       newX<<BFRAC_BITS,newY<<BFRAC_BITS);
  409.  
  410.     p->nb_edges++;
  411. }
  412.  
  413. /***********************************************************************/
  414.  
  415.  
  416. /* bit parser */
  417.  
  418. static void InitBitParser(struct BitParser *b,U8 *buf)
  419. {
  420.     b->ptr = buf;
  421. }
  422.  
  423. static void InitBits(struct BitParser *b)
  424. {
  425.     // Reset the bit position and buffer.
  426.     b->m_bitPos = 0;
  427.     b->m_bitBuf = 0;
  428. }
  429.  
  430.  
  431.  
  432. static inline U8 GetByte(struct BitParser *b)
  433. {
  434.     U8 v;
  435.     v = *b->ptr++;
  436.     return v;
  437. }
  438.  
  439. static inline U16 GetWord(struct BitParser *b)
  440. {
  441.     U8 *s;
  442.     U16 v;
  443.     s = b->ptr;
  444.     v = s[0] | ((U16) s[1] << 8);
  445.     b->ptr = s + 2;
  446.     return v;
  447. }
  448.  
  449. static inline U32 GetDWord(struct BitParser *b)
  450. {
  451.     U32 v;
  452.     U8 * s = b->ptr;
  453.     v = (U32) s[0] | ((U32) s[1] << 8) |
  454.         ((U32) s[2] << 16) | ((U32) s [3] << 24);
  455.     b->ptr = s + 4;
  456.     return v;
  457. }
  458.  
  459. static inline U32 GetBit (struct BitParser *b)
  460. {
  461.     U32 v;
  462.     S32 m_bitPos = b->m_bitPos;
  463.     U32 m_bitBuf = b->m_bitBuf;
  464.  
  465.     if (m_bitPos == 0) {
  466.         m_bitBuf = (U32)(*b->ptr++) << 24;
  467.         m_bitPos = 8;
  468.     }
  469.  
  470.     v = (m_bitBuf >> 31);
  471.  
  472.     m_bitPos--;
  473.     m_bitBuf <<= 1;
  474.  
  475.     b->m_bitPos = m_bitPos;
  476.     b->m_bitBuf = m_bitBuf;
  477.  
  478.     return v;
  479. }
  480.  
  481. static inline U32 GetBits (struct BitParser *b, int n)
  482. {
  483.     U32 v;
  484.     S32 m_bitPos = b->m_bitPos;
  485.     U32 m_bitBuf = b->m_bitBuf;
  486.  
  487.     if (n == 0)
  488.         return 0;
  489.  
  490.     while (m_bitPos < n) {
  491.         m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos);
  492.         m_bitPos += 8;
  493.     }
  494.  
  495.     v = m_bitBuf >> (32 - n);
  496.     m_bitBuf <<= n;
  497.     m_bitPos -= n;
  498.  
  499.     b->m_bitPos = m_bitPos;
  500.     b->m_bitBuf = m_bitBuf;
  501.     return v;
  502. }
  503.  
  504. // Get n bits from the string with sign extension.
  505. static inline S32 GetSBits (struct BitParser *b,S32 n)
  506. {
  507.     // Get the number as an unsigned value.
  508.     S32 v = (S32) GetBits(b,n);
  509.  
  510.     // Is the number negative?
  511.     if (v & (1L << (n - 1)))
  512.     {
  513.         // Yes. Extend the sign.
  514.         v |= -1L << n;
  515.     }
  516.  
  517.     return v;
  518. }
  519.  
  520.  
  521.  
  522. /************************************************************************/
  523.  
  524. static void GetMatrix(BitParser *b, Matrix* mat)
  525. {
  526.     InitBits(b);
  527.  
  528.     // Scale terms
  529.     if (GetBit(b))
  530.     {
  531.         int nBits = (int) GetBits(b,5);
  532.         mat->a = (float)(GetSBits(b,nBits))/(float)0x10000;
  533.         mat->d = (float)(GetSBits(b,nBits))/(float)0x10000;
  534.     }
  535.     else
  536.     {
  537.          mat->a = mat->d = 1.0;
  538.     }
  539.  
  540.     // Rotate/skew terms
  541.     if (GetBit(b))
  542.     {
  543.         int nBits = (int)GetBits(b,5);
  544.         mat->c = (float)(GetSBits(b,nBits))/(float)0x10000;
  545.         mat->b = (float)(GetSBits(b,nBits))/(float)0x10000;
  546.     }
  547.     else
  548.     {
  549.          mat->b = mat->c = 0.0;
  550.     }
  551.  
  552.     // Translate terms
  553.     int nBits = (int) GetBits(b,5);
  554.     mat->tx = GetSBits(b,nBits);
  555.     mat->ty = GetSBits(b,nBits);
  556. }
  557.  
  558. static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha)
  559. {
  560.     BitParser *b = &shape->bit_parser;
  561.     FillStyleDef *defs;
  562.     U16 i = 0;
  563.  
  564.     // Get the number of fills.
  565.     U16 nFills = GetByte(b);
  566.  
  567.     // Do we have a larger number?
  568.     if (nFills == 255)
  569.     {
  570.         // Get the larger number.
  571.         nFills = GetWord(b);
  572.     }
  573.  
  574.     *n = nFills;
  575.     defs = new FillStyleDef[ nFills ];
  576.     if (defs == NULL) return NULL;
  577.  
  578.     // Get each of the fill style.
  579.     for (i = 0; i < nFills; i++)
  580.     {
  581.         U16 fillStyle = GetByte(b);
  582.  
  583.         defs[i].type = (FillType) fillStyle;
  584.  
  585.         if (fillStyle & 0x10)
  586.         {
  587.             defs[i].type = (FillType) (fillStyle & 0x12);
  588.  
  589.             // Get the gradient matrix.
  590.             GetMatrix(b,&(defs[i].matrix));
  591.  
  592.             // Get the number of colors.
  593.             defs[i].gradient.nbGradients = GetByte(b);
  594.  
  595.             // Get each of the colors.
  596.             for (U16 j = 0; j < defs[i].gradient.nbGradients; j++)
  597.             {
  598.                 defs[i].gradient.ratio[j] = GetByte(b);
  599.                 defs[i].gradient.color[j].red = GetByte(b);
  600.                 defs[i].gradient.color[j].green = GetByte(b);
  601.                 defs[i].gradient.color[j].blue = GetByte(b);
  602.                 if (getAlpha) {
  603.                                     defs[i].gradient.color[j].alpha = GetByte(b);
  604.                 } else {
  605.                     defs[i].gradient.color[j].alpha = ALPHA_OPAQUE;
  606.                                 }
  607.             }
  608.         }
  609.         else if (fillStyle & 0x40)
  610.         {
  611.             defs[i].type = (FillType) (fillStyle & 0x41);
  612.  
  613.             // Get the bitmapId
  614.             defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b));
  615.             // Get the bitmap matrix.
  616.             GetMatrix(b,&(defs[i].matrix));
  617.         }
  618.         else
  619.         {
  620.             defs[i].type = (FillType) 0;
  621.  
  622.             // A solid color
  623.             defs[i].color.red = GetByte(b);
  624.             defs[i].color.green = GetByte(b);
  625.             defs[i].color.blue = GetByte(b);
  626.             if (getAlpha) {
  627.                 defs[i].color.alpha = GetByte(b);
  628.             } else {
  629.                 defs[i].color.alpha = ALPHA_OPAQUE;
  630.                         }
  631.         }
  632.     }
  633.  
  634.     return defs;
  635. }
  636.  
  637. static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha)
  638. {
  639.     BitParser *b = &shape->bit_parser;
  640.     LineStyleDef *defs,*def;
  641.     FillStyleDef *f;
  642.     long i;
  643.  
  644.     // Get the number of lines.
  645.     U16 nLines = GetByte(b);
  646.  
  647.     // Do we have a larger number?
  648.     if (nLines == 255)
  649.     {
  650.         // Get the larger number.
  651.         nLines = GetWord(b);
  652.     }
  653.  
  654.     *n = nLines;
  655.     defs = new LineStyleDef[ nLines ];
  656.     if (defs == NULL) return NULL;
  657.  
  658.     // Get each of the line styles.
  659.     for (i = 0; i < nLines; i++)
  660.     {
  661.             def=&defs[i];
  662.             def->width = GetWord(b);
  663.             def->color.red = GetByte(b);
  664.             def->color.green = GetByte(b);
  665.             def->color.blue = GetByte(b);
  666.             if (getAlpha) {
  667.                 def->color.alpha = GetByte(b);
  668.             } else {
  669.                 def->color.alpha = ALPHA_OPAQUE;
  670.             }
  671.  
  672.             f=&def->fillstyle;
  673.             f->type = f_Solid;
  674.             f->color = def->color;
  675.             if (shape->cxform) {
  676.                 f->color = shape->cxform->getColor(f->color);
  677.             }
  678.             f->color.pixel = shape->gd->allocColor(f->color);
  679.     }
  680.  
  681.     return defs;
  682. }
  683.  
  684. /* 0 = end of shape */
  685. static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha)
  686. {
  687.     BitParser *b = &shape->bit_parser;
  688.  
  689.     // Determine if this is an edge.
  690.     BOOL isEdge = (BOOL) GetBit(b);
  691.  
  692.     if (!isEdge)
  693.     {
  694.         // Handle a state change
  695.         U16 flags = (U16) GetBits(b,5);
  696.  
  697.         // Are we at the end?
  698.         if (flags == 0)
  699.         {
  700.             // End of shape
  701.             return 0;
  702.         }
  703.  
  704.         sr->type = shapeNonEdge;
  705.         sr->flags = (ShapeFlags)flags;
  706.  
  707.         // Process a move to.
  708.         if (flags & flagsMoveTo)
  709.         {
  710.             U16 nBits = (U16) GetBits(b,5);
  711.             sr->x = GetSBits(b,nBits);
  712.             sr->y = GetSBits(b,nBits);
  713.         }
  714.  
  715.         // Get new fill info.
  716.         if (flags & flagsFill0)
  717.         {
  718.             sr->fillStyle0 = GetBits(b,shape->m_nFillBits);
  719.         }
  720.         if (flags & flagsFill1)
  721.         {
  722.             sr->fillStyle1 = GetBits(b,shape->m_nFillBits);
  723.         }
  724.  
  725.         // Get new line info
  726.         if (flags & flagsLine)
  727.         {
  728.             sr->lineStyle = GetBits(b,shape->m_nLineBits);
  729.         }
  730.  
  731.         // Check to get a new set of styles for a new shape layer.
  732.         if (flags & flagsNewStyles)
  733.         {
  734.             FillStyleDef *fillDefs;
  735.             LineStyleDef *lineDefs;
  736.             long n;
  737.  
  738.             // Parse the style.
  739.             fillDefs = ParseFillStyle(shape, &n, getAlpha);
  740.             if (fillDefs == NULL)  return 0;
  741.  
  742.             sr->newFillStyles = fillDefs;
  743.             sr->nbNewFillStyles = n;
  744.  
  745.             lineDefs = ParseLineStyle(shape, &n, getAlpha);
  746.             if (lineDefs == NULL) return 0;
  747.  
  748.             sr->newLineStyles = lineDefs;
  749.             sr->nbNewLineStyles = n;
  750.  
  751.             InitBits(b);    // Bug !
  752.  
  753.             // Reset.
  754.             shape->m_nFillBits = (U16) GetBits(b,4);
  755.             shape->m_nLineBits = (U16) GetBits(b,4);
  756.         }
  757.  
  758.         //if (flags & flagsEndShape)
  759.             //printf("\tEnd of shape.\n\n");
  760.  
  761.         return flags & flagsEndShape ? 0 : 1;
  762.     }
  763.     else
  764.     {
  765.         if (GetBit(b))
  766.         {
  767.             sr->type = shapeLine;
  768.  
  769.             // Handle a line
  770.             U16 nBits = (U16) GetBits(b,4) + 2;    // nBits is biased by 2
  771.  
  772.             // Save the deltas
  773.             if (GetBit(b))
  774.             {
  775.                 // Handle a general line.
  776.                 sr->dX = GetSBits(b,nBits);
  777.                 sr->dY = GetSBits(b,nBits);
  778.             }
  779.             else
  780.             {
  781.                 // Handle a vert or horiz line.
  782.                 if (GetBit(b))
  783.                 {
  784.                     // Vertical line
  785.                     sr->dY = GetSBits(b,nBits);
  786.                     sr->dX = 0;
  787.                 }
  788.                 else
  789.                 {
  790.                     // Horizontal line
  791.                     sr->dX = GetSBits(b,nBits);
  792.                     sr->dY = 0;
  793.                 }
  794.             }
  795.         }
  796.         else
  797.         {
  798.             sr->type = shapeCurve;
  799.  
  800.              // Handle a curve
  801.             U16 nBits = (U16) GetBits(b,4) + 2;    // nBits is biased by 2
  802.  
  803.             // Get the control
  804.             sr->ctrlX = GetSBits(b,nBits);
  805.             sr->ctrlY = GetSBits(b,nBits);
  806.  
  807.             // Get the anchor
  808.             sr->anchorX = GetSBits(b,nBits);
  809.             sr->anchorY = GetSBits(b,nBits);
  810.         }
  811.  
  812.         return 1;
  813.     }
  814. }
  815.  
  816. static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
  817.                       ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func)
  818. {
  819.     LineStyleDef *l;
  820.     FillStyleDef *f0;
  821.     FillStyleDef *f1;
  822.     ShapeRecord sr1,*sr = &sr1;
  823.     int firstPoint;
  824.     long lastX,lastY;
  825.     LineStyleDef *curLineStyle;
  826.     long curNbLineStyles;
  827.     FillStyleDef *curFillStyle;
  828.     long curNbFillStyles;
  829.     StyleList *sl;
  830.     ShapeParser sp1,*sp=&sp1;
  831.     BitParser *b;
  832.     Matrix     mat,*matrix;
  833.  
  834.     mat = (*gd->adjust) * (*matrix1);
  835.     matrix = &mat;
  836.  
  837.     sp->reverse = (mat.a * mat.d) < 0;
  838.  
  839.     curLineStyle = NULL;
  840.     curNbLineStyles = 0;
  841.     curFillStyle = NULL;
  842.     curNbFillStyles = 0;
  843.     sp->style_list = NULL;
  844.  
  845.     sp->shape = shape;
  846.     sp->gd = gd;
  847.     sp->matrix = matrix;
  848.     sp->cxform = cxform;
  849.     sp->dict = shape->dict;
  850.  
  851.     if (shapeAction == ShapeGetRegion) {
  852.         gd->scan_line_func = scan_line_func;
  853.         gd->scan_line_func_id = id;
  854.     } else {
  855.         gd->scan_line_func = NULL;
  856.     }
  857.  
  858.     b = &sp->bit_parser;
  859.     InitBitParser(b,shape->file_ptr);
  860.  
  861.     if (shape->getStyles) {
  862.         // ShapeWithStyle
  863.         curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha);
  864.     if (curFillStyle == NULL) return;
  865.  
  866.         curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha);
  867.     if (curLineStyle == NULL) return;
  868.  
  869.         sl = new StyleList;
  870.     if (sl == NULL) return;
  871.  
  872.         sl->next = NULL;
  873.         sl->newFillStyles = curFillStyle;
  874.         sl->nbNewFillStyles = curNbFillStyles;
  875.         sl->newLineStyles = curLineStyle;
  876.         sl->nbNewLineStyles = curNbLineStyles;
  877.  
  878.         sp->style_list = sl;
  879.  
  880.         if (shapeAction == ShapeDraw) {
  881.             prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
  882.         }
  883.     }
  884.  
  885.     InitBits(b);
  886.     sp->m_nFillBits = (U16) GetBits(b,4);
  887.     sp->m_nLineBits = (U16) GetBits(b,4);
  888.  
  889.     l = 0;
  890.     f0 = 0;
  891.     f1 = 0;
  892.     firstPoint = 1;
  893.     lastX = 0;
  894.     lastY = 0;
  895.     sp->curPath.nb_edges = 0;
  896.     sp->first_line = NULL;
  897.     sp->last_line = NULL;
  898.  
  899.     for(;;) {
  900.         if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break;
  901.  
  902.         switch (sr->type)
  903.         {
  904.             case shapeNonEdge:
  905.                 if (sr->flags & flagsNewStyles) {
  906.  
  907.                     curFillStyle = sr->newFillStyles;
  908.                     curNbFillStyles = sr->nbNewFillStyles;
  909.                     curLineStyle = sr->newLineStyles;
  910.                     curNbLineStyles = sr->nbNewLineStyles;
  911.  
  912.                     sl = new StyleList;
  913.                     sl->next = sp->style_list;
  914.                     sl->newFillStyles = sr->newFillStyles;
  915.                     sl->nbNewFillStyles = sr->nbNewFillStyles;
  916.                     sl->newLineStyles = sr->newLineStyles;
  917.                     sl->nbNewLineStyles = sr->nbNewLineStyles;
  918.  
  919.                     sp->style_list = sl;
  920.  
  921.                     if (shapeAction == ShapeDraw) {
  922.                         prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
  923.                     }
  924.                 }
  925.                 if (sr->flags & flagsFill0) {
  926.                     if (sr->fillStyle0) {
  927.                         if (curFillStyle) {
  928.                             f0 = &curFillStyle[sr->fillStyle0-1];
  929.                         } else {
  930.                             f0 = &shape->defaultFillStyle;
  931.                         }
  932.                     } else {
  933.                         f0 = 0;
  934.                     }
  935.                 }
  936.                 if (sr->flags & flagsFill1) {
  937.                     if (sr->fillStyle1) {
  938.                         if (curFillStyle) {
  939.                             f1 = &curFillStyle[sr->fillStyle1-1];
  940.                         } else {
  941.                             f1 = &shape->defaultFillStyle;
  942.                         }
  943.                     } else {
  944.                         f1 = 0;
  945.                     }
  946.                 }
  947.                 if (sr->flags & flagsLine) {
  948.                     if (sr->lineStyle) {
  949.                         l = &curLineStyle[sr->lineStyle-1];
  950.                     } else {
  951.                         l = 0;
  952.                     }
  953.                 }
  954.                 if (sr->flags & flagsMoveTo) {
  955.                     if (sp->curPath.nb_edges == 0) {
  956.                         /* if no edges, draw the polygon, then the lines */
  957.                         flushPaths(sp);
  958.                     }
  959.  
  960.                     newPath(sp, sr->x, sr->y);
  961.                     firstPoint = 0;
  962.  
  963.                     lastX = sr->x;
  964.                     lastY = sr->y;
  965.  
  966. #if PRINT
  967.                     printf("---------\nX,Y    = %4d,%4d\n", sr->x/20, sr->y/20);
  968. #endif
  969.                 }
  970.                 break;
  971.             case shapeCurve:
  972.                 // Handle Bezier Curves !!!
  973.                 if (firstPoint) {
  974.                     newPath(sp, 0, 0);
  975.                     firstPoint = 0;
  976.                 }
  977.                 {
  978.                     long newX,newY,ctrlX,ctrlY;
  979.  
  980.                     ctrlX = lastX+sr->ctrlX;
  981.                     ctrlY = lastY+sr->ctrlY;
  982.                     newX = ctrlX+sr->anchorX;
  983.                     newY = ctrlY+sr->anchorY;
  984.  
  985. #if 1
  986.                     addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l);
  987. #else
  988.                     addLine(sp, newX, newY, f0, f1, l);
  989. #endif
  990.  
  991.                     lastX = newX;
  992.                     lastY = newY;
  993.                 }
  994.                 break;
  995.             case shapeLine:
  996.                 if (firstPoint) {
  997.                     newPath(sp, 0, 0);
  998.                     firstPoint = 0;
  999.                 }
  1000.  
  1001.                 lastX += sr->dX;
  1002.                 lastY += sr->dY;
  1003.  
  1004.                 addLine(sp, lastX, lastY, f0, f1, l);
  1005. #if PRINT
  1006.                 printf(" X, Y  = %4d,%4d\n", lastX/20, lastY/20);
  1007. #endif
  1008.                 break;
  1009.         }
  1010.     }
  1011.  
  1012.     /* XXX: should test if there is something to draw */
  1013.     flushPaths(sp);
  1014.  
  1015.     /* free the styles */
  1016.     while (sp->style_list) {
  1017.         StyleList *sl;
  1018.  
  1019.         sl=sp->style_list;
  1020.         sp->style_list = sl->next;
  1021.  
  1022.         if (shapeAction == ShapeDraw) {
  1023.             clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles);
  1024.         }
  1025.  
  1026.         delete[] sl->newFillStyles;
  1027.         delete[] sl->newLineStyles;
  1028.  
  1029.         delete sl;
  1030.     }
  1031. }
  1032.  
  1033. static void
  1034. prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform,
  1035.               FillStyleDef *ftab, long n)
  1036. {
  1037.     long fs;
  1038.     FillStyleDef *f;
  1039.  
  1040.     for(fs = 0; fs < n; fs++)
  1041.     {
  1042.         f = ftab + fs;
  1043.         switch (f->type)
  1044.         {
  1045.             case f_None:
  1046.             break;
  1047.             case f_Solid:
  1048.                 if (cxform) {
  1049.                     f->color = cxform->getColor(f->color);
  1050.                 }
  1051.                 f->color.pixel = gd->allocColor(f->color);
  1052.                 break;
  1053.             case f_LinearGradient:
  1054.             case f_RadialGradient:
  1055.                 {
  1056.                     Matrix mat;
  1057.                     int  n,r,l;
  1058.                     long red, green, blue, alpha;
  1059.                     long dRed, dGreen, dBlue, dAlpha;
  1060.                     long min,max;
  1061.                     Matrix *m;
  1062.  
  1063.                     mat = *(matrix) * f->matrix;
  1064.                     // Compute inverted matrix
  1065.                     f->gradient.imat = mat.invert();
  1066.  
  1067.                     /* renormalize the matrix */
  1068.                     m=&f->gradient.imat;
  1069.                     if (f->type == f_LinearGradient) {
  1070. #if 1
  1071.                         m->a = m->a * (float)(512 << FRAC_BITS);
  1072.                         m->b = m->b * (float)(512 << FRAC_BITS);
  1073. #else
  1074.                         m->a = m->a * (float)FRAC * 512.0;
  1075.                         m->b = m->b * (float)FRAC * 512.0;
  1076. #endif
  1077.                         m->tx = (long) ((m->tx + 16384) * 512L);
  1078.                     } else {
  1079. #if 1
  1080.                         m->a = m->a * (float)(1024 << FRAC_BITS);
  1081.                         m->b = m->b * (float)(1024 << FRAC_BITS);
  1082.                         m->c = m->c * (float)(1024 << FRAC_BITS);
  1083.                         m->d = m->d * (float)(1024 << FRAC_BITS);
  1084. #else
  1085.                         m->a = m->a * (float)FRAC * 1024.0;
  1086.                         m->b = m->b * (float)FRAC * 1024.0;
  1087.                         m->c = m->c * (float)FRAC * 1024.0;
  1088.                         m->d = m->d * (float)FRAC * 1024.0;
  1089. #endif
  1090.                         m->tx = (long) (m->tx * 1024L);
  1091.                         m->ty = (long) (m->ty * 1024L);
  1092.                     }
  1093.  
  1094.                     // Reset translation in inverted matrix
  1095.                     f->gradient.has_alpha = 0;
  1096.  
  1097.                     // Build a 256 color ramp
  1098.                     f->gradient.ramp = new Color[256];
  1099.             if (f->gradient.ramp == NULL) {
  1100.                 // Invalidate fill style
  1101.             f->type = f_None;
  1102.             continue;
  1103.             }
  1104.  
  1105.                     // Store min and max
  1106.                     min = f->gradient.ratio[0];
  1107.                     max = f->gradient.ratio[f->gradient.nbGradients-1];
  1108.                     for(r=0; r < f->gradient.nbGradients-1; r++)
  1109.                     {
  1110.                         Color start,end;
  1111.  
  1112.                         l = f->gradient.ratio[r+1]-f->gradient.ratio[r];
  1113.                         if (l == 0) continue;
  1114.  
  1115.                         if (cxform) {
  1116.                             start = cxform->getColor(f->gradient.color[r]);
  1117.                             end   = cxform->getColor(f->gradient.color[r+1]);
  1118.                         } else {
  1119.                             start = f->gradient.color[r];
  1120.                             end   = f->gradient.color[r+1];
  1121.                         }
  1122.  
  1123.                         if (start.alpha != ALPHA_OPAQUE ||
  1124.                             end.alpha != ALPHA_OPAQUE) {
  1125.                             f->gradient.has_alpha = 1;
  1126.                         }
  1127.  
  1128.                         dRed   = end.red - start.red;
  1129.                         dGreen = end.green - start.green;
  1130.                         dBlue  = end.blue - start.blue;
  1131.                         dAlpha = end.alpha - start.alpha;
  1132.  
  1133.                         dRed   = (dRed<<16)/l;
  1134.                         dGreen = (dGreen<<16)/l;
  1135.                         dBlue  = (dBlue<<16)/l;
  1136.                         dAlpha  = (dAlpha<<16)/l;
  1137.  
  1138.                         red   = start.red <<16;
  1139.                         green = start.green <<16;
  1140.                         blue  = start.blue <<16;
  1141.                         alpha  = start.alpha <<16;
  1142.  
  1143.                         for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) {
  1144.                             f->gradient.ramp[n].red = red>>16;
  1145.                             f->gradient.ramp[n].green = green>>16;
  1146.                             f->gradient.ramp[n].blue = blue>>16;
  1147.                             f->gradient.ramp[n].alpha = alpha>>16;
  1148.  
  1149.                             f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]);
  1150.                             red += dRed;
  1151.                             green += dGreen;
  1152.                             blue += dBlue;
  1153.                             alpha += dAlpha;
  1154.                         }
  1155.                     }
  1156.                     for(n=0; n<min; n++) {
  1157.                         f->gradient.ramp[n].pixel = f->gradient.ramp[min].pixel;
  1158.                         f->gradient.ramp[n].alpha = f->gradient.ramp[min].alpha;
  1159.                     }
  1160.                     for(n=max; n<256; n++) {
  1161.                         f->gradient.ramp[n].pixel = f->gradient.ramp[max].pixel;
  1162.                         f->gradient.ramp[n].alpha = f->gradient.ramp[max].alpha;
  1163.                     }
  1164.                 }
  1165.                 break;
  1166.             case f_TiledBitmap:
  1167.             case f_clippedBitmap:
  1168.                 if (f->bitmap) {
  1169.                     Matrix *m;
  1170.  
  1171.                     f->cmap = gd->getColormap(f->bitmap->colormap,
  1172.                                               f->bitmap->nbColors, cxform);
  1173.             if (f->cmap == NULL) {
  1174.             /* Get the normal cmap anyway */
  1175.                 f->cmap = f->bitmap->colormap;
  1176.             }
  1177.  
  1178.                     f->bitmap_matrix = *(matrix) * f->matrix;
  1179.  
  1180.                     f->bitmap_matrix = f->bitmap_matrix.invert();
  1181.  
  1182.                     m=&f->bitmap_matrix;
  1183. #if 1
  1184.                     m->a = m->a * (float)(65536 << FRAC_BITS);
  1185.                     m->b = m->b * (float)(65536 << FRAC_BITS);
  1186.                     m->c = m->c * (float)(65536 << FRAC_BITS);
  1187.                     m->d = m->d * (float)(65536 << FRAC_BITS);
  1188. #else
  1189.                     m->a = m->a * (float)FRAC * 65536.0;
  1190.                     m->b = m->b * (float)FRAC * 65536.0;
  1191.                     m->c = m->c * (float)FRAC * 65536.0;
  1192.                     m->d = m->d * (float)FRAC * 65536.0;
  1193. #endif
  1194.                     m->tx = (long) (m->tx * 65536L);
  1195.                     m->ty = (long) (m->ty * 65536L);
  1196. #ifdef RISCOS
  1197.                     f->bm_a = (long)m->a;
  1198.                     f->bm_b = (long)m->b;
  1199.                     f->bm_c = (long)m->c;
  1200.                     f->bm_d = (long)m->d;
  1201.                     f->bm_tx = m->tx;
  1202.                     f->bm_ty = m->ty;
  1203. #endif
  1204.                     f->alpha_table = NULL;
  1205.  
  1206.                     if (f->bitmap->alpha_buf && cxform) {
  1207.                         unsigned char *alpha_table;
  1208.                         int i;
  1209.  
  1210.                         alpha_table = (unsigned char *)malloc (256);
  1211.                         if (alpha_table != NULL) {
  1212.                             for(i=0;i<256;i++) {
  1213.                                 alpha_table[i] = cxform->getAlpha(i);
  1214.                             }
  1215.                         }
  1216.                         f->alpha_table = alpha_table;
  1217.                     }
  1218.                 }
  1219.                 break;
  1220.         }
  1221.     }
  1222. }
  1223.  
  1224. static void
  1225. clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n)
  1226. {
  1227.     long fs;
  1228.     FillStyleDef *f;
  1229.  
  1230.     for(fs = 0; fs < n; fs++)
  1231.     {
  1232.         f = ftab + fs;
  1233.         switch (f->type)
  1234.         {
  1235.             case f_Solid:
  1236.                 break;
  1237.             case f_LinearGradient:
  1238.             case f_RadialGradient:
  1239.                 if (f->gradient.ramp) {
  1240.                     delete f->gradient.ramp;
  1241.                 }
  1242.                 break;
  1243.             case f_TiledBitmap:
  1244.             case f_clippedBitmap:
  1245.                 if (f->bitmap) {
  1246.                     if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
  1247.                     if (f->alpha_table) free(f->alpha_table);
  1248.                 }
  1249.                 break;
  1250.         case f_None:
  1251.             break;
  1252.         }
  1253.     }
  1254. }
  1255.  
  1256.