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