summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/graphic.cc
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/graphic.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/graphic.cc632
1 files changed, 632 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/graphic.cc b/core/multimedia/opieplayer/libflash/graphic.cc
new file mode 100644
index 0000000..f65011e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic.cc
@@ -0,0 +1,632 @@
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#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29#define PRINT 0
30
31// Public
32
33GraphicDevice::GraphicDevice(FlashDisplay *fd)
34{
35 flashDisplay = fd;
36
37 bgInitialized = 0;
38
39 // Reset flash refresh flag
40 flashDisplay->flash_refresh = 0;
41
42 /* 16 bits, RGB565 */
43 redMask = 0xF800;
44 greenMask = 0x07E0;
45 blueMask = 0x001F;
46
47 /* should be the actual window size */
48 targetWidth = fd->width;
49 targetHeight = fd->height;
50 bpl = fd->bpl;
51
52#if PRINT
53 printf("Target Width = %d\n", targetWidth);
54 printf("Target Height = %d\n", targetHeight);
55#endif
56
57 zoom = FRAC;
58 movieWidth = targetWidth;
59 movieHeight = targetHeight;
60
61 viewPort.xmin = 0;
62 viewPort.xmax = targetWidth-1;
63 viewPort.ymin = 0;
64 viewPort.ymax = targetHeight-1;
65
66 canvasBuffer = (unsigned char *) fd->pixels;
67
68 adjust = new Matrix;
69 foregroundColor.red = 0;
70 foregroundColor.green = 0;
71 foregroundColor.blue = 0;
72 foregroundColor.alpha = ALPHA_OPAQUE;
73
74 backgroundColor.red = 0;
75 backgroundColor.green = 0;
76 backgroundColor.blue = 0;
77 backgroundColor.alpha = ALPHA_OPAQUE;
78
79 showMore = 0;
80
81 setClipping(0);// Reset
82 setClipping(1);
83
84 /* polygon rasterizer : handle memory errors ! */
85
86 height = targetHeight;
87 segs = (Segment **)malloc(height * sizeof(Segment *));
88 memset(segs, 0, height * sizeof(Segment *));
89 ymin = height;
90 ymax = -1;
91
92 seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment));
93 seg_pool_cur = seg_pool;
94}
95
96GraphicDevice::~GraphicDevice()
97{
98 free(segs);
99 free(seg_pool);
100
101 if (adjust) {
102 delete adjust;
103 }
104}
105
106Color *
107GraphicDevice::getColormap(Color *old, long n, Cxform *cxform)
108{
109 Color *newCmp;
110
111 newCmp = new Color[n];
112 if (newCmp == NULL) return NULL;
113
114 if (cxform) {
115 for(long i = 0; i < n; i++)
116 {
117 newCmp[i] = cxform->getColor(old[i]);
118 newCmp[i].pixel = allocColor(newCmp[i]);
119 }
120 } else {
121 for(long i = 0; i < n; i++)
122 {
123 newCmp[i] = old[i];
124 newCmp[i].pixel = allocColor(old[i]);
125 }
126 }
127
128 return newCmp;
129}
130
131long
132GraphicDevice::getHeight()
133{
134 return targetHeight;
135}
136
137long
138GraphicDevice::getWidth()
139{
140 return targetWidth;
141}
142
143Color
144GraphicDevice::getForegroundColor()
145{
146 return foregroundColor;
147}
148
149void
150GraphicDevice::setForegroundColor(Color color)
151{
152 foregroundColor = color;
153}
154
155Color
156GraphicDevice::getBackgroundColor()
157{
158 return backgroundColor;
159}
160
161int
162GraphicDevice::setBackgroundColor(Color color)
163{
164 if (bgInitialized == 0) {
165 backgroundColor = color;
166 clearCanvas();
167 bgInitialized = 1;
168 return 1;
169 }
170 return 0;
171}
172
173void
174GraphicDevice::setMovieDimension(long width, long height)
175{
176 float xAdjust, yAdjust;
177
178 movieWidth = width;
179 movieHeight = height;
180
181 xAdjust = (float)targetWidth*zoom/(float)width;
182 yAdjust = (float)targetHeight*zoom/(float)height;
183
184 if (xAdjust < yAdjust) {
185 adjust->a = xAdjust;
186 adjust->d = xAdjust;
187 adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2;
188 viewPort.ymin = adjust->ty/zoom;
189 viewPort.ymax = targetHeight-viewPort.ymin-1;
190 } else {
191 adjust->a = yAdjust;
192 adjust->d = yAdjust;
193 adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2;
194 viewPort.xmin = adjust->tx/zoom;
195 viewPort.xmax = targetWidth-viewPort.xmin-1;
196 }
197
198 if (viewPort.xmin < 0) viewPort.xmin = 0;
199 if (viewPort.ymin < 0) viewPort.ymin = 0;
200 if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1;
201 if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1;
202}
203
204void
205GraphicDevice::setMovieZoom(int z)
206{
207 z *= FRAC;
208 if (z <= 0 || z > 100) return;
209 zoom = z;
210 setMovieDimension(movieWidth,movieHeight);
211}
212
213void
214GraphicDevice::setMovieOffset(long x, long y)
215{
216 adjust->tx = -zoom*x;
217 adjust->ty = -zoom*y;
218}
219
220long
221GraphicDevice::clip(long &y, long &start, long &end)
222{
223 long xmin,xend;
224
225 if (y < clip_rect.ymin ||
226 y >= clip_rect.ymax) return 1;
227 if (end <= start)
228 return 1;
229 xmin = clip_rect.xmin * FRAC;
230 xend = clip_rect.xmax * FRAC;
231
232 if (end <= xmin || start >= xend) return 1;
233
234 if (start < xmin) start = xmin;
235 if (end > xend) end = xend;
236
237 return 0;
238}
239
240void
241GraphicDevice::drawBox(long x1, long y1, long x2, long y2)
242{
243 int i;
244
245 for(i=0;i<FRAC*2;i++) {
246 drawLine(x1+i, y1+i, x2-i, y1+i, 0);
247 drawLine(x1+i, y2-i, x2-i, y2-i, 0);
248
249 drawLine(x1+i, y1+i+1, x1+i, y2-i-1, 0);
250 drawLine(x2-i, y1+i+1, x2-i, y2-i-1, 0);
251 }
252}
253
254/* polygon rasteriser */
255
256inline Segment *
257GraphicDevice::allocSeg()
258{
259 Segment *seg;
260
261 if ( (seg_pool_cur - seg_pool) >= NB_SEGMENT_MAX )
262 return NULL;
263 seg = seg_pool_cur++;
264
265 return seg;
266}
267
268/* add a segment to the current path */
269void
270GraphicDevice::addSegment(long x1, long y1, long x2, long y2,
271 FillStyleDef *f0,
272 FillStyleDef *f1,
273 int aa)
274{
275 Segment *seg,**segs;
276 long dX, X, Y, ymin, ymax, tmp;
277 FillStyleDef *ff;
278
279 if ( y1 == y2 ) {
280 return;
281 }
282
283 if (y1 < y2) {
284 ymin = y1;
285 ymax = y2;
286 ff = f0;
287 f0 = f1;
288 f1 = ff;
289 } else {
290 ymin = y2;
291 ymax = y1;
292 tmp = x1;
293 x1 = x2;
294 x2 = tmp;
295 }
296
297 if (ymax>>FRAC_BITS < clip_rect.ymin) {
298 return;
299 }
300 if (ymin>>FRAC_BITS > clip_rect.ymax) {
301 return;
302 }
303
304 X = x1 << SEGFRAC;
305 dX = ((x2 - x1)<<SEGFRAC)/(ymax-ymin);
306
307 if (ymin < 0) {
308 X += dX * (-ymin);
309 ymin = 0;
310 }
311
312 Y = (ymin + (FRAC-1)) & ~(FRAC-1);
313 if (Y > ymax) {
314 //printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax);
315 return;
316 }
317 X += dX * (Y-ymin);
318
319 Y >>= FRAC_BITS;
320 if (Y >= clip_rect.ymax) {
321 return;
322 }
323
324 seg = allocSeg();
325 if (seg == NULL) {
326 return;
327 }
328
329 seg->next = 0;
330 seg->nextValid = 0;
331 seg->aa = aa;
332 seg->ymax = ymax;
333 seg->x1 = x1;
334 seg->x2 = x2;
335 seg->X = X;
336 seg->dX = dX;
337 seg->fs[0] = f0;
338 seg->fs[1] = f1;
339
340 if (Y < this->ymin) this->ymin = Y;
341 ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS;
342 if (ymax >= this->height) ymax = this->height-1;
343 if (ymax > this->ymax) this->ymax = ymax;
344
345 segs = this->segs;
346
347 if (segs[Y] == 0) {
348 segs[Y] = seg;
349 } else {
350 Segment *s,*prev;
351
352 prev = 0;
353 for(s = segs[Y]; s; prev = s, s = s->next) {
354 if (s->X > seg->X) {
355 if (prev) {
356 prev->next = seg;
357 seg->next = s;
358 } else {
359 seg->next = segs[Y];
360 segs[Y] = seg;
361 }
362 break;
363 }
364 }
365 if (s == 0) {
366 prev->next = seg;
367 seg->next = s;
368 }
369 }
370}
371
372inline Segment *
373GraphicDevice::progressSegments(Segment * curSegs, long y)
374{
375 Segment *seg,*prev;
376
377 // Update current segments
378 seg = curSegs;
379 prev = 0;
380 while(seg)
381 {
382 if ((y*FRAC) > seg->ymax) {
383 // Remove this segment, no more valid
384 if (prev) {
385 prev->nextValid = seg->nextValid;
386 } else {
387 curSegs = seg->nextValid;
388 }
389 seg = seg->nextValid;
390 } else {
391 seg->X += seg->dX * FRAC;
392 prev = seg;
393 seg = seg->nextValid;
394 }
395 }
396 return curSegs;
397}
398
399inline Segment *
400GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs)
401{
402 Segment *s,*seg,*prev;
403
404 s = curSegs;
405 prev = 0;
406
407 // Check for new segments
408 for (seg = newSegs; seg; seg=seg->next)
409 {
410 // Place it at the correct position according to X
411 if (curSegs == 0) {
412 curSegs = seg;
413 seg->nextValid = 0;
414 } else {
415 for(; s; prev = s, s = s->nextValid)
416 {
417 if ( s->X > seg->X ||
418 ( (s->X == seg->X) &&
419 ( (seg->x1 == s->x1 && seg->dX < s->dX) ||
420 (seg->x2 == s->x2 && seg->dX > s->dX)
421 ))) {
422 // Insert before s
423 if (prev) {
424 seg->nextValid = s;
425 prev->nextValid = seg;
426 } else {
427 seg->nextValid = curSegs;
428 curSegs = seg;
429 }
430 break;
431 }
432 }
433 // Append at the end
434 if (s == 0) {
435 prev->nextValid = seg;
436 seg->nextValid = 0;
437 }
438 }
439
440 s = seg;
441 }
442
443 return curSegs;
444}
445
446#if 0
447static void
448printSeg(Segment *seg)
449{
450 /*
451 printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg,
452 seg->X>>SEGFRAC,
453 seg->right ? seg->right->type: -1,
454 seg->left ? seg->left->color.red : -1,
455 seg->left ? seg->left->color.green : -1,
456 seg->left ? seg->left->color.blue : -1,
457 seg->right ? seg->right->color.red : -1,
458 seg->right ? seg->right->color.green : -1,
459 seg->right ? seg->right->color.blue : -1,
460 seg->x1, seg->x2, seg->ymin, seg->ymax);
461 */
462}
463#endif
464
465inline void
466GraphicDevice::renderScanLine(long y, Segment *curSegs)
467{
468 Segment *seg;
469 long width;
470 int fi = 1;
471 FillStyleDef *f;
472
473 width = targetWidth * FRAC;
474
475 if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) {
476 fi = 0;
477 }
478 for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid)
479 {
480 if (seg->nextValid->X <0) continue;
481 if ((seg->X>>SEGFRAC) > width) break;
482 f = seg->fs[fi];
483 if (f) {
484 switch (f->type) {
485 case f_Solid:
486 if (seg->aa) {
487 fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
488 } else {
489 fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
490 }
491 break;
492 case f_TiledBitmap:
493 case f_clippedBitmap:
494 fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
495 break;
496 case f_LinearGradient:
497 fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
498 break;
499 case f_RadialGradient:
500 fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
501 break;
502 case f_None:
503 break;
504 }
505 }
506 }
507}
508
509/* draw the current path */
510void
511GraphicDevice::drawPolygon(void)
512{
513 long y;
514 Segment *curSegs,*seg;
515
516 // no segments ?
517 if (this->ymax == -1)
518 return;
519
520 // Foreach scanline
521 curSegs = 0;
522 for(y=this->ymin; y <= this->ymax; y++) {
523
524 // Make X values progess and remove unuseful segments
525 curSegs = progressSegments(curSegs, y);
526
527 // Add the new segment starting at the y position.
528 curSegs = newSegments(curSegs, this->segs[y]);
529
530 // Render the scanline
531 if (this->scan_line_func == NULL) {
532 renderScanLine(y, curSegs);
533 } else {
534 for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) {
535 if (seg->nextValid->X >= seg->X) {
536 scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
537 }
538 }
539 }
540 }
541
542 /* free the segments */
543 memset(this->segs + this->ymin, 0,
544 (this->ymax - this->ymin + 1) * sizeof(Segment *));
545
546 this->ymax = -1;
547 this->ymin = this->height;
548
549 this->seg_pool_cur = this->seg_pool;
550}
551
552void
553GraphicDevice::updateClippingRegion(Rect *rect)
554{
555 if (!clipping) return;
556
557 transformBoundingBox(&clip_rect, adjust, rect, 1);
558 clip_rect.xmin >>= FRAC_BITS;
559 clip_rect.xmax >>= FRAC_BITS;
560 clip_rect.ymin >>= FRAC_BITS;
561 clip_rect.ymax >>= FRAC_BITS;
562
563 clip_rect.xmin-=2;
564 clip_rect.ymin-=2;
565 clip_rect.xmax+=2;
566 clip_rect.ymax+=2;
567
568 if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin;
569 if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin;
570 if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin;
571 if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;
572
573 if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;
574 if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;
575 if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;
576 if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;
577}
578
579void
580GraphicDevice::setClipping(int value)
581{
582 clipping = value;
583 if (clipping == 0) {
584 // Reset region
585 clip_rect.xmin = viewPort.xmin;
586 clip_rect.xmax = viewPort.xmax;
587 clip_rect.ymin = viewPort.ymin;
588 clip_rect.ymax = viewPort.ymax;
589 }
590}
591
592// Virtual
593void
594GraphicDevice::clearCanvas()
595{
596}
597
598long
599GraphicDevice::allocColor(Color color)
600{
601 return 0;
602}
603
604void
605GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
606{
607}
608
609void
610GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end)
611{
612}
613
614void
615GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end)
616{
617}
618
619void
620GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end)
621{
622}
623
624void
625GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end)
626{
627}
628
629void
630GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width)
631{
632}