home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / Updates / Flash / flashplayer / flashlib / c++ / graphic16 < prev    next >
Encoding:
Text File  |  2000-04-09  |  22.0 KB  |  854 lines

  1. ////////////////////////////////////////////////////////////
  2. // Flash Plugin and Player
  3. // Copyright (C) 1998 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. #include "graphic16.h"
  25.  
  26. #ifdef RCSID
  27. static char *rcsid = "$Id: graphic.cc,v 1.5 1999/09/03 15:17:40 ode Exp $";
  28. #endif
  29.  
  30. #include "sqrt.h"
  31.  
  32. #define FULL_AA
  33.  
  34. #define PRINT 0
  35.  
  36. #define HBP
  37.  
  38. #ifdef HBP
  39. extern "C" {
  40.   extern long mix_alpha16(long c1, long c2, int alpha);
  41.   extern void fill_line_flat_opaque16(unsigned short *line, long pixels, long col);
  42.   extern void fill_line_flat16(unsigned short *line, long pixels, long col, int alpha);
  43.   extern void fill_line_flat_bitmap16(unsigned short *p, long n, Color *cmap, unsigned char *pixels, int pixbpl, long x1, long y1, long dx, long dy, long width, long height, int tiled);
  44.   extern void fill_line_alpha_chn_bitmap16(unsigned short *p, long n, Color *cmap, unsigned char *pixels, int pixbpl, long x1, long y1, long dx, long dy, unsigned char *alphatable, unsigned char *alphachannel, long width, long height, int tiled);
  45.   extern void fill_line_alpha_bitmap16(unsigned short *p, long n, Color *cmap, unsigned char *pixels, int pixbpl, long x1, long y1, long dx, long dy, unsigned char *alphachannel, long width, long height, int tiled);
  46.   extern int fill_line_ramp_opaque16(unsigned short *point, long n, Color *ramp, long r, long dr);
  47.   extern int fill_line_ramp16(unsigned short *point, long n, Color *ramp, long r, long dr);
  48.   extern int fill_line_ramp_2_opaque16(unsigned short *point, long n, Color *ramp, long r, long dr);
  49.   extern int fill_line_ramp_2_16(unsigned short *point, long n, Color *ramp, long r, long dr);
  50.   extern void fill_line_radial_ramp_2_16(unsigned short *point, long n, long *X, long *Y, long dx, long dy, Color *ramp, unsigned char *SQRT);
  51.   extern void fill_line_radial_ramp16(unsigned short *point, long n, long *X, long *Y, long dx, long dy, Color *ramp, unsigned char *SQRT);
  52.   extern Color *get_colour16(long c, Color *c);
  53.   extern long alloc_colour16(Color *c);
  54. }
  55. #else
  56. #define mix_alpha16 mix_alpha
  57. #endif
  58.  
  59. typedef unsigned short TYPE;
  60.  
  61.  
  62.  
  63. // Public
  64.  
  65. GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd)
  66. {
  67. }
  68.  
  69. GraphicDevice16::~GraphicDevice16()
  70. {
  71. }
  72.  
  73.  
  74. long
  75. GraphicDevice16::allocColor(Color color)
  76. {
  77. #ifdef HBP
  78.         return alloc_colour16(&color);
  79. #else
  80.     return (color.red >> 3) | (color.green>>3)<<5 | (color.blue>>3) << 10;
  81. #endif
  82. }
  83.  
  84. Color
  85. GraphicDevice16::getColor(unsigned long c)
  86. {
  87.   Color color;
  88.  
  89. #ifdef HBP
  90.   get_colour16(c, &color);
  91. #else
  92.  
  93.   color.red   = (c & 0x1f) << 3;
  94.   color.green = ((c >> 5) & 0x1f) << 3;
  95.   color.blue  = ((c >> 10) & 0x1f) << 3;
  96. #endif
  97.   return color;
  98. }
  99.  
  100. void
  101. GraphicDevice16::clearCanvas()
  102. {
  103. #ifdef HBP
  104.     long  pixel;
  105. #else
  106.     TYPE  pixel;
  107. #endif
  108.     TYPE *point,*p;
  109.     long                 h, w,n;
  110.  
  111.     if (!bgInitialized) return;
  112.  
  113.     pixel = allocColor(backgroundColor);
  114.  
  115.     // The following allows to test clipping
  116.     //for(point = (TYPE *)canvasBuffer,n=0; n<targetHeight*bpl/2; point++,n++) *point = 0xfe00;
  117.  
  118.     point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
  119.     w = clip_rect.xmax - clip_rect.xmin;
  120.     h = clip_rect.ymax - clip_rect.ymin;
  121.  
  122.     while (h--) {
  123.         p = point;
  124.         n = w;
  125. #ifdef HBP
  126.         if (h &1)  pixel = (pixel<<16) | (pixel>>16);
  127.         fill_line_flat_opaque16(point, n, pixel);
  128. #else
  129.         while (n--) {
  130.             *p++ = pixel;
  131.         }
  132. #endif
  133.         point = (TYPE *)((char *)point + bpl);
  134.     }
  135.  
  136.     flashDisplay->flash_refresh = 1;
  137.     flashDisplay->clip_x = clip_rect.xmin;
  138.     flashDisplay->clip_y = clip_rect.ymin;
  139.     flashDisplay->clip_width  = clip_rect.xmax-clip_rect.xmin;
  140.     flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
  141. }
  142.  
  143. void
  144. GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end)
  145. {
  146.     register long   n;
  147.     TYPE *line;
  148.     TYPE *point;
  149. #ifdef HBP
  150.     long pixel;
  151. #else
  152.     TYPE pixel;
  153. #endif
  154.     unsigned int alpha, start_alpha,end_alpha;
  155.  
  156.     if (clip(y,start,end)) return;
  157.  
  158.     line = (TYPE *)(canvasBuffer + bpl*y);
  159.  
  160.     alpha = f->color.alpha;
  161.     pixel = f->color.pixel;
  162. #ifdef HBP
  163.     if (y &1)  pixel = (pixel<<16) | (pixel>>16);
  164. #endif
  165.     if (alpha == ALPHA_OPAQUE) {
  166.  
  167.         start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
  168.         end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
  169.  
  170.         start >>= FRAC_BITS;
  171.         end >>= FRAC_BITS;
  172.  
  173.         point = &line[start];
  174.  
  175.         if (start == end) {
  176.             *point = mix_alpha16(*point, pixel, start_alpha + end_alpha - 255);
  177.         } else {
  178.             n = end-start;
  179.             if (start_alpha < 255) {
  180.                 *point = mix_alpha16(*point, pixel, start_alpha);
  181.                 point++;
  182.                 n--;
  183.             }
  184. #ifdef HBP
  185.             fill_line_flat_opaque16(point, n, pixel);
  186.             point += n;
  187. #else
  188.             while (n > 0) {
  189.                 *point = pixel;
  190.                 point++;
  191.                 n--;
  192.             }
  193. #endif
  194.             if (end_alpha > 0) {
  195.                 *point = mix_alpha16(*point, pixel, end_alpha);
  196.             }
  197.         }
  198.     } else {
  199.  
  200.         start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
  201.         end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
  202.  
  203.         start >>= FRAC_BITS;
  204.         end >>= FRAC_BITS;
  205.  
  206.         point = &line[start];
  207.  
  208.         if (start == end) {
  209.             *point = mix_alpha16(*point, pixel,
  210.                                ((start_alpha + end_alpha - 255) * alpha) >> 8);
  211.         } else {
  212.             n = end-start;
  213.             if (start_alpha < 255) {
  214.                 *point = mix_alpha16(*point, pixel, (start_alpha * alpha) >> 8);
  215.                 point++;
  216.                 n--;
  217.             }
  218. #ifdef HBP
  219.             fill_line_flat16(point, n, pixel, alpha);
  220.             point += n;
  221. #else
  222.             while (n > 0) {
  223.                 *point = mix_alpha16(*point, pixel, alpha);
  224.                 point++;
  225.                 n--;
  226.             }
  227. #endif
  228.             if (end_alpha > 0) {
  229.                 *point = mix_alpha16(*point, pixel, (end_alpha * alpha) >> 8);
  230.             }
  231.         }
  232.     }
  233. }
  234.  
  235. void
  236. GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end)
  237. {
  238.     register long   n;
  239.         TYPE *line,*point;
  240. #ifdef HBP
  241.         long pixel;
  242. #else
  243.         TYPE pixel;
  244. #endif
  245.         unsigned int alpha;
  246.  
  247.     if (clip(y,start,end)) return;
  248.  
  249.         start >>= FRAC_BITS;
  250.         end >>= FRAC_BITS;
  251.  
  252.     line = (TYPE *)(canvasBuffer + bpl*y);
  253.     point = &line[start];
  254.     n = end-start;
  255.         pixel = f->color.pixel;
  256. #ifdef HBP
  257.         if (y &1)  pixel = (pixel<<16) | (pixel>>16);
  258. #endif
  259.         alpha = f->color.alpha;
  260.         if (alpha == ALPHA_OPAQUE) {
  261. #ifdef HBP
  262.             fill_line_flat_opaque16(point, n, pixel);
  263. #else
  264.             while (n--) {
  265.         *point = pixel;
  266.         point++;
  267.             }
  268. #endif
  269.         } else {
  270. #ifdef HBP
  271.           fill_line_flat16(point, n, pixel, alpha);
  272. #else
  273.           while (n--) {
  274.             *point = mix_alpha(*point, pixel, alpha);
  275.         point++;
  276.           }
  277. #endif
  278.         }
  279. }
  280.  
  281. /* 16 bit assumed... easy to change */
  282. void
  283. GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
  284. {
  285.     int n;
  286.     long x1,y1,dx,dy;
  287.     Matrix *m = &f->bitmap_matrix;
  288.     Bitmap *b = f->bitmap;
  289.     unsigned char *pixels;
  290.     unsigned short *p;
  291.     Color *cmap;
  292.     long pixbpl;
  293.     TYPE pixel;
  294.     int offset;
  295.     unsigned char *alpha_table;
  296.  
  297.     /* safety test) */
  298.     if (!b) return;
  299.  
  300.     if (clip(y,start,end)) return;
  301.  
  302.     start /= FRAC;
  303.     end /= FRAC;
  304.     n = end - start;
  305.     p = (unsigned short *) (this->canvasBuffer + this->bpl*y + start * 2);
  306.  
  307.     /* the coordinates in the image are normalized to 16 bits */
  308. #ifdef HBP
  309.     x1 = start*m->a + y*m->b + m->tx;
  310.     y1 = start*m->c + y*m->d + m->ty;
  311.     dx = m->a;
  312.     dy = m->c;
  313. #else
  314.     x1 = (long) (m->a * start + m->b * y + m->tx);
  315.     y1 = (long) (m->c * start + m->d * y + m->ty);
  316.     dx = (long) (m->a);
  317.     dy = (long) (m->c);
  318. #endif
  319.  
  320.     pixels = b->pixels;
  321.     pixbpl = b->bpl;
  322.     cmap = f->cmap;
  323.  
  324.     if (b->alpha_buf == NULL) {
  325. #ifdef HBP
  326.       if (f->type == f_TiledBitmap) {
  327.         // step values may not be larger than the bitmap width or height
  328.         if ((dx>>16 > b->width) || (dy>>16 > b->height))  dx = dy = 0;
  329.         // make sure start point is within bitmap
  330.         x1 = x1 % (b->width<<16);
  331.         if (x1 < 0)  x1 += b->width<<16;
  332.         y1 = y1 % (b->height<<16);
  333.         if (y1 < 0)  y1 += b->height<<16;
  334.         fill_line_flat_bitmap16(p, n, cmap, pixels, pixbpl,
  335.                                 x1, y1, dx, dy,
  336.                                 b->width, b->height, 1);
  337.       } else {
  338.         fill_line_flat_bitmap16(p, n, cmap, pixels, pixbpl,
  339.                                 x1, y1, dx, dy,
  340.                                 b->width, b->height, 0);
  341.       }
  342. #else
  343.         while (n) {
  344.             if (x1 >= 0 && y1 >= 0 &&
  345.                 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
  346.  
  347.                 pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
  348.                 *p = pixel;
  349.             }
  350.             x1 += dx;
  351.             y1 += dy;
  352.             p++;
  353.             n--;
  354.         }
  355. #endif
  356.     } else if (f->alpha_table) {
  357. #ifdef HBP
  358.       if (f->type == f_TiledBitmap) {
  359.         // step values may not be larger than the bitmap width or height
  360.         if ((dx>>16 > b->width) || (dy>>16 > b->height))  dx = dy = 0;
  361.         // make sure start point is within bitmap
  362.         x1 = x1 % (b->width<<16);
  363.         if (x1 < 0)  x1 += b->width<<16;
  364.         y1 = y1 % (b->height<<16);
  365.         if (y1 < 0)  y1 += b->height<<16;
  366.         fill_line_alpha_chn_bitmap16(p, n, cmap, pixels, pixbpl,
  367.                      x1, y1, dx, dy, f->alpha_table, b->alpha_buf,
  368.                      b->width, b->height, 1);
  369.       } else {
  370.         fill_line_alpha_chn_bitmap16(p, n, cmap, pixels, pixbpl,
  371.                      x1, y1, dx, dy, f->alpha_table, b->alpha_buf,
  372.                      b->width, b->height, 0);
  373.       }
  374. #else
  375.         alpha_table = f->alpha_table;
  376.         while (n) {
  377.             if (x1 >= 0 && y1 >= 0 &&
  378.                 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
  379.  
  380.                 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
  381.                 pixel = cmap[pixels[offset]].pixel;
  382.                 *p = mix_alpha16(*p, pixel, alpha_table[b->alpha_buf[offset]]);
  383.             }
  384.             x1 += dx;
  385.             y1 += dy;
  386.             p++;
  387.             n--;
  388.         }
  389. #endif
  390.     } else {
  391. #ifdef HBP
  392.       if (f->type == f_TiledBitmap) {
  393.         // step values may not be larger than the bitmap width or height
  394.         if ((dx>>16 > b->width) || (dy>>16 > b->height))  dx = dy = 0;
  395.         // make sure start point is within bitmap
  396.         x1 = x1 % (b->width<<16);
  397.         if (x1 < 0)  x1 += b->width<<16;
  398.         y1 = y1 % (b->height<<16);
  399.         if (y1 < 0)  y1 += b->height<<16;
  400.         fill_line_alpha_bitmap16(p, n, cmap, pixels, pixbpl,
  401.                      x1, y1, dx, dy, b->alpha_buf,
  402.                      b->width, b->height, 1);
  403.       } else {
  404.         fill_line_alpha_bitmap16(p, n, cmap, pixels, pixbpl,
  405.                      x1, y1, dx, dy, b->alpha_buf,
  406.                      b->width, b->height, 0);
  407.       }
  408. #else
  409.       while (n) {
  410.             if (x1 >= 0 && y1 >= 0 &&
  411.                 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
  412.  
  413.                 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
  414.                 pixel = cmap[pixels[offset]].pixel;
  415.                 *p = mix_alpha16(*p, pixel, b->alpha_buf[offset]);
  416.             }
  417.             x1 += dx;
  418.             y1 += dy;
  419.             p++;
  420.             n--;
  421.         }
  422. #endif
  423.     }
  424. }
  425.  
  426.  
  427. /* XXX: clipping should be better handled */
  428. void
  429. GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end)
  430. {
  431.     long dr,r,v,r2;
  432.     register long n;
  433.     TYPE *line;
  434.     TYPE *point;
  435.         Color *cp,*ramp;
  436.         Matrix *m = &grad->imat;
  437.         unsigned int start_alpha,end_alpha;
  438.  
  439.     if (clip(y,start,end)) return;
  440.  
  441.         start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
  442.         end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
  443.  
  444.     start /= FRAC;
  445.     end /= FRAC;
  446.  
  447.     n = end-start;
  448.  
  449. //fprintf(stderr, "%d mat: a %f, b %f, tx %ld, start %d, end %d, y %d\n", __LINE__, m->a, m->b, m->tx, start, end, y);
  450. #if 1
  451. #define SHIFTIT 10
  452.         r = (((long)m->a) >> 6) * start + (((long)m->b) >> 6) * y + (m->tx >> 6);
  453.         dr = ((long)(m->a)) >> 6;
  454.  
  455. #else
  456. #define SHIFTIT 16
  457.         r = (long) (m->a * start + m->b * y + m->tx);
  458.         dr = (long) (m->a);
  459. #endif
  460.  
  461.         ramp = grad->ramp;
  462.  
  463.         line = (TYPE *)(canvasBuffer + bpl*y);
  464.     point = &line[start];
  465.  
  466.         r2 = r + n * dr;
  467.         if ( ((r | r2) & ~255) == 0 ) {
  468.             if (!grad->has_alpha) {
  469. #ifdef FULL_AA
  470.         if (start_alpha < 255) {
  471.                     v = r>>SHIFTIT;
  472.                     *point = mix_alpha16(*point, (TYPE)ramp[v].pixel, start_alpha);
  473.                     point++;
  474.                     r += dr;
  475.             n--;
  476.         }
  477. #endif /* FULL_AA */
  478.  
  479. #ifdef HBP
  480.                 r = fill_line_ramp_opaque16(point, n, ramp, r, dr);
  481.                 point += n;
  482. #else
  483.                 while (n>0) {
  484.                     v = r>>SHIFTIT;
  485.                     *point = (TYPE)ramp[v].pixel;
  486.                     point++;
  487.                     r += dr;
  488.             n--;
  489.                 }
  490. #endif
  491. #ifdef FULL_AA
  492.         if (end_alpha > 0) {
  493.                     v = r>>SHIFTIT;
  494.                     *point = mix_alpha16(*point, (TYPE)ramp[v].pixel, end_alpha);
  495.         }
  496. #endif /* FULL_AA */
  497.             } else {
  498. #ifdef HBP
  499.                 fill_line_ramp16(point, n, ramp, r, dr);
  500. #else
  501.                 while (n--) {
  502.                     v = r>>SHIFTIT;
  503.                     cp = &ramp[v];
  504.                     *point = mix_alpha16(*point, cp->pixel, cp->alpha);
  505.                     point++;
  506.                     r += dr;
  507.                 }
  508. #endif
  509.             }
  510.         } else {
  511.             if (!grad->has_alpha) {
  512. #ifdef FULL_AA
  513.         if (start_alpha < 255) {
  514.                     v = r>>SHIFTIT;
  515.                     if (v < 0) v = 0;
  516.                     else if (v > 255) v = 255;
  517.                     *point = mix_alpha16(*point, (TYPE)ramp[v].pixel, start_alpha);
  518.                     point++;
  519.                     r += dr;
  520.             n--;
  521.         }
  522. #endif /* FULL_AA */
  523.  
  524. #ifdef HBP
  525.                 r = fill_line_ramp_2_opaque16(point, n, ramp, r, dr);
  526.                 point += n;
  527. #else
  528.                 while (n>0) {
  529.                     v = r>>SHIFTIT;
  530.                     if (v < 0) v = 0;
  531.                     else if (v > 255) v = 255;
  532.                     *point = (TYPE)ramp[v].pixel;
  533.                     point++;
  534.                     r += dr;
  535.             n--;
  536.                 }
  537. #endif
  538. #ifdef FULL_AA
  539.         if (end_alpha > 0) {
  540.                     v = r>>SHIFTIT;
  541.                     if (v < 0) v = 0;
  542.                     else if (v > 255) v = 255;
  543.                     *point = mix_alpha16(*point, (TYPE)ramp[v].pixel, end_alpha);
  544.         }
  545. #endif /* FULL_AA */
  546.             } else {
  547. #ifdef HBP
  548.                 fill_line_ramp_2_16(point, n, ramp, r, dr);
  549. #else
  550.                 while (n--) {
  551.                     v = r>>SHIFTIT;
  552.                     if (v < 0) v = 0;
  553.                     else if (v > 255) v = 255;
  554.                     cp = &ramp[v];
  555.                     *point = mix_alpha16(*point, cp->pixel, cp->alpha);
  556.                     point++;
  557.                     r += dr;
  558.                 }
  559. #endif
  560.             }
  561.         }
  562. }
  563.  
  564. ///////////// PLATFORM INDEPENDENT
  565. void
  566. GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end)
  567. {
  568.     long X,dx,r,Y,dy;
  569.     long dist2;
  570.     register long   n;
  571.         Color *cp,*ramp;
  572.     TYPE *line;
  573.     TYPE *point;
  574.         Matrix *m = &grad->imat;
  575.         unsigned int start_alpha,end_alpha;
  576.  
  577.     if (clip(y,start,end)) return;
  578.  
  579.         start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
  580.         end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
  581.  
  582.     start /= FRAC;
  583.     end /= FRAC;
  584.  
  585.     n = end-start;
  586. //fprintf(stderr, "mat: a %f, b %f, c %f, d %f, tx %ld, ty %ld\n", m->a, m->b, m->c, m->d, m->tx, m->ty);
  587. #if 1
  588.         X = ((((long)m->a >> 10 ) * start + (((long)m->b) >> 10) * y) << 10) + m->tx;
  589.         Y = ((((long)m->c >> 10 ) * start + (((long)m->d) >> 10) * y) << 10) + m->ty;
  590. #else
  591.         X = (long) (m->a * start + m->b * y + m->tx);
  592.         Y = (long) (m->c * start + m->d * y + m->ty);
  593. #endif
  594.         dx = (long) (m->a);
  595.         dy = (long) (m->c);
  596.  
  597.         ramp = grad->ramp;
  598.  
  599.     line = (TYPE *)(canvasBuffer + bpl*y);
  600.     point = &line[start];
  601.  
  602.         if (!grad->has_alpha) {
  603. #ifdef FULL_AA
  604.         if (start == end) {
  605.             dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
  606.             if ((unsigned long)dist2 >= 65536) {
  607.                 r = 255;
  608.             } else {
  609.                 r= SQRT[dist2];
  610.             }
  611.             *point = mix_alpha16(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
  612.         } else {
  613.             if (start_alpha < 255) {
  614.             dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
  615.             if ((unsigned long)dist2 >= 65536) {
  616.                 r = 255;
  617.             } else {
  618.                 r= SQRT[dist2];
  619.             }
  620.             *point = mix_alpha16(*point, (TYPE)ramp[r].pixel, start_alpha);
  621.             point++;
  622.             X += dx;
  623.             Y += dy;
  624.             n--;
  625.             }
  626. #endif /* FULL_AA */
  627.  
  628. #ifdef HBP
  629.                     fill_line_radial_ramp16(point, n, &X, &Y, dx, dy, ramp, SQRT);
  630.                     point += n;
  631. #else
  632.             while (n>0) {
  633.             dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
  634.             if ((unsigned long)dist2 >= 65536) {
  635.                 r = 255;
  636.             } else {
  637.                 r= SQRT[dist2];
  638.             }
  639.             *point = (TYPE)ramp[r].pixel;
  640.             point++;
  641.             X += dx;
  642.             Y += dy;
  643.             n--;
  644.             }
  645. #endif
  646. #ifdef FULL_AA
  647.             if (end_alpha > 0) {
  648.             dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
  649.             if ((unsigned long)dist2 >= 65536) {
  650.                 r = 255;
  651.             } else {
  652.                 r= SQRT[dist2];
  653.             }
  654.             *point = mix_alpha16(*point, (TYPE)ramp[r].pixel, end_alpha);
  655.             }
  656.         }
  657. #endif /* FULL_AA */
  658.  
  659.         } else {
  660. #ifdef HBP
  661.           fill_line_radial_ramp_2_16(point, n, &X, &Y, dx, dy, ramp, SQRT);
  662.           point += n;
  663. #else
  664.           while (n--) {
  665.         dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
  666.         if ((unsigned long)dist2 >= 65536) {
  667.                     r = 255;
  668.         } else {
  669.                     r= SQRT[dist2];
  670.         }
  671.                 cp = &ramp[r];
  672.         *point = mix_alpha16(*point, cp->pixel, cp->alpha);
  673.         point++;
  674.         X += dx;
  675.         Y += dy;
  676.             }
  677. #endif
  678.         }
  679. }
  680.  
  681. /* XXX: should use polygon rasterizer to handle width */
  682. /* XXX: handle only 16 bit case */
  683. /* XXX: must be clipped */
  684.  
  685. void
  686. GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width)
  687. {
  688.     int n,adr,dx,dy,sx,color;
  689.     register int a;
  690.     register unsigned short *pp;
  691.     int alpha;
  692.  
  693. #if 0
  694.     x1 = (x1 + (FRAC/2)) >> FRAC_BITS;
  695.     y1 = (y1 + (FRAC/2)) >> FRAC_BITS;
  696.     x2 = (x2 + (FRAC/2)) >> FRAC_BITS;
  697.     y2 = (y2 + (FRAC/2)) >> FRAC_BITS;
  698. #else
  699.     x1 = (x1) >> FRAC_BITS;
  700.     y1 = (y1) >> FRAC_BITS;
  701.     x2 = (x2) >> FRAC_BITS;
  702.     y2 = (y2) >> FRAC_BITS;
  703. #endif
  704.  
  705.     if (y1 > y2 || (y1 == y2 && x1 > x2)) {
  706.         long tmp;
  707.  
  708.         tmp=x1;
  709.         x1=x2;
  710.         x2=tmp;
  711.  
  712.         tmp=y1;
  713.         y1=y2;
  714.         y2=tmp;
  715.     }
  716.  
  717.     if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
  718.     if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
  719.     if (x1 == x2 && y1 == y2) return;    // Bad !!!
  720.  
  721.     if (y1 < clip_rect.ymin && y1 != y2) {
  722.     x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
  723.     y1 = clip_rect.ymin;
  724.     }
  725.  
  726.     if (y2 > clip_rect.ymax && y1 != y2) {
  727.     x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
  728.     y2 = clip_rect.ymax;
  729.     }
  730.  
  731.     if (x1 < x2) {
  732.         if (x1 < clip_rect.xmin && x1 != x2) {
  733.         y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
  734.         x1 = clip_rect.xmin;
  735.         }
  736.  
  737.         if (x2 > clip_rect.xmax && x1 != x2) {
  738.         y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
  739.         x2 = clip_rect.xmax;
  740.         }
  741.     }
  742.  
  743.     if (x1 > x2) {
  744.         if (x2 < clip_rect.xmin && x2 != x1) {
  745.         y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
  746.         x2 = clip_rect.xmin;
  747.         }
  748.  
  749.         if (x1 > clip_rect.xmax && x2 != x1) {
  750.         y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
  751.         x1 = clip_rect.xmax;
  752.         }
  753.     }
  754.  
  755.     // Check again
  756.     if (x1 == x2 && y1 == y2) return;
  757.     if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
  758.     if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
  759.     if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
  760.     if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
  761.  
  762.     sx=bpl >> 1;
  763.     adr=(y1 * sx + x1);
  764.     pp = (unsigned short *)canvasBuffer + adr;
  765.  
  766.     dx = x2 - x1;
  767.     dy = y2 - y1;
  768.  
  769.     color = allocColor(foregroundColor);
  770.     alpha = foregroundColor.alpha;
  771.  
  772.     if (alpha == ALPHA_OPAQUE) {
  773.  
  774. #define PUTPIXEL()                 \
  775.   {                        \
  776.       *pp=color;                        \
  777.   }
  778.  
  779. #define DRAWLINE(dx,dy,inc_1,inc_2) \
  780.     n=dx;\
  781.     a=2*dy-dx;\
  782.     dy=2*dy;\
  783.     dx=2*dx-dy;\
  784.      do {\
  785.       PUTPIXEL();\
  786.             if (a>0) { pp+=(inc_1); a-=dx; }\
  787.             else { pp+=(inc_2); a+=dy; }\
  788.      } while (--n >= 0);
  789.  
  790. /* fin macro */
  791.  
  792.   if (dx == 0 && dy == 0) {
  793.     PUTPIXEL();
  794.   } else if (dx > 0) {
  795.     if (dx >= dy) {
  796.       DRAWLINE(dx, dy, sx + 1, 1);
  797.     } else {
  798.       DRAWLINE(dy, dx, sx + 1, sx);
  799.     }
  800.   } else {
  801.     dx = -dx;
  802.     if (dx >= dy) {
  803.       DRAWLINE(dx, dy, sx - 1, -1);
  804.     } else {
  805.       DRAWLINE(dy, dx, sx - 1, sx);
  806.     }
  807.   }
  808.  
  809.  
  810. #undef DRAWLINE
  811. #undef PUTPIXEL
  812.     } else {
  813. #define PUTPIXEL()                 \
  814.   {                        \
  815.       *pp=mix_alpha16(*pp,color,alpha);            \
  816.   }
  817.  
  818. #define DRAWLINE(dx,dy,inc_1,inc_2) \
  819.     n=dx;\
  820.     a=2*dy-dx;\
  821.     dy=2*dy;\
  822.     dx=2*dx-dy;\
  823.      do {\
  824.       PUTPIXEL();\
  825.             if (a>0) { pp+=(inc_1); a-=dx; }\
  826.             else { pp+=(inc_2); a+=dy; }\
  827.      } while (--n >= 0);
  828.  
  829. /* fin macro */
  830.  
  831.   if (dx == 0 && dy == 0) {
  832.     PUTPIXEL();
  833.   } else if (dx > 0) {
  834.     if (dx >= dy) {
  835.       DRAWLINE(dx, dy, sx + 1, 1);
  836.     } else {
  837.       DRAWLINE(dy, dx, sx + 1, sx);
  838.     }
  839.   } else {
  840.     dx = -dx;
  841.     if (dx >= dy) {
  842.       DRAWLINE(dx, dy, sx - 1, -1);
  843.     } else {
  844.       DRAWLINE(dy, dx, sx - 1, sx);
  845.     }
  846.   }
  847.  
  848.  
  849. #undef DRAWLINE
  850. #undef PUTPIXEL
  851.     }
  852. }
  853.  
  854.