00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef AGG_PIXFMT_RGB565_INCLUDED
00017 #define AGG_PIXFMT_RGB565_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 inline int16u rgb565(unsigned r, unsigned g, unsigned b)
00029 {
00030 return (int16u)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
00031 }
00032
00033
00034
00035 class pixfmt_rgb565
00036 {
00037 public:
00038 typedef rgba8 color_type;
00039 typedef bool order_type;
00040 typedef rendering_buffer::row_data row_data;
00041
00042
00043 pixfmt_rgb565(rendering_buffer& rb)
00044 : m_rbuf(&rb)
00045 {
00046 }
00047
00048
00049 unsigned width() const { return m_rbuf->width(); }
00050 unsigned height() const { return m_rbuf->height(); }
00051
00052
00053 color_type pixel(int x, int y) const
00054 {
00055 unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x];
00056 return color_type((rgb >> 8) & 0xF8,
00057 (rgb >> 3) & 0xFC,
00058 (rgb << 3) & 0xF8);
00059 }
00060
00061
00062 row_data span(int x, int y) const
00063 {
00064 return row_data(x, width() - 1, m_rbuf->row(y) + x * 2);
00065 }
00066
00067
00068 void copy_pixel(int x, int y, const color_type& c)
00069 {
00070 ((int16u*)(m_rbuf->row(y)))[x] = rgb565(c.r, c.g, c.b);
00071 }
00072
00073
00074 void blend_pixel(int x, int y, const color_type& c, int8u cover)
00075 {
00076 int alpha = int(cover) * c.a;
00077 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00078 if(alpha == 255*255)
00079 {
00080 *p = rgb565(c.r, c.g, c.b);
00081 }
00082 else
00083 {
00084 int16u rgb = *p;
00085 int r = (rgb >> 8) & 0xF8;
00086 int g = (rgb >> 3) & 0xFC;
00087 int b = (rgb << 3) & 0xF8;
00088 *p = (int16u)
00089 ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00090 (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00091 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00092 }
00093 }
00094
00095
00096 void copy_hline(int x, int y, unsigned len, const color_type& c)
00097 {
00098 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00099 int16u v = rgb565(c.r, c.g, c.b);
00100 do
00101 {
00102 *p++ = v;
00103 }
00104 while(--len);
00105 }
00106
00107
00108 void copy_vline(int x, int y, unsigned len, const color_type& c)
00109 {
00110 int8u* p = m_rbuf->row(y) + (x << 1);
00111 int16u v = rgb565(c.r, c.g, c.b);
00112 do
00113 {
00114 *(int16u*)p = v;
00115 p += m_rbuf->stride();
00116 }
00117 while(--len);
00118 }
00119
00120
00121 void blend_hline(int x, int y, unsigned len,
00122 const color_type& c, int8u cover)
00123 {
00124 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00125 int alpha = int(cover) * c.a;
00126 if(alpha == 255*255)
00127 {
00128 int16u v = rgb565(c.r, c.g, c.b);
00129 do
00130 {
00131 *p++ = v;
00132 }
00133 while(--len);
00134 }
00135 else
00136 {
00137 do
00138 {
00139 int16u rgb = *p;
00140 int r = (rgb >> 8) & 0xF8;
00141 int g = (rgb >> 3) & 0xFC;
00142 int b = (rgb << 3) & 0xF8;
00143 *p++ = (int16u)
00144 ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00145 (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00146 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00147
00148 }
00149 while(--len);
00150 }
00151 }
00152
00153
00154 void blend_vline(int x, int y, unsigned len,
00155 const color_type& c, int8u cover)
00156 {
00157 int8u* p = m_rbuf->row(y) + (x << 1);
00158 int alpha = int(cover) * c.a;
00159 if(alpha == 255*255)
00160 {
00161 int16u v = rgb565(c.r, c.g, c.b);
00162 do
00163 {
00164 *(int16u*)p = v;
00165 p += m_rbuf->stride();
00166 }
00167 while(--len);
00168 }
00169 else
00170 {
00171 do
00172 {
00173 int16u rgb = *(int16u*)p;
00174 int r = (rgb >> 8) & 0xF8;
00175 int g = (rgb >> 3) & 0xFC;
00176 int b = (rgb << 3) & 0xF8;
00177 *(int16u*)p = (int16u)
00178 ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00179 (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00180 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00181 p += m_rbuf->stride();
00182 }
00183 while(--len);
00184 }
00185 }
00186
00187
00188 void copy_from(const rendering_buffer& from,
00189 int xdst, int ydst,
00190 int xsrc, int ysrc,
00191 unsigned len)
00192 {
00193 memmove(m_rbuf->row(ydst) + xdst * 2,
00194 (const void*)(from.row(ysrc) + xsrc * 2), len * 2);
00195 }
00196
00197
00198 void blend_solid_hspan(int x, int y, unsigned len,
00199 const color_type& c, const int8u* covers)
00200 {
00201 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00202 do
00203 {
00204 int alpha = int(*covers++) * c.a;
00205 if(alpha)
00206 {
00207 if(alpha == 255*255)
00208 {
00209 *p = rgb565(c.r, c.g, c.b);
00210 }
00211 else
00212 {
00213 int16u rgb = *p;
00214 int r = (rgb >> 8) & 0xF8;
00215 int g = (rgb >> 3) & 0xFC;
00216 int b = (rgb << 3) & 0xF8;
00217 *p = (int16u)
00218 ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00219 (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00220 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00221 }
00222 }
00223 ++p;
00224 }
00225 while(--len);
00226 }
00227
00228
00229 void blend_solid_vspan(int x, int y, unsigned len,
00230 const color_type& c, const int8u* covers)
00231 {
00232 int8u* p = m_rbuf->row(y) + (x << 1);
00233 do
00234 {
00235 int alpha = int(*covers++) * c.a;
00236 if(alpha)
00237 {
00238 if(alpha == 255*255)
00239 {
00240 *(int16u*)p = rgb565(c.r, c.g, c.b);
00241 }
00242 else
00243 {
00244 int16u rgb = *(int16u*)p;
00245 int r = (rgb >> 8) & 0xF8;
00246 int g = (rgb >> 3) & 0xFC;
00247 int b = (rgb << 3) & 0xF8;
00248 *(int16u*)p = (int16u)
00249 ((((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00250 (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00251 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00252 }
00253 }
00254 p += m_rbuf->stride();
00255 }
00256 while(--len);
00257 }
00258
00259
00260 void blend_color_hspan(int x, int y, unsigned len,
00261 const color_type* colors,
00262 const int8u* covers,
00263 int8u cover)
00264 {
00265 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00266 do
00267 {
00268 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00269 if(alpha)
00270 {
00271 if(alpha == 255*255)
00272 {
00273 *(int16u*)p = rgb565(colors->r, colors->g, colors->b);
00274 }
00275 else
00276 {
00277 int16u rgb = *p;
00278 int r = (rgb >> 8) & 0xF8;
00279 int g = (rgb >> 3) & 0xFC;
00280 int b = (rgb << 3) & 0xF8;
00281 *p = (int16u)
00282 ((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00283 (((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00284 ((((colors->b - b) * alpha) + (b << 16)) >> 19));
00285 }
00286 }
00287 ++p;
00288 ++colors;
00289 }
00290 while(--len);
00291 }
00292
00293
00294 void blend_color_vspan(int x, int y, unsigned len,
00295 const color_type* colors,
00296 const int8u* covers,
00297 int8u cover)
00298 {
00299 int8u* p = m_rbuf->row(y) + (x << 1);
00300 do
00301 {
00302 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00303 if(alpha)
00304 {
00305 if(alpha == 255*255)
00306 {
00307 *(int16u*)p = rgb565(colors->r, colors->g, colors->b);
00308 }
00309 else
00310 {
00311 int16u rgb = *(int16u*)p;
00312 int r = (rgb >> 8) & 0xF8;
00313 int g = (rgb >> 3) & 0xFC;
00314 int b = (rgb << 3) & 0xF8;
00315 *(int16u*)p = (int16u)
00316 ((((((colors->r - r) * alpha) + (r << 16)) >> 8) & 0xF800) |
00317 (((((colors->g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) |
00318 ((((colors->b - b) * alpha) + (b << 16)) >> 19));
00319 }
00320 }
00321 p += m_rbuf->stride();
00322 ++colors;
00323 }
00324 while(--len);
00325 }
00326
00327 private:
00328 rendering_buffer* m_rbuf;
00329 };
00330
00331 }
00332
00333 #endif
00334