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