00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef RENDER_HANDLER_H
00023 #define RENDER_HANDLER_H
00024
00099
00100
00145
00146
00147 #include <vector>
00148 #include <boost/noncopyable.hpp>
00149
00150 #include "dsodefs.h"
00151
00152 #include "FileTypes.h"
00153 #include "gnash.h"
00154 #include "Range2d.h"
00155 #include "Point2d.h"
00156 #include "RGBA.h"
00157 #include "log.h"
00158 #include "snappingrange.h"
00159 #include "SWFRect.h"
00160
00161
00162 namespace gnash {
00163 class CachedBitmap;
00164 class rgba;
00165 class Transform;
00166 class SWFMatrix;
00167 class FillStyle;
00168 class LineStyle;
00169 class Shape;
00170 class MorphShape;
00171
00172
00173 class GnashVaapiImageProxy;
00174
00175 namespace SWF {
00176 class ShapeRecord;
00177 }
00178 namespace image {
00179 class GnashImage;
00180 }
00181 }
00182
00183 namespace gnash {
00184
00186
00191 class DSOEXPORT Renderer : boost::noncopyable
00192 {
00193 public:
00194
00195 Renderer()
00196 :
00197 _quality(QUALITY_HIGH)
00198 {}
00199
00200 virtual ~Renderer() {}
00201
00203 virtual std::string description() const = 0;
00204
00208
00210 virtual void set_scale(float , float ) {}
00211
00215 virtual void set_translation(float , float ) {}
00216
00217 void setQuality(Quality q) { _quality = q; }
00218
00222
00227 virtual CachedBitmap* createCachedBitmap(
00228 std::auto_ptr<image::GnashImage> im) = 0;
00229
00230
00234
00236
00256 virtual void drawVideoFrame(image::GnashImage* frame,
00257 const Transform& xform, const SWFRect* bounds, bool smooth) = 0;
00258
00260
00271 virtual void drawLine(const std::vector<point>& coords,
00272 const rgba& color, const SWFMatrix& mat) = 0;
00273
00275
00288 virtual void draw_poly(const point* corners, size_t corner_count,
00289 const rgba& fill, const rgba& outline, const SWFMatrix& mat,
00290 bool masked) = 0;
00291
00292 virtual void drawShape(const SWF::ShapeRecord& shape,
00293 const Transform& xform) = 0;
00294
00297
00309 virtual void drawGlyph(const SWF::ShapeRecord& rec, const rgba& color,
00310 const SWFMatrix& mat) = 0;
00311
00313
00317
00322 virtual void renderToImage(boost::shared_ptr<IOChannel> ,
00323 FileType ) const {
00324
00325 log_debug(_("Rendering to image not implemented for this "
00326 "renderer"));
00327 }
00328
00329
00333
00335
00346 virtual void set_invalidated_regions(const InvalidatedRanges& )
00347 {
00348 }
00349
00353
00355 typedef boost::shared_ptr<GnashVaapiImageProxy> RenderImage;
00356 typedef std::vector<RenderImage> RenderImages;
00357
00358
00359 virtual RenderImages::iterator getFirstRenderImage()
00360 { return _render_images.begin(); }
00361 virtual RenderImages::const_iterator getFirstRenderImage() const
00362 { return _render_images.begin(); }
00363
00364
00365 virtual RenderImages::iterator getLastRenderImage()
00366 { return _render_images.end(); }
00367 virtual RenderImages::const_iterator getLastRenderImage() const
00368 { return _render_images.end(); }
00369
00371
00385 virtual void begin_submit_mask() = 0;
00386 virtual void end_submit_mask() = 0;
00387 virtual void disable_mask() = 0;
00389
00393
00395 virtual geometry::Range2d<int> world_to_pixel(const SWFRect& worldbounds) = 0;
00396
00398 virtual point pixel_to_world(int x, int y) = 0;
00399
00400 virtual geometry::Range2d<int> pixel_to_world(
00401 const geometry::Range2d<int>& pixelbounds)
00402 {
00403 point topleft = pixel_to_world(
00404 pixelbounds.getMinX(), pixelbounds.getMinY());
00405 point bottomright = pixel_to_world(
00406 pixelbounds.getMaxX(), pixelbounds.getMaxY());
00407
00408 return geometry::Range2d<int> (topleft.x, topleft.y,
00409 bottomright.x, bottomright.y);
00410 }
00411
00412 virtual geometry::Range2d<int> world_to_pixel(
00413 const geometry::Range2d<int>& worldbounds)
00414 {
00415 if ((worldbounds.isNull() || worldbounds.isWorld())) return worldbounds;
00416
00417
00418
00419
00420
00421 return world_to_pixel(SWFRect(static_cast<int>(worldbounds.getMinX()),
00422 static_cast<int>(worldbounds.getMinY()),
00423 static_cast<int>(worldbounds.getMaxX()),
00424 static_cast<int>(worldbounds.getMaxY())));
00425 }
00426
00430
00444 virtual bool bounds_in_clipping_area(const SWFRect& bounds) {
00445 return bounds_in_clipping_area(bounds.getRange());
00446 }
00447
00448 virtual bool bounds_in_clipping_area(const InvalidatedRanges& ranges)
00449 {
00450 for (unsigned int rno=0; rno<ranges.size(); rno++)
00451 {
00452 if (bounds_in_clipping_area(ranges.getRange(rno)))
00453 return true;
00454 }
00455
00456 return false;
00457 }
00458
00459 virtual bool bounds_in_clipping_area(
00460 const geometry::Range2d<int>& )
00461 {
00462 return true;
00463 }
00464
00465 #ifdef USE_TESTSUITE
00466
00470
00471
00478 virtual bool getPixel(rgba& , int , int ) const {
00479
00480 log_debug("getPixel() not implemented for this renderer");
00481 abort();
00482 return false;
00483 }
00484
00485
00496 virtual bool getAveragePixel(rgba& color_return, int x, int y,
00497 unsigned int radius) const
00498 {
00499
00500 assert(radius>0);
00501
00502
00503 if (radius==1) return getPixel(color_return, x, y);
00504
00505 unsigned int r=0, g=0, b=0, a=0;
00506
00507 x -= radius/2;
00508 y -= radius/2;
00509
00510 int xe = x+radius;
00511 int ye = y+radius;
00512
00513 rgba pixel;
00514
00515 for (int yp=y; yp<ye; yp++)
00516 for (int xp=x; xp<xe; xp++)
00517 {
00518 if (!getPixel(pixel, xp, yp))
00519 return false;
00520
00521 r += pixel.m_r;
00522 g += pixel.m_g;
00523 b += pixel.m_b;
00524 a += pixel.m_a;
00525 }
00526
00527 int pcount = radius*radius;
00528 color_return.m_r = r / pcount;
00529 color_return.m_g = g / pcount;
00530 color_return.m_b = b / pcount;
00531 color_return.m_a = a / pcount;
00532
00533 return true;
00534 }
00535
00536
00557 virtual bool initTestBuffer(unsigned , unsigned ) {
00558 return false;
00559 }
00560
00562
00568 virtual unsigned int getBitsPerPixel() const {
00569 return 0;
00570 }
00571
00572 #endif
00573
00574 class External
00575 {
00576 public:
00578
00581 External(Renderer& r, const rgba& c, int w = 0, int h = 0,
00582 float x0 = 0, float x1 = 0, float y0 = 0, float y1 = 0)
00583 :
00584 _r(r)
00585 {
00586 _r.begin_display(c, w, h, x0, x1, y0, y1);
00587 }
00588
00589 ~External() {
00590 _r.end_display();
00591 }
00592
00593 private:
00594 Renderer& _r;
00595 };
00596
00597 class Internal
00598 {
00599 public:
00600
00602 Internal(Renderer& r, image::GnashImage& im)
00603 :
00604 _r(r),
00605 _ext(_r.startInternalRender(im))
00606 {
00607 }
00608
00609 Renderer* renderer() const {
00610 return _ext;
00611 }
00612
00613 ~Internal() {
00614 _r.endInternalRender();
00615 }
00616
00617 private:
00618 Renderer& _r;
00619 Renderer* _ext;
00620 };
00621
00622 protected:
00623
00625 Quality _quality;
00626
00627
00628 RenderImages _render_images;
00629
00630 private:
00631
00633
00638
00641 virtual void begin_display(const rgba& background_color,
00642 int viewport_width, int viewport_height,
00643 float x0, float x1, float y0, float y1) = 0;
00644
00645 virtual void end_display() = 0;
00646
00648
00650
00652 virtual Renderer* startInternalRender(image::GnashImage& buffer) = 0;
00653
00655
00658 virtual void endInternalRender() = 0;
00659
00660 };
00661
00662 }
00663
00664 #endif
00665
00666
00667
00668
00669
00670