00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BACKEND_RENDER_HANDLER_AGG_STYLE_H
00020 #define BACKEND_RENDER_HANDLER_AGG_STYLE_H
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "GnashAlgorithm.h"
00035 #include "FillStyle.h"
00036
00037 namespace gnash {
00038
00039 class StyleHandler;
00040
00041
00042 namespace {
00043
00045 template<typename FillMode, typename Pixel>
00046 void storeBitmap(StyleHandler& st, const agg_bitmap_info* bi,
00047 const SWFMatrix& mat, const SWFCxForm& cx,
00048 bool smooth);
00049 template<typename FillMode> void storeBitmap(StyleHandler& st,
00050 const agg_bitmap_info* bi, const SWFMatrix& mat, const SWFCxForm& cx,
00051 bool smooth);
00052
00054 void storeGradient(StyleHandler& st, const GradientFill& fs,
00055 const SWFMatrix& mat, const SWFCxForm& cx);
00056 template<typename Spread> void storeGradient(StyleHandler& st,
00057 const GradientFill& fs, const SWFMatrix& mat, const SWFCxForm& cx);
00058 template<typename Spread, typename Interpolation>
00059 void storeGradient(StyleHandler& st, const GradientFill& fs,
00060 const SWFMatrix& mat, const SWFCxForm& cx);
00061 }
00062
00067 class AggStyle
00068 {
00069 public:
00070 AggStyle(bool solid, const agg::rgba8& color = agg::rgba8(0,0,0,0))
00071 :
00072 _solid(solid),
00073 _color(color)
00074 {
00075 }
00076
00077
00078
00079
00080
00081 virtual ~AggStyle() {}
00082 bool solid() const { return _solid; }
00083 agg::rgba8 color() const { return _color; }
00084
00085
00086 virtual void generate_span(agg::rgba8* span, int x, int y,
00087 unsigned len) = 0;
00088
00089 private:
00090
00091 const bool _solid;
00092 const agg::rgba8 _color;
00093 };
00094
00095 namespace {
00096
00098 struct Tile
00099 {
00100 template<typename P> struct Type {
00101 typedef agg::wrap_mode_repeat Wrap;
00102 typedef agg::image_accessor_wrap<P, Wrap, Wrap> type;
00103 };
00104 };
00105
00107 struct Clip
00108 {
00109 template<typename P> struct Type {
00110 typedef agg::image_accessor_clone<P> type;
00111 };
00112 };
00113
00115 template<typename P, typename W>
00116 struct FilterType
00117 {
00118 typedef typename P::PixelFormat PixelFormat;
00119 typedef typename W::template Type<PixelFormat>::type SourceType;
00120 typedef agg::span_allocator<PixelFormat> Allocator;
00121 typedef agg::span_interpolator_linear<agg::trans_affine>
00122 Interpolator;
00123 };
00124
00126 struct RGBA
00127 {
00128 typedef agg::pixfmt_rgba32_pre PixelFormat;
00129
00130 template<typename SourceType, typename Interpolator>
00131 struct Simple {
00132 typedef agg::span_image_filter_rgba_nn<SourceType, Interpolator> type;
00133 };
00134
00135 template<typename SourceType, typename Interpolator>
00136 struct AntiAlias {
00137 typedef agg::span_image_filter_rgba_bilinear<SourceType, Interpolator>
00138 type;
00139 };
00140 };
00141
00143 struct RGB
00144 {
00145 typedef agg::pixfmt_rgb24_pre PixelFormat;
00146
00147 template<typename SourceType, typename Interpolator>
00148 struct Simple {
00149 typedef agg::span_image_filter_rgb_nn<SourceType, Interpolator> type;
00150 };
00151
00152 template<typename SourceType, typename Interpolator>
00153 struct AntiAlias {
00154 typedef agg::span_image_filter_rgb_bilinear<SourceType, Interpolator>
00155 type;
00156 };
00157 };
00158
00160 template<typename P, typename W>
00161 struct NN : public FilterType<P, W>
00162 {
00163 typedef FilterType<P, W> BaseType;
00164 typedef typename P::template Simple<
00165 typename BaseType::SourceType,
00166 typename BaseType::Interpolator>::type Generator;
00167 };
00168
00170 template<typename P, typename W>
00171 struct AA : public FilterType<P, W>
00172 {
00173 typedef FilterType<P, W> BaseType;
00174 typedef typename P::template AntiAlias<
00175 typename BaseType::SourceType,
00176 typename BaseType::Interpolator>::type Generator;
00177 };
00178
00180 struct Reflect
00181 {
00182 template<typename T> struct Type {
00183 typedef agg::gradient_reflect_adaptor<T> type;
00184 };
00185 };
00186
00188 struct Repeat
00189 {
00190 template<typename T> struct Type {
00191 typedef agg::gradient_repeat_adaptor<T> type;
00192 };
00193 };
00194
00196 struct Pad
00197 {
00198 template<typename T> struct Type {
00199 typedef T type;
00200 };
00201 };
00202
00204 struct InterpolatorRGB
00205 {
00206 template<typename Pixel> struct Type {
00207 typedef agg::gradient_lut<agg::color_interpolator<Pixel>, 256> type;
00208 };
00209 };
00210
00216 template <class Color, class Allocator, class Interpolator, class GradientType,
00217 class Adaptor, class ColorInterpolator, class SpanGenerator>
00218 class GradientStyle : public AggStyle
00219 {
00220 public:
00221
00222 GradientStyle(const GradientFill& fs, const SWFMatrix& mat,
00223 const SWFCxForm& cx, int norm_size, GradientType gr = GradientType())
00224 :
00225 AggStyle(false),
00226 m_cx(cx),
00227 m_tr(mat.sx / 65536.0, mat.shx/65536.0, mat.shy / 65536.0,
00228 mat.sy / 65536.0, mat.tx, mat.ty),
00229 m_span_interpolator(m_tr),
00230 m_gradient_adaptor(gr),
00231 m_sg(m_span_interpolator, m_gradient_adaptor, m_gradient_lut, 0,
00232 norm_size),
00233
00234 m_need_premultiply(false)
00235 {
00236
00237 m_gradient_lut.remove_all();
00238 const size_t size = fs.recordCount();
00239
00240
00241
00242 assert(size > 1);
00243
00244 for (size_t i = 0; i != size; ++i) {
00245 const GradientRecord& gr = fs.record(i);
00246 const rgba tr = m_cx.transform(gr.color);
00247 if (tr.m_a < 255) m_need_premultiply = true;
00248 m_gradient_lut.add_color(gr.ratio/255.0,
00249 agg::rgba8(tr.m_r, tr.m_g, tr.m_b, tr.m_a));
00250 }
00251 m_gradient_lut.build_lut();
00252
00253 }
00254
00255 virtual ~GradientStyle() { }
00256
00257 void generate_span(Color* span, int x, int y, unsigned len) {
00258 m_sg.generate(span, x, y, len);
00259 if (!m_need_premultiply) return;
00260
00261 while (len--) {
00262 span->premultiply();
00263 ++span;
00264 }
00265 }
00266
00267 protected:
00268
00269
00270 SWFCxForm m_cx;
00271
00272
00273 Allocator m_sa;
00274
00275
00276 agg::trans_affine m_tr;
00277
00278
00279 Interpolator m_span_interpolator;
00280
00281
00282 Adaptor m_gradient_adaptor;
00283
00284
00285 ColorInterpolator m_gradient_lut;
00286
00287
00288 SpanGenerator m_sg;
00289
00290
00291 bool m_need_premultiply;
00292 };
00293
00295
00299 template<typename G, typename A, typename I>
00300 struct Gradient
00301 {
00302 typedef agg::rgba8 Color;
00303 typedef G GradientType;
00304 typedef typename A::template Type<G>::type Adaptor;
00305 typedef typename I::template Type<Color>::type ColorInterpolator;
00306 typedef agg::span_allocator<Color> Allocator;
00307 typedef agg::span_interpolator_linear<agg::trans_affine> Interpolator;
00308 typedef agg::span_gradient<Color, Interpolator, Adaptor,
00309 ColorInterpolator> Generator;
00310 typedef GradientStyle<Color, Allocator, Interpolator, GradientType,
00311 Adaptor, ColorInterpolator, Generator> Type;
00312 };
00313
00314
00317 class SolidStyle : public AggStyle
00318 {
00319 public:
00320
00321 SolidStyle(const agg::rgba8& color)
00322 :
00323 AggStyle(true, color)
00324 {
00325 }
00326
00327 void generate_span(agg::rgba8* , int , int ,
00328 unsigned )
00329 {
00330 abort();
00331 }
00332 };
00333
00334
00339 template <class PixelFormat, class Allocator, class SourceType,
00340 class Interpolator, class Generator>
00341 class BitmapStyle : public AggStyle
00342 {
00343 public:
00344
00345 BitmapStyle(int width, int height, int rowlen, boost::uint8_t* data,
00346 const SWFMatrix& mat, const SWFCxForm& cx)
00347 :
00348 AggStyle(false),
00349 m_cx(cx),
00350 m_rbuf(data, width, height, rowlen),
00351 m_pixf(m_rbuf),
00352 m_img_src(m_pixf),
00353 m_tr(mat.sx / 65535.0, mat.shx / 65535.0, mat.shy / 65535.0,
00354 mat.sy / 65535.0, mat.tx, mat.ty),
00355 m_interpolator(m_tr),
00356 m_sg(m_img_src, m_interpolator)
00357 {
00358
00359
00360
00361
00362
00363 }
00364
00365 virtual ~BitmapStyle() {
00366 }
00367
00368 void generate_span(agg::rgba8* span, int x, int y, unsigned len)
00369 {
00370 m_sg.generate(span, x, y, len);
00371
00372 const bool transform = (m_cx != SWFCxForm());
00373
00374 for (size_t i = 0; i < len; ++i) {
00375
00376
00377 span->r = std::min(span->r, span->a);
00378 span->g = std::min(span->g, span->a);
00379 span->b = std::min(span->b, span->a);
00380 if (transform) {
00381 m_cx.transform(span->r, span->g, span->b, span->a);
00382 span->premultiply();
00383 }
00384 ++span;
00385 }
00386 }
00387
00388 private:
00389
00390
00391 SWFCxForm m_cx;
00392
00393
00394 agg::rendering_buffer m_rbuf;
00395 PixelFormat m_pixf;
00396
00397
00398 Allocator m_sa;
00399
00400
00401 SourceType m_img_src;
00402
00403
00404 agg::trans_affine m_tr;
00405
00406
00407 Interpolator m_interpolator;
00408
00409
00410 Generator m_sg;
00411 };
00412
00413 }
00414
00415
00416
00417
00421 class StyleHandler
00422 {
00423 public:
00424
00425 StyleHandler() :
00426 m_transparent(0, 0, 0, 0)
00427 {}
00428
00429 ~StyleHandler() {
00430 deleteChecked(_styles.begin(), _styles.end());
00431 }
00432
00434 bool is_solid(unsigned style) const {
00435 assert(style < _styles.size());
00436 return _styles[style]->solid();
00437 }
00438
00440 void add_color(const agg::rgba8& color) {
00441 SolidStyle *st = new SolidStyle(color);
00442 _styles.push_back(st);
00443 }
00444
00446 void add_bitmap(const agg_bitmap_info* bi, const SWFMatrix& mat,
00447 const SWFCxForm& cx, bool repeat, bool smooth) {
00448
00449 if (!bi) {
00450 add_color(agg::rgba8_pre(0,0,0,0));
00451 return;
00452 }
00453
00454
00455 if (repeat) {
00456 storeBitmap<Tile>(*this, bi, mat, cx, smooth);
00457 return;
00458 }
00459
00460 storeBitmap<Clip>(*this, bi, mat, cx, smooth);
00461 }
00462
00463 template<typename T>
00464 void addLinearGradient(const GradientFill& fs, const SWFMatrix& mat,
00465 const SWFCxForm& cx)
00466 {
00467
00468
00469 typename T::Type* st = new typename T::Type(fs, mat, cx, 256);
00470 _styles.push_back(st);
00471 }
00472
00473 template<typename T>
00474 void addFocalGradient(const GradientFill& fs, const SWFMatrix& mat,
00475 const SWFCxForm& cx)
00476 {
00477
00478 SWFMatrix transl;
00479 transl.set_translation(-32, -32);
00480 transl.concatenate(mat);
00481
00482 typename T::GradientType gr;
00483 gr.init(32.0, fs.focalPoint() * 32.0, 0.0);
00484
00485
00486 typename T::Type* st = new typename T::Type(fs, transl, cx, 64/2, gr);
00487
00488
00489
00490 _styles.push_back(st);
00491 }
00492
00493 template<typename T>
00494 void addRadialGradient(const GradientFill& fs, const SWFMatrix& mat,
00495 const SWFCxForm& cx)
00496 {
00497
00498 SWFMatrix transl;
00499 transl.set_translation(-32, -32);
00500 transl.concatenate(mat);
00501
00502
00503 typename T::Type* st = new typename T::Type(fs, transl, cx, 64 / 2);
00504
00505
00506
00507 _styles.push_back(st);
00508 }
00509
00511 agg::rgba8 color(unsigned style) const
00512 {
00513 if (style < _styles.size())
00514 return _styles[style]->color();
00515
00516 return m_transparent;
00517 }
00518
00520 void generate_span(agg::rgba8* span, int x, int y,
00521 unsigned len, unsigned style)
00522 {
00523 _styles[style]->generate_span(span,x,y,len);
00524 }
00525
00526
00528
00531 template<typename Filter> void
00532 addBitmap(const agg_bitmap_info* bi, const SWFMatrix& mat,
00533 const SWFCxForm& cx)
00534 {
00535 typedef typename Filter::PixelFormat PixelFormat;
00536 typedef typename Filter::Generator Generator;
00537 typedef typename Filter::Allocator Allocator;
00538 typedef typename Filter::SourceType SourceType;
00539 typedef typename Filter::Interpolator Interpolator;
00540
00541 typedef BitmapStyle<PixelFormat, Allocator,
00542 SourceType, Interpolator, Generator> Style;
00543
00544 Style* st = new Style(bi->get_width(), bi->get_height(),
00545 bi->get_rowlen(), bi->get_data(), mat, cx);
00546
00547 _styles.push_back(st);
00548 }
00549
00550 std::vector<AggStyle*> _styles;
00551 agg::rgba8 m_transparent;
00552
00553 };
00554
00555 class agg_mask_style_handler
00556 {
00557 public:
00558
00559 agg_mask_style_handler() :
00560 m_color(255,255)
00561 {
00562 }
00563
00564 bool is_solid(unsigned ) const
00565 {
00566 return true;
00567 }
00568
00569 const agg::gray8& color(unsigned ) const
00570 {
00571 return m_color;
00572 }
00573
00574 void generate_span(agg::gray8* , int , int ,
00575 int , unsigned )
00576 {
00577 abort();
00578 }
00579
00580 private:
00581 agg::gray8 m_color;
00582
00583 };
00584
00586
00588 struct AddStyles : boost::static_visitor<>
00589 {
00590 AddStyles(SWFMatrix stage, SWFMatrix fill, const SWFCxForm& c,
00591 StyleHandler& sh, Quality q)
00592 :
00593 _stageMatrix(stage.invert()),
00594 _fillMatrix(fill.invert()),
00595 _cx(c),
00596 _sh(sh),
00597 _quality(q)
00598 {}
00599
00600 void operator()(const GradientFill& f) const {
00601 SWFMatrix m = f.matrix();
00602 m.concatenate(_fillMatrix);
00603 m.concatenate(_stageMatrix);
00604 storeGradient(_sh, f, m, _cx);
00605 }
00606
00607 void operator()(const SolidFill& f) const {
00608 const rgba color = _cx.transform(f.color());
00609
00610
00611
00612 _sh.add_color(agg::rgba8_pre(color.m_r, color.m_g, color.m_b,
00613 color.m_a));
00614 }
00615
00616 void operator()(const BitmapFill& f) const {
00617 SWFMatrix m = f.matrix();
00618 m.concatenate(_fillMatrix);
00619 m.concatenate(_stageMatrix);
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 bool smooth = false;
00631 if (_quality > QUALITY_LOW) {
00632
00633 switch (f.smoothingPolicy()) {
00634 case BitmapFill::SMOOTHING_UNSPECIFIED:
00635 if (_quality >= QUALITY_BEST) smooth = true;
00636 break;
00637 case BitmapFill::SMOOTHING_ON:
00638 smooth = true;
00639 break;
00640 default: break;
00641 }
00642 }
00643
00644 const bool tiled = (f.type() == BitmapFill::TILED);
00645
00646 _sh.add_bitmap(dynamic_cast<const agg_bitmap_info*>(f.bitmap()),
00647 m, _cx, tiled, smooth);
00648 }
00649
00650 private:
00651
00653 const SWFMatrix _stageMatrix;
00654
00656 const SWFMatrix _fillMatrix;
00657 const SWFCxForm& _cx;
00658 StyleHandler& _sh;
00659 const Quality _quality;
00660 };
00661
00662 namespace {
00663
00664 template<typename FillMode, typename Pixel>
00665 void
00666 storeBitmap(StyleHandler& st, const agg_bitmap_info* bi,
00667 const SWFMatrix& mat, const SWFCxForm& cx, bool smooth)
00668 {
00669 if (smooth) {
00670 st.addBitmap<AA<Pixel, FillMode> >(bi, mat, cx);
00671 return;
00672 }
00673 st.addBitmap<NN<Pixel, FillMode> >(bi, mat, cx);
00674 }
00675
00676 template<typename FillMode>
00677 void
00678 storeBitmap(StyleHandler& st, const agg_bitmap_info* bi,
00679 const SWFMatrix& mat, const SWFCxForm& cx, bool smooth)
00680 {
00681
00682 if (bi->get_bpp() == 24) {
00683 storeBitmap<FillMode, RGB>(st, bi, mat, cx, smooth);
00684 return;
00685 }
00686 storeBitmap<FillMode, RGBA>(st, bi, mat, cx, smooth);
00687 }
00688
00689 template<typename Spread, typename Interpolation>
00690 void
00691 storeGradient(StyleHandler& st, const GradientFill& fs, const SWFMatrix& mat,
00692 const SWFCxForm& cx)
00693 {
00694
00695 typedef agg::gradient_x Linear;
00696 typedef agg::gradient_radial Radial;
00697 typedef agg::gradient_radial_focus Focal;
00698
00699 typedef Gradient<Linear, Spread, Interpolation> LinearGradient;
00700 typedef Gradient<Focal, Spread, Interpolation> FocalGradient;
00701 typedef Gradient<Radial, Spread, Interpolation> RadialGradient;
00702
00703 switch (fs.type()) {
00704 case GradientFill::LINEAR:
00705 st.addLinearGradient<LinearGradient>(fs, mat, cx);
00706 return;
00707
00708 case GradientFill::RADIAL:
00709 if (fs.focalPoint()) {
00710 st.addFocalGradient<FocalGradient>(fs, mat, cx);
00711 return;
00712 }
00713 st.addRadialGradient<RadialGradient>(fs, mat, cx);
00714 }
00715 }
00716
00717 template<typename Spread>
00718 void
00719 storeGradient(StyleHandler& st, const GradientFill& fs, const SWFMatrix& mat,
00720 const SWFCxForm& cx)
00721 {
00722
00723 switch (fs.interpolation) {
00724 default:
00725 storeGradient<Spread, InterpolatorRGB>(st, fs, mat, cx);
00726 break;
00727 }
00728
00729 }
00730
00731 void
00732 storeGradient(StyleHandler& st, const GradientFill& fs, const SWFMatrix& mat,
00733 const SWFCxForm& cx)
00734 {
00735
00736 switch (fs.spreadMode) {
00737 case GradientFill::PAD:
00738 storeGradient<Pad>(st, fs, mat, cx);
00739 break;
00740 case GradientFill::REFLECT:
00741 storeGradient<Reflect>(st, fs, mat, cx);
00742 break;
00743 case GradientFill::REPEAT:
00744 storeGradient<Repeat>(st, fs, mat, cx);
00745 break;
00746 }
00747 }
00748
00749 }
00750
00751 }
00752
00753 #endif // BACKEND_RENDER_HANDLER_AGG_STYLE_H