00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef AGG_PIXFMT_RGBA32_INCLUDED
00017 #define AGG_PIXFMT_RGBA32_INCLUDED
00018
00019 #include <string.h>
00020 #include "agg_basics.h"
00021 #include "agg_color_rgba8.h"
00022 #include "agg_rendering_buffer.h"
00023
00024 namespace agg
00025 {
00026
00027
00028 template<class Order> class pixel_formats_rgba32
00029 {
00030 public:
00031 typedef rgba8 color_type;
00032 typedef Order order_type;
00033 typedef rendering_buffer::row_data row_data;
00034
00035
00036 pixel_formats_rgba32(rendering_buffer& rb)
00037 : m_rbuf(&rb)
00038 {
00039 }
00040
00041
00042 unsigned width() const { return m_rbuf->width(); }
00043 unsigned height() const { return m_rbuf->height(); }
00044
00045
00046 color_type pixel(int x, int y) const
00047 {
00048 int8u* p = m_rbuf->row(y) + (x << 2);
00049 return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
00050 }
00051
00052
00053 row_data span(int x, int y) const
00054 {
00055 return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
00056 }
00057
00058
00059 void copy_pixel(int x, int y, const color_type& c)
00060 {
00061 int8u* p = m_rbuf->row(y) + (x << 2);
00062 p[Order::R] = (int8u)c.r;
00063 p[Order::G] = (int8u)c.g;
00064 p[Order::B] = (int8u)c.b;
00065 p[Order::A] = (int8u)c.a;
00066 }
00067
00068
00069 void blend_pixel(int x, int y, const color_type& c, int8u cover)
00070 {
00071 int8u* p = m_rbuf->row(y) + (x << 2);
00072 int alpha = int(cover) * int(c.a);
00073 if(alpha == 255*255)
00074 {
00075 p[Order::R] = (int8u)c.r;
00076 p[Order::G] = (int8u)c.g;
00077 p[Order::B] = (int8u)c.b;
00078 p[Order::A] = (int8u)c.a;
00079 }
00080 else
00081 {
00082 int r = p[Order::R];
00083 int g = p[Order::G];
00084 int b = p[Order::B];
00085 int a = p[Order::A];
00086 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00087 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00088 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00089 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00090 }
00091 }
00092
00093
00094 void copy_hline(int x, int y, unsigned len, const color_type& c)
00095 {
00096 int32u v;
00097 int8u* p8 = (int8u*)&v;
00098 p8[Order::R] = (int8u)c.r;
00099 p8[Order::G] = (int8u)c.g;
00100 p8[Order::B] = (int8u)c.b;
00101 p8[Order::A] = (int8u)c.a;
00102 int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
00103 do
00104 {
00105 *p32++ = v;
00106 }
00107 while(--len);
00108 }
00109
00110
00111 void copy_vline(int x, int y, unsigned len, const color_type& c)
00112 {
00113 int32u v;
00114 int8u* p8 = (int8u*)&v;
00115 p8[Order::R] = (int8u)c.r;
00116 p8[Order::G] = (int8u)c.g;
00117 p8[Order::B] = (int8u)c.b;
00118 p8[Order::A] = (int8u)c.a;
00119 int8u* p = m_rbuf->row(y) + (x << 2);
00120 do
00121 {
00122 *(int32u*)p = v;
00123 p += m_rbuf->stride();
00124 }
00125 while(--len);
00126 }
00127
00128
00129 void blend_hline(int x, int y, unsigned len,
00130 const color_type& c, int8u cover)
00131 {
00132 int alpha = int(cover) * int(c.a);
00133 if(alpha == 255*255)
00134 {
00135 int32u v;
00136 int8u* p8 = (int8u*)&v;
00137 p8[Order::R] = (int8u)c.r;
00138 p8[Order::G] = (int8u)c.g;
00139 p8[Order::B] = (int8u)c.b;
00140 p8[Order::A] = (int8u)c.a;
00141 int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
00142 do
00143 {
00144 *p32++ = v;
00145 }
00146 while(--len);
00147 }
00148 else
00149 {
00150 int8u* p = m_rbuf->row(y) + (x << 2);
00151 do
00152 {
00153 int r = p[Order::R];
00154 int g = p[Order::G];
00155 int b = p[Order::B];
00156 int a = p[Order::A];
00157 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00158 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00159 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00160 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00161 p += 4;
00162 }
00163 while(--len);
00164 }
00165 }
00166
00167
00168 void blend_vline(int x, int y, unsigned len,
00169 const color_type& c, int8u cover)
00170 {
00171 int8u* p = m_rbuf->row(y) + (x << 2);
00172 int alpha = int(cover) * c.a;
00173 if(alpha == 255*255)
00174 {
00175 int32u v;
00176 int8u* p8 = (int8u*)&v;
00177 p8[Order::R] = (int8u)c.r;
00178 p8[Order::G] = (int8u)c.g;
00179 p8[Order::B] = (int8u)c.b;
00180 p8[Order::A] = (int8u)c.a;
00181 do
00182 {
00183 *(int32u*)p = v;
00184 p += m_rbuf->stride();
00185 }
00186 while(--len);
00187 }
00188 else
00189 {
00190 do
00191 {
00192 int r = p[Order::R];
00193 int g = p[Order::G];
00194 int b = p[Order::B];
00195 int a = p[Order::A];
00196 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00197 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00198 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00199 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00200 p += m_rbuf->stride();
00201 }
00202 while(--len);
00203 }
00204 }
00205
00206
00207
00208 void copy_from(const rendering_buffer& from,
00209 int xdst, int ydst,
00210 int xsrc, int ysrc,
00211 unsigned len)
00212 {
00213 memmove(m_rbuf->row(ydst) + xdst * 4,
00214 (const void*)(from.row(ysrc) + xsrc * 4), len * 4);
00215 }
00216
00217
00218
00219
00220 template<class SrcPixelFormatRenderer>
00221 void blend_from(const SrcPixelFormatRenderer& from,
00222 const int8u* psrc,
00223 int xdst, int ydst,
00224 int xsrc, int ysrc,
00225 unsigned len)
00226 {
00227 typedef typename SrcPixelFormatRenderer::order_type src_order;
00228
00229 int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
00230 int incp = 4;
00231 if(xdst > xsrc)
00232 {
00233 psrc += (len-1) << 2;
00234 pdst += (len-1) << 2;
00235 incp = -4;
00236 }
00237 do
00238 {
00239 int alpha = psrc[src_order::A];
00240
00241 if(alpha)
00242 {
00243 if(alpha == 255)
00244 {
00245 pdst[Order::R] = psrc[src_order::R];
00246 pdst[Order::G] = psrc[src_order::G];
00247 pdst[Order::B] = psrc[src_order::B];
00248 pdst[Order::A] = psrc[src_order::A];
00249 }
00250 else
00251 {
00252 int r = pdst[Order::R];
00253 int g = pdst[Order::G];
00254 int b = pdst[Order::B];
00255 int a = pdst[Order::A];
00256 pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
00257 pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
00258 pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
00259 pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
00260 }
00261 }
00262 psrc += incp;
00263 pdst += incp;
00264 }
00265 while(--len);
00266 }
00267
00268
00269
00270
00271
00272 void blend_solid_hspan(int x, int y, unsigned len,
00273 const color_type& c, const int8u* covers)
00274 {
00275 int8u* p = m_rbuf->row(y) + (x << 2);
00276 do
00277 {
00278 int alpha = int(*covers++) * c.a;
00279
00280 if(alpha)
00281 {
00282 if(alpha == 255*255)
00283 {
00284 p[Order::R] = (int8u)c.r;
00285 p[Order::G] = (int8u)c.g;
00286 p[Order::B] = (int8u)c.b;
00287 p[Order::A] = (int8u)c.a;
00288 }
00289 else
00290 {
00291 int r = p[Order::R];
00292 int g = p[Order::G];
00293 int b = p[Order::B];
00294 int a = p[Order::A];
00295 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00296 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00297 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00298 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00299 }
00300 }
00301 p += 4;
00302 }
00303 while(--len);
00304 }
00305
00306
00307
00308
00309 void blend_solid_vspan(int x, int y, unsigned len,
00310 const color_type& c, const int8u* covers)
00311 {
00312 int8u* p = m_rbuf->row(y) + (x << 2);
00313 do
00314 {
00315 int alpha = int(*covers++) * c.a;
00316
00317 if(alpha)
00318 {
00319 if(alpha == 255*255)
00320 {
00321 p[Order::R] = (int8u)c.r;
00322 p[Order::G] = (int8u)c.g;
00323 p[Order::B] = (int8u)c.b;
00324 p[Order::A] = (int8u)c.a;
00325 }
00326 else
00327 {
00328 int r = p[Order::R];
00329 int g = p[Order::G];
00330 int b = p[Order::B];
00331 int a = p[Order::A];
00332 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00333 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00334 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00335 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00336 }
00337 }
00338 p += m_rbuf->stride();
00339 }
00340 while(--len);
00341 }
00342
00343
00344
00345 void blend_color_hspan(int x, int y, unsigned len,
00346 const color_type* colors,
00347 const int8u* covers,
00348 int8u cover)
00349 {
00350 int8u* p = m_rbuf->row(y) + (x << 2);
00351 do
00352 {
00353 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00354
00355 if(alpha)
00356 {
00357 if(alpha == 255*255)
00358 {
00359 p[Order::R] = (int8u)colors->r;
00360 p[Order::G] = (int8u)colors->g;
00361 p[Order::B] = (int8u)colors->b;
00362 p[Order::A] = (int8u)colors->a;
00363 }
00364 else
00365 {
00366 int r = p[Order::R];
00367 int g = p[Order::G];
00368 int b = p[Order::B];
00369 int a = p[Order::A];
00370 p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
00371 p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
00372 p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
00373 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00374 }
00375 }
00376 p += 4;
00377 ++colors;
00378 }
00379 while(--len);
00380 }
00381
00382
00383
00384 void blend_color_vspan(int x, int y, unsigned len,
00385 const color_type* colors,
00386 const int8u* covers,
00387 int8u cover)
00388 {
00389 int8u* p = m_rbuf->row(y) + (x << 2);
00390 do
00391 {
00392 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00393
00394 if(alpha)
00395 {
00396 if(alpha == 255*255)
00397 {
00398 p[Order::R] = (int8u)colors->r;
00399 p[Order::G] = (int8u)colors->g;
00400 p[Order::B] = (int8u)colors->b;
00401 p[Order::A] = (int8u)colors->a;
00402 }
00403 else
00404 {
00405 int r = p[Order::R];
00406 int g = p[Order::G];
00407 int b = p[Order::B];
00408 int a = p[Order::A];
00409 p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
00410 p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
00411 p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
00412 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00413 }
00414 }
00415 p += m_rbuf->stride();
00416 ++colors;
00417 }
00418 while(--len);
00419 }
00420
00421 private:
00422 rendering_buffer* m_rbuf;
00423 };
00424
00425 typedef pixel_formats_rgba32<order_rgba32> pixfmt_rgba32;
00426 typedef pixel_formats_rgba32<order_argb32> pixfmt_argb32;
00427 typedef pixel_formats_rgba32<order_abgr32> pixfmt_abgr32;
00428 typedef pixel_formats_rgba32<order_bgra32> pixfmt_bgra32;
00429 }
00430
00431 #endif
00432