00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef AGG_PIXFMT_RGB555_INCLUDED
00017 #define AGG_PIXFMT_RGB555_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 rgb555(unsigned r, unsigned g, unsigned b)
00029 {
00030 return (int16u)(((r & 0xF8) << 7) | ((g & 0xF8) << 2) | (b >> 3));
00031 }
00032
00033
00034
00035 class pixfmt_rgb555
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_rgb555(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 >> 7) & 0xF8,
00057 (rgb >> 2) & 0xF8,
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] = rgb555(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 = rgb555(c.r, c.g, c.b);
00081 }
00082 else
00083 {
00084 int16u rgb = *p;
00085 int r = (rgb >> 7) & 0xF8;
00086 int g = (rgb >> 2) & 0xF8;
00087 int b = (rgb << 3) & 0xF8;
00088 *p = (int16u)
00089 ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00090 (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
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 = rgb555(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 = rgb555(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 = rgb555(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 >> 7) & 0xF8;
00141 int g = (rgb >> 2) & 0xF8;
00142 int b = (rgb << 3) & 0xF8;
00143 *p++ = (int16u)
00144 ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00145 (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
00146 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00147 }
00148 while(--len);
00149 }
00150 }
00151
00152
00153 void blend_vline(int x, int y, unsigned len,
00154 const color_type& c, int8u cover)
00155 {
00156 int8u* p = m_rbuf->row(y) + (x << 1);
00157 int alpha = int(cover) * c.a;
00158 if(alpha == 255*255)
00159 {
00160 int16u v = rgb555(c.r, c.g, c.b);
00161 do
00162 {
00163 *(int16u*)p = v;
00164 p += m_rbuf->stride();
00165 }
00166 while(--len);
00167 }
00168 else
00169 {
00170 do
00171 {
00172 int16u rgb = *(int16u*)p;
00173 int r = (rgb >> 7) & 0xF8;
00174 int g = (rgb >> 2) & 0xF8;
00175 int b = (rgb << 3) & 0xF8;
00176 *(int16u*)p = (int16u)
00177 ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00178 (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
00179 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00180 p += m_rbuf->stride();
00181 }
00182 while(--len);
00183 }
00184 }
00185
00186
00187 void copy_from(const rendering_buffer& from,
00188 int xdst, int ydst,
00189 int xsrc, int ysrc,
00190 unsigned len)
00191 {
00192 memmove(m_rbuf->row(ydst) + xdst * 2,
00193 (const void*)(from.row(ysrc) + xsrc * 2), len * 2);
00194 }
00195
00196
00197 void blend_solid_hspan(int x, int y, unsigned len,
00198 const color_type& c, const int8u* covers)
00199 {
00200 int16u* p = (int16u*)(m_rbuf->row(y)) + x;
00201 do
00202 {
00203 int alpha = int(*covers++) * c.a;
00204 if(alpha)
00205 {
00206 if(alpha == 255*255)
00207 {
00208 *p = rgb555(c.r, c.g, c.b);
00209 }
00210 else
00211 {
00212 int16u rgb = *p;
00213 int r = (rgb >> 7) & 0xF8;
00214 int g = (rgb >> 2) & 0xF8;
00215 int b = (rgb << 3) & 0xF8;
00216 *p = (int16u)
00217 ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00218 (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
00219 ((((c.b - b) * alpha) + (b << 16)) >> 19));
00220 }
00221 }
00222 ++p;
00223 }
00224 while(--len);
00225 }
00226
00227
00228 void blend_solid_vspan(int x, int y, unsigned len,
00229 const color_type& c, const int8u* covers)
00230 {
00231 int8u* p = m_rbuf->row(y) + (x << 1);
00232 do
00233 {
00234 int alpha = int(*covers++) * c.a;
00235
00236 if(alpha)
00237 {
00238 if(alpha == 255*255)
00239 {
00240 *(int16u*)p = rgb555(c.r, c.g, c.b);
00241 }
00242 else
00243 {
00244 int16u rgb = *(int16u*)p;
00245 int r = (rgb >> 7) & 0xF8;
00246 int g = (rgb >> 2) & 0xF8;
00247 int b = (rgb << 3) & 0xF8;
00248 *(int16u*)p = (int16u)
00249 ((((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00250 (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
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 = rgb555(colors->r, colors->g, colors->b);
00274 }
00275 else
00276 {
00277 int16u rgb = *p;
00278 int r = (rgb >> 7) & 0xF8;
00279 int g = (rgb >> 2) & 0xF8;
00280 int b = (rgb << 3) & 0xF8;
00281 *(int16u*)p = (int16u)
00282 ((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00283 (((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
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 = rgb555(colors->r, colors->g, colors->b);
00308 }
00309 else
00310 {
00311 int16u rgb = *(int16u*)p;
00312 int r = (rgb >> 7) & 0xF8;
00313 int g = (rgb >> 2) & 0xF8;
00314 int b = (rgb << 3) & 0xF8;
00315 *(int16u*)p = (int16u)
00316 ((((((colors->r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) |
00317 (((((colors->g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) |
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