summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/graphic32.cc
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/graphic32.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/graphic32.cc657
1 files changed, 657 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/graphic32.cc b/core/multimedia/opieplayer/libflash/graphic32.cc
new file mode 100644
index 0000000..b9c2008
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic32.cc
@@ -0,0 +1,657 @@
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
25#include "graphic32.h"
26
27extern unsigned char SQRT[];
28
29#define FULL_AA
30
31#define PRINT 0
32
33typedef unsigned long TYPE;
34
35GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd)
36{
37}
38
39long
40GraphicDevice32::allocColor(Color color)
41{
42 return (color.red)<<16 | (color.green)<<8 | (color.blue);
43}
44
45void
46GraphicDevice32::clearCanvas()
47{
48 TYPE pixel;
49 TYPE *point,*p;
50 long h, w,n;
51
52 if (!bgInitialized) return;
53
54 pixel = allocColor(backgroundColor);
55
56 point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
57 w = clip_rect.xmax - clip_rect.xmin;
58 h = clip_rect.ymax - clip_rect.ymin;
59
60 while (h--) {
61 p = point;
62 n = w;
63 while (n--) {
64 *p++ = pixel;
65 }
66
67 point = (TYPE *)((char *)point + bpl);
68 }
69
70 flashDisplay->flash_refresh = 1;
71 flashDisplay->clip_x = clip_rect.xmin;
72 flashDisplay->clip_y = clip_rect.ymin;
73 flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
74 flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
75}
76
77#define RED_MASK 0xFF0000
78#define GREEN_MASK 0x00FF00
79#define BLUE_MASK 0x0000FF
80
81/* alpha = 0 : select c1, alpha = 255 select c2 */
82static inline unsigned long
83mix_alpha(unsigned long c1, unsigned long c2, int alpha)
84{
85 long r1,r2,r;
86 long g1,g2,g;
87 long b1,b2,b;
88
89 r1 = c1 & RED_MASK;
90 r2 = c2 & RED_MASK;
91 r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
92
93 g1 = c1 & GREEN_MASK;
94 g2 = c2 & GREEN_MASK;
95 g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
96
97 b1 = c1 & BLUE_MASK;
98 b2 = c2 & BLUE_MASK;
99 b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
100
101 return (r|g|b);
102}
103
104void
105GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end)
106{
107 register long n;
108 TYPE *line;
109 TYPE *point,pixel;
110 unsigned int alpha, start_alpha,end_alpha;
111
112 if (clip(y,start,end)) return;
113
114 line = (TYPE *)(canvasBuffer + bpl*y);
115
116 alpha = f->color.alpha;
117 pixel = f->color.pixel;
118
119 if (alpha == ALPHA_OPAQUE) {
120
121 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
122 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
123
124 start >>= FRAC_BITS;
125 end >>= FRAC_BITS;
126
127 point = &line[start];
128
129 if (start == end) {
130 *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
131 } else {
132 n = end-start;
133 if (start_alpha < 255) {
134 *point = mix_alpha(*point, pixel, start_alpha);
135 point++;
136 n--;
137 }
138 while (n > 0) {
139 *point = pixel;
140 point++;
141 n--;
142 }
143 if (end_alpha > 0) {
144 *point = mix_alpha(*point, pixel, end_alpha);
145 }
146 }
147 } else {
148
149 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
150 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
151
152 start >>= FRAC_BITS;
153 end >>= FRAC_BITS;
154
155 point = &line[start];
156
157 if (start == end) {
158 *point = mix_alpha(*point, pixel,
159 ((start_alpha + end_alpha - 255) * alpha) >> 8);
160 } else {
161 n = end-start;
162 if (start_alpha < 255) {
163 *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
164 point++;
165 n--;
166 }
167 while (n > 0) {
168 *point = mix_alpha(*point, pixel, alpha);
169 point++;
170 n--;
171 }
172 if (end_alpha > 0) {
173 *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
174 }
175 }
176 }
177}
178
179void
180GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end)
181{
182 register long n;
183 TYPE *line,*point;
184 TYPE pixel;
185 unsigned int alpha;
186
187 if (clip(y,start,end)) return;
188
189 start >>= FRAC_BITS;
190 end >>= FRAC_BITS;
191
192 line = (TYPE *)(canvasBuffer + bpl*y);
193 point = &line[start];
194 n = end-start;
195 pixel = f->color.pixel;
196 alpha = f->color.alpha;
197 if (alpha == ALPHA_OPAQUE) {
198 while (n--) {
199 *point = pixel;
200 point++;
201 }
202 } else {
203 while (n--) {
204 *point = mix_alpha(*point, pixel, alpha);
205 point++;
206 }
207 }
208}
209
210void
211GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
212{
213 int n;
214 long x1,y1,dx,dy;
215 Matrix *m = &f->bitmap_matrix;
216 Bitmap *b = f->bitmap;
217 unsigned char *pixels;
218 TYPE *p;
219 Color *cmap;
220 long pixbpl;
221 TYPE pixel;
222 int offset;
223 unsigned char *alpha_table;
224
225 /* safety test) */
226 if (!b) return;
227
228 if (clip(y,start,end)) return;
229
230 start /= FRAC;
231 end /= FRAC;
232 n = end - start;
233 p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE));
234
235 /* the coordinates in the image are normalized to 16 bits */
236 x1 = (long) (m->a * start + m->b * y + m->tx);
237 y1 = (long) (m->c * start + m->d * y + m->ty);
238 dx = (long) (m->a);
239 dy = (long) (m->c);
240
241 pixels = b->pixels;
242 pixbpl = b->bpl;
243 cmap = f->cmap;
244
245 if (b->alpha_buf == NULL) {
246 while (n) {
247 if (x1 >= 0 && y1 >= 0 &&
248 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
249
250 pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
251 *p = pixel;
252 }
253 x1 += dx;
254 y1 += dy;
255 p++;
256 n--;
257 }
258 } else if (f->alpha_table) {
259 alpha_table = f->alpha_table;
260 while (n) {
261 if (x1 >= 0 && y1 >= 0 &&
262 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
263
264 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
265 pixel = cmap[pixels[offset]].pixel;
266 *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
267 }
268 x1 += dx;
269 y1 += dy;
270 p++;
271 n--;
272 }
273 } else {
274 while (n) {
275 if (x1 >= 0 && y1 >= 0 &&
276 (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
277
278 offset = (y1 >> 16) * pixbpl + (x1 >> 16);
279 pixel = cmap[pixels[offset]].pixel;
280 *p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
281 }
282 x1 += dx;
283 y1 += dy;
284 p++;
285 n--;
286 }
287 }
288}
289
290void
291GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end)
292{
293 long dr,r,v,r2;
294 register long n;
295 TYPE *line;
296 TYPE *point;
297 Color *cp,*ramp;
298 Matrix *m = &grad->imat;
299 unsigned int start_alpha,end_alpha;
300
301 if (clip(y,start,end)) return;
302
303 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
304 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
305
306 start /= FRAC;
307 end /= FRAC;
308
309 n = end-start;
310
311 r = (long) (m->a * start + m->b * y + m->tx);
312 dr = (long) (m->a);
313
314 ramp = grad->ramp;
315
316 line = (TYPE *)(canvasBuffer + bpl*y);
317 point = &line[start];
318
319 r2 = r + n * dr;
320 if ( ((r | r2) & ~255) == 0 ) {
321 if (!grad->has_alpha) {
322#ifdef FULL_AA
323 if (start_alpha < 255) {
324 v = r>>16;
325 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
326 point++;
327 r += dr;
328 n--;
329 }
330#endif /* FULL_AA */
331 while (n>0) {
332 v = r>>16;
333 *point = (TYPE)ramp[v].pixel;
334 point++;
335 r += dr;
336 n--;
337 }
338#ifdef FULL_AA
339 if (end_alpha > 0) {
340 v = r>>16;
341 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
342 }
343#endif /* FULL_AA */
344 } else {
345 while (n--) {
346 v = r>>16;
347 cp = &ramp[v];
348 *point = mix_alpha(*point, cp->pixel, cp->alpha);
349 point++;
350 r += dr;
351 }
352 }
353 } else {
354 if (!grad->has_alpha) {
355#ifdef FULL_AA
356 if (start_alpha < 255) {
357 v = r>>16;
358 if (v < 0) v = 0;
359 else if (v > 255) v = 255;
360 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
361 point++;
362 r += dr;
363 n--;
364 }
365#endif /* FULL_AA */
366 while (n>0) {
367 v = r>>16;
368 if (v < 0) v = 0;
369 else if (v > 255) v = 255;
370 *point = (TYPE)ramp[v].pixel;
371 point++;
372 r += dr;
373 n--;
374 }
375#ifdef FULL_AA
376 if (end_alpha > 0) {
377 v = r>>16;
378 if (v < 0) v = 0;
379 else if (v > 255) v = 255;
380 *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
381 }
382#endif /* FULL_AA */
383 } else {
384 while (n--) {
385 v = r>>16;
386 if (v < 0) v = 0;
387 else if (v > 255) v = 255;
388 cp = &ramp[v];
389 *point = mix_alpha(*point, cp->pixel, cp->alpha);
390 point++;
391 r += dr;
392 }
393 }
394 }
395}
396
397void
398GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end)
399{
400 long X,dx,r,Y,dy;
401 long dist2;
402 register long n;
403 Color *cp,*ramp;
404 TYPE *line;
405 TYPE *point;
406 Matrix *m = &grad->imat;
407 unsigned int start_alpha,end_alpha;
408
409 if (clip(y,start,end)) return;
410
411 start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
412 end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
413
414 start /= FRAC;
415 end /= FRAC;
416
417 n = end-start;
418
419 X = (long) (m->a * start + m->b * y + m->tx);
420 Y = (long) (m->c * start + m->d * y + m->ty);
421 dx = (long) (m->a);
422 dy = (long) (m->c);
423
424 ramp = grad->ramp;
425
426 line = (TYPE *)(canvasBuffer + bpl*y);
427 point = &line[start];
428
429 if (!grad->has_alpha) {
430#ifdef FULL_AA
431 if (start == end) {
432 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
433 if ((unsigned long)dist2 >= 65536) {
434 r = 255;
435 } else {
436 r = SQRT[dist2];
437 }
438 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
439 } else {
440 if (start_alpha < 255) {
441 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
442 if ((unsigned long)dist2 >= 65536) {
443 r = 255;
444 } else {
445 r = SQRT[dist2];
446 }
447 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
448 point++;
449 X += dx;
450 Y += dy;
451 n--;
452 }
453#endif /* FULL_AA */
454 while (n>0) {
455 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
456 if ((unsigned long)dist2 >= 65536) {
457 r = 255;
458 } else {
459 r= SQRT[dist2];
460 }
461 *point = (TYPE)ramp[r].pixel;
462 point++;
463 X += dx;
464 Y += dy;
465 n--;
466 }
467#ifdef FULL_AA
468 if (end_alpha > 0) {
469 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
470 if ((unsigned long)dist2 >= 65536) {
471 r = 255;
472 } else {
473 r= SQRT[dist2];
474 }
475 *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
476 }
477 }
478#endif /* FULL_AA */
479
480 } else {
481 while (n--) {
482 dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
483 if ((unsigned long)dist2 >= 65536) {
484 r = 255;
485 } else {
486 r= SQRT[dist2];
487 }
488 cp = &ramp[r];
489 *point = mix_alpha(*point, cp->pixel, cp->alpha);
490 point++;
491 X += dx;
492 Y += dy;
493 }
494 }
495}
496
497void
498GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width)
499{
500 int n,adr,dx,dy,sx,color;
501 register int a;
502 register TYPE *pp;
503 int alpha;
504
505 x1 = (x1) >> FRAC_BITS;
506 y1 = (y1) >> FRAC_BITS;
507 x2 = (x2) >> FRAC_BITS;
508 y2 = (y2) >> FRAC_BITS;
509
510 if (y1 > y2 || (y1 == y2 && x1 > x2)) {
511 long tmp;
512
513 tmp=x1;
514 x1=x2;
515 x2=tmp;
516
517 tmp=y1;
518 y1=y2;
519 y2=tmp;
520 }
521
522 if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
523 if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
524 if (x1 == x2 && y1 == y2) return;// Bad !!!
525
526 if (y1 < clip_rect.ymin && y1 != y2) {
527 x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
528 y1 = clip_rect.ymin;
529 }
530
531 if (y2 > clip_rect.ymax && y1 != y2) {
532 x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
533 y2 = clip_rect.ymax;
534 }
535
536 if (x1 < x2) {
537 if (x1 < clip_rect.xmin && x1 != x2) {
538 y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
539 x1 = clip_rect.xmin;
540 }
541
542 if (x2 > clip_rect.xmax && x1 != x2) {
543 y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
544 x2 = clip_rect.xmax;
545 }
546 }
547
548 if (x1 > x2) {
549 if (x2 < clip_rect.xmin && x2 != x1) {
550 y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
551 x2 = clip_rect.xmin;
552 }
553
554 if (x1 > clip_rect.xmax && x2 != x1) {
555 y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
556 x1 = clip_rect.xmax;
557 }
558 }
559
560 // Check again
561 if (x1 == x2 && y1 == y2) return;
562 if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
563 if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
564 if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
565 if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
566
567 sx=bpl >> 1;
568 adr=(y1 * sx + x1);
569 pp = (TYPE *)canvasBuffer + adr;
570
571 dx = x2 - x1;
572 dy = y2 - y1;
573
574 color = allocColor(foregroundColor);
575 alpha = foregroundColor.alpha;
576
577 if (alpha == ALPHA_OPAQUE) {
578
579 #define PUTPIXEL() \
580 { \
581 *pp=color; \
582 }
583
584#define DRAWLINE(dx,dy,inc_1,inc_2) \
585 n=dx;\
586 a=2*dy-dx;\
587 dy=2*dy;\
588 dx=2*dx-dy;\
589 do {\
590 PUTPIXEL();\
591 if (a>0) { pp+=(inc_1); a-=dx; }\
592 else { pp+=(inc_2); a+=dy; }\
593 } while (--n >= 0);
594
595/* fin macro */
596
597 if (dx == 0 && dy == 0) {
598 PUTPIXEL();
599 } else if (dx > 0) {
600 if (dx >= dy) {
601 DRAWLINE(dx, dy, sx + 1, 1);
602 } else {
603 DRAWLINE(dy, dx, sx + 1, sx);
604 }
605 } else {
606 dx = -dx;
607 if (dx >= dy) {
608 DRAWLINE(dx, dy, sx - 1, -1);
609 } else {
610 DRAWLINE(dy, dx, sx - 1, sx);
611 }
612 }
613
614
615#undef DRAWLINE
616#undef PUTPIXEL
617 } else {
618 #define PUTPIXEL() \
619 { \
620 *pp=mix_alpha(*pp,color,alpha); \
621 }
622
623#define DRAWLINE(dx,dy,inc_1,inc_2) \
624 n=dx;\
625 a=2*dy-dx;\
626 dy=2*dy;\
627 dx=2*dx-dy;\
628 do {\
629 PUTPIXEL();\
630 if (a>0) { pp+=(inc_1); a-=dx; }\
631 else { pp+=(inc_2); a+=dy; }\
632 } while (--n >= 0);
633
634/* fin macro */
635
636 if (dx == 0 && dy == 0) {
637 PUTPIXEL();
638 } else if (dx > 0) {
639 if (dx >= dy) {
640 DRAWLINE(dx, dy, sx + 1, 1);
641 } else {
642 DRAWLINE(dy, dx, sx + 1, sx);
643 }
644 } else {
645 dx = -dx;
646 if (dx >= dy) {
647 DRAWLINE(dx, dy, sx - 1, -1);
648 } else {
649 DRAWLINE(dy, dx, sx - 1, sx);
650 }
651 }
652
653
654#undef DRAWLINE
655#undef PUTPIXEL
656 }
657}