~s-cecilio/lenmus/trunk

« back to all changes in this revision

Viewing changes to lomse/trunk/src/agg/include/agg_pixfmt_rgb_packed.h

  • Committer: Cecilio Salmeron
  • Date: 2016-02-04 10:15:44 UTC
  • Revision ID: s.cecilios@gmail.com-20160204101544-wdodav3eyyej64ga
Prepare for GitHub migration

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//----------------------------------------------------------------------------
2
 
// Anti-Grain Geometry - Version 2.4
3
 
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4
 
//
5
 
// Permission to copy, use, modify, sell and distribute this software 
6
 
// is granted provided this copyright notice appears in all copies. 
7
 
// This software is provided "as is" without express or implied
8
 
// warranty, and with no claim as to its suitability for any purpose.
9
 
//
10
 
//----------------------------------------------------------------------------
11
 
// Contact: mcseem@antigrain.com
12
 
//          mcseemagg@yahoo.com
13
 
//          http://www.antigrain.com
14
 
//----------------------------------------------------------------------------
15
 
//
16
 
// Adaptation for high precision colors has been sponsored by 
17
 
// Liberty Technology Systems, Inc., visit http://lib-sys.com
18
 
//
19
 
// Liberty Technology Systems, Inc. is the provider of
20
 
// PostScript and PDF technology for software developers.
21
 
// 
22
 
//----------------------------------------------------------------------------
23
 
 
24
 
#ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
25
 
#define AGG_PIXFMT_RGB_PACKED_INCLUDED
26
 
 
27
 
#include <string.h>
28
 
#include "agg_basics.h"
29
 
#include "agg_color_rgba.h"
30
 
#include "agg_rendering_buffer.h"
31
 
 
32
 
namespace agg
33
 
{
34
 
    //=========================================================blender_rgb555
35
 
    struct blender_rgb555
36
 
    {
37
 
        typedef rgba8 color_type;
38
 
        typedef color_type::value_type value_type;
39
 
        typedef color_type::calc_type calc_type;
40
 
        typedef int16u pixel_type;
41
 
 
42
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
43
 
                                         unsigned cr, unsigned cg, unsigned cb,
44
 
                                         unsigned alpha, 
45
 
                                         unsigned)
46
 
        {
47
 
            pixel_type rgb = *p;
48
 
            calc_type r = (rgb >> 7) & 0xF8;
49
 
            calc_type g = (rgb >> 2) & 0xF8;
50
 
            calc_type b = (rgb << 3) & 0xF8;
51
 
            *p = (pixel_type)
52
 
               (((((cr - r) * alpha + (r << 8)) >> 1)  & 0x7C00) |
53
 
                ((((cg - g) * alpha + (g << 8)) >> 6)  & 0x03E0) |
54
 
                 (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000);
55
 
        }
56
 
 
57
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
58
 
        {
59
 
            return (pixel_type)(((r & 0xF8) << 7) | 
60
 
                                ((g & 0xF8) << 2) | 
61
 
                                 (b >> 3) | 0x8000);
62
 
        }
63
 
 
64
 
        static AGG_INLINE color_type make_color(pixel_type p)
65
 
        {
66
 
            return color_type((p >> 7) & 0xF8, 
67
 
                              (p >> 2) & 0xF8, 
68
 
                              (p << 3) & 0xF8);
69
 
        }
70
 
    };
71
 
 
72
 
 
73
 
    //=====================================================blender_rgb555_pre
74
 
    struct blender_rgb555_pre
75
 
    {
76
 
        typedef rgba8 color_type;
77
 
        typedef color_type::value_type value_type;
78
 
        typedef color_type::calc_type calc_type;
79
 
        typedef int16u pixel_type;
80
 
 
81
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
82
 
                                         unsigned cr, unsigned cg, unsigned cb,
83
 
                                         unsigned alpha, 
84
 
                                         unsigned cover)
85
 
        {
86
 
            alpha = color_type::base_mask - alpha;
87
 
            pixel_type rgb = *p;
88
 
            calc_type r = (rgb >> 7) & 0xF8;
89
 
            calc_type g = (rgb >> 2) & 0xF8;
90
 
            calc_type b = (rgb << 3) & 0xF8;
91
 
            *p = (pixel_type)
92
 
               ((((r * alpha + cr * cover) >> 1)  & 0x7C00) |
93
 
                (((g * alpha + cg * cover) >> 6)  & 0x03E0) |
94
 
                 ((b * alpha + cb * cover) >> 11) | 0x8000);
95
 
        }
96
 
 
97
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
98
 
        {
99
 
            return (pixel_type)(((r & 0xF8) << 7) | 
100
 
                                ((g & 0xF8) << 2) | 
101
 
                                 (b >> 3) | 0x8000);
102
 
        }
103
 
 
104
 
        static AGG_INLINE color_type make_color(pixel_type p)
105
 
        {
106
 
            return color_type((p >> 7) & 0xF8, 
107
 
                              (p >> 2) & 0xF8, 
108
 
                              (p << 3) & 0xF8);
109
 
        }
110
 
    };
111
 
 
112
 
 
113
 
 
114
 
 
115
 
    //=====================================================blender_rgb555_gamma
116
 
    template<class Gamma> class blender_rgb555_gamma
117
 
    {
118
 
    public:
119
 
        typedef rgba8 color_type;
120
 
        typedef color_type::value_type value_type;
121
 
        typedef color_type::calc_type calc_type;
122
 
        typedef int16u pixel_type;
123
 
        typedef Gamma gamma_type;
124
 
 
125
 
        blender_rgb555_gamma() : m_gamma(0) {}
126
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
127
 
 
128
 
        AGG_INLINE void blend_pix(pixel_type* p, 
129
 
                                  unsigned cr, unsigned cg, unsigned cb,
130
 
                                  unsigned alpha, 
131
 
                                  unsigned)
132
 
        {
133
 
            pixel_type rgb = *p;
134
 
            calc_type r = m_gamma->dir((rgb >> 7) & 0xF8);
135
 
            calc_type g = m_gamma->dir((rgb >> 2) & 0xF8);
136
 
            calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
137
 
            *p = (pixel_type)
138
 
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) |
139
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) |
140
 
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000);
141
 
        }
142
 
 
143
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
144
 
        {
145
 
            return (pixel_type)(((r & 0xF8) << 7) | 
146
 
                                ((g & 0xF8) << 2) | 
147
 
                                 (b >> 3) | 0x8000);
148
 
        }
149
 
 
150
 
        static AGG_INLINE color_type make_color(pixel_type p)
151
 
        {
152
 
            return color_type((p >> 7) & 0xF8, 
153
 
                              (p >> 2) & 0xF8, 
154
 
                              (p << 3) & 0xF8);
155
 
        }
156
 
 
157
 
    private:
158
 
        const Gamma* m_gamma;
159
 
    };
160
 
 
161
 
 
162
 
 
163
 
 
164
 
 
165
 
    //=========================================================blender_rgb565
166
 
    struct blender_rgb565
167
 
    {
168
 
        typedef rgba8 color_type;
169
 
        typedef color_type::value_type value_type;
170
 
        typedef color_type::calc_type calc_type;
171
 
        typedef int16u pixel_type;
172
 
 
173
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
174
 
                                         unsigned cr, unsigned cg, unsigned cb,
175
 
                                         unsigned alpha, 
176
 
                                         unsigned)
177
 
        {
178
 
            pixel_type rgb = *p;
179
 
            calc_type r = (rgb >> 8) & 0xF8;
180
 
            calc_type g = (rgb >> 3) & 0xFC;
181
 
            calc_type b = (rgb << 3) & 0xF8;
182
 
            *p = (pixel_type)
183
 
               (((((cr - r) * alpha + (r << 8))     ) & 0xF800) |
184
 
                ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) |
185
 
                 (((cb - b) * alpha + (b << 8)) >> 11));
186
 
        }
187
 
 
188
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
189
 
        {
190
 
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
191
 
        }
192
 
 
193
 
        static AGG_INLINE color_type make_color(pixel_type p)
194
 
        {
195
 
            return color_type((p >> 8) & 0xF8, 
196
 
                              (p >> 3) & 0xFC, 
197
 
                              (p << 3) & 0xF8);
198
 
        }
199
 
    };
200
 
 
201
 
 
202
 
 
203
 
    //=====================================================blender_rgb565_pre
204
 
    struct blender_rgb565_pre
205
 
    {
206
 
        typedef rgba8 color_type;
207
 
        typedef color_type::value_type value_type;
208
 
        typedef color_type::calc_type calc_type;
209
 
        typedef int16u pixel_type;
210
 
 
211
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
212
 
                                         unsigned cr, unsigned cg, unsigned cb,
213
 
                                         unsigned alpha, 
214
 
                                         unsigned cover)
215
 
        {
216
 
            alpha = color_type::base_mask - alpha;
217
 
            pixel_type rgb = *p;
218
 
            calc_type r = (rgb >> 8) & 0xF8;
219
 
            calc_type g = (rgb >> 3) & 0xFC;
220
 
            calc_type b = (rgb << 3) & 0xF8;
221
 
            *p = (pixel_type)
222
 
               ((((r * alpha + cr * cover)      ) & 0xF800) |
223
 
                (((g * alpha + cg * cover) >> 5 ) & 0x07E0) |
224
 
                 ((b * alpha + cb * cover) >> 11));
225
 
        }
226
 
 
227
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
228
 
        {
229
 
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
230
 
        }
231
 
 
232
 
        static AGG_INLINE color_type make_color(pixel_type p)
233
 
        {
234
 
            return color_type((p >> 8) & 0xF8, 
235
 
                              (p >> 3) & 0xFC, 
236
 
                              (p << 3) & 0xF8);
237
 
        }
238
 
    };
239
 
 
240
 
 
241
 
 
242
 
    //=====================================================blender_rgb565_gamma
243
 
    template<class Gamma> class blender_rgb565_gamma
244
 
    {
245
 
    public:
246
 
        typedef rgba8 color_type;
247
 
        typedef color_type::value_type value_type;
248
 
        typedef color_type::calc_type calc_type;
249
 
        typedef int16u pixel_type;
250
 
        typedef Gamma gamma_type;
251
 
 
252
 
        blender_rgb565_gamma() : m_gamma(0) {}
253
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
254
 
 
255
 
        AGG_INLINE void blend_pix(pixel_type* p, 
256
 
                                  unsigned cr, unsigned cg, unsigned cb,
257
 
                                  unsigned alpha, 
258
 
                                  unsigned)
259
 
        {
260
 
            pixel_type rgb = *p;
261
 
            calc_type r = m_gamma->dir((rgb >> 8) & 0xF8);
262
 
            calc_type g = m_gamma->dir((rgb >> 3) & 0xFC);
263
 
            calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
264
 
            *p = (pixel_type)
265
 
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) |
266
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) |
267
 
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3));
268
 
        }
269
 
 
270
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
271
 
        {
272
 
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
273
 
        }
274
 
 
275
 
        static AGG_INLINE color_type make_color(pixel_type p)
276
 
        {
277
 
            return color_type((p >> 8) & 0xF8, 
278
 
                              (p >> 3) & 0xFC, 
279
 
                              (p << 3) & 0xF8);
280
 
        }
281
 
 
282
 
    private:
283
 
        const Gamma* m_gamma;
284
 
    };
285
 
 
286
 
 
287
 
 
288
 
    //=====================================================blender_rgbAAA
289
 
    struct blender_rgbAAA
290
 
    {
291
 
        typedef rgba16 color_type;
292
 
        typedef color_type::value_type value_type;
293
 
        typedef color_type::calc_type calc_type;
294
 
        typedef int32u pixel_type;
295
 
 
296
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
297
 
                                         unsigned cr, unsigned cg, unsigned cb,
298
 
                                         unsigned alpha, 
299
 
                                         unsigned)
300
 
        {
301
 
            pixel_type rgb = *p;
302
 
            calc_type r = (rgb >> 14) & 0xFFC0;
303
 
            calc_type g = (rgb >> 4)  & 0xFFC0;
304
 
            calc_type b = (rgb << 6)  & 0xFFC0;
305
 
            *p = (pixel_type)
306
 
               (((((cr - r) * alpha + (r << 16)) >> 2)  & 0x3FF00000) |
307
 
                ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
308
 
                 (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000);
309
 
        }
310
 
 
311
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
312
 
        {
313
 
            return (pixel_type)(((r & 0xFFC0) << 14) | 
314
 
                                ((g & 0xFFC0) << 4) | 
315
 
                                 (b >> 6) | 0xC0000000);
316
 
        }
317
 
 
318
 
        static AGG_INLINE color_type make_color(pixel_type p)
319
 
        {
320
 
            return color_type((p >> 14) & 0xFFC0, 
321
 
                              (p >> 4)  & 0xFFC0, 
322
 
                              (p << 6)  & 0xFFC0);
323
 
        }
324
 
    };
325
 
 
326
 
 
327
 
 
328
 
    //==================================================blender_rgbAAA_pre
329
 
    struct blender_rgbAAA_pre
330
 
    {
331
 
        typedef rgba16 color_type;
332
 
        typedef color_type::value_type value_type;
333
 
        typedef color_type::calc_type calc_type;
334
 
        typedef int32u pixel_type;
335
 
 
336
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
337
 
                                         unsigned cr, unsigned cg, unsigned cb,
338
 
                                         unsigned alpha, 
339
 
                                         unsigned cover)
340
 
        {
341
 
            alpha = color_type::base_mask - alpha;
342
 
            cover = (cover + 1) << (color_type::base_shift - 8);
343
 
            pixel_type rgb = *p;
344
 
            calc_type r = (rgb >> 14) & 0xFFC0;
345
 
            calc_type g = (rgb >> 4)  & 0xFFC0;
346
 
            calc_type b = (rgb << 6)  & 0xFFC0;
347
 
            *p = (pixel_type)
348
 
               ((((r * alpha + cr * cover) >> 2)  & 0x3FF00000) |
349
 
                (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
350
 
                 ((b * alpha + cb * cover) >> 22) | 0xC0000000);
351
 
        }
352
 
 
353
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
354
 
        {
355
 
            return (pixel_type)(((r & 0xFFC0) << 14) | 
356
 
                                ((g & 0xFFC0) << 4) | 
357
 
                                 (b >> 6) | 0xC0000000);
358
 
        }
359
 
 
360
 
        static AGG_INLINE color_type make_color(pixel_type p)
361
 
        {
362
 
            return color_type((p >> 14) & 0xFFC0, 
363
 
                              (p >> 4)  & 0xFFC0, 
364
 
                              (p << 6)  & 0xFFC0);
365
 
        }
366
 
    };
367
 
 
368
 
 
369
 
 
370
 
    //=================================================blender_rgbAAA_gamma
371
 
    template<class Gamma> class blender_rgbAAA_gamma
372
 
    {
373
 
    public:
374
 
        typedef rgba16 color_type;
375
 
        typedef color_type::value_type value_type;
376
 
        typedef color_type::calc_type calc_type;
377
 
        typedef int32u pixel_type;
378
 
        typedef Gamma gamma_type;
379
 
 
380
 
        blender_rgbAAA_gamma() : m_gamma(0) {}
381
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
382
 
 
383
 
        AGG_INLINE void blend_pix(pixel_type* p, 
384
 
                                  unsigned cr, unsigned cg, unsigned cb,
385
 
                                  unsigned alpha, 
386
 
                                  unsigned)
387
 
        {
388
 
            pixel_type rgb = *p;
389
 
            calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0);
390
 
            calc_type g = m_gamma->dir((rgb >> 4)  & 0xFFC0);
391
 
            calc_type b = m_gamma->dir((rgb << 6)  & 0xFFC0);
392
 
            *p = (pixel_type)
393
 
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) |
394
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
395
 
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000);
396
 
        }
397
 
 
398
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
399
 
        {
400
 
            return (pixel_type)(((r & 0xFFC0) << 14) | 
401
 
                                ((g & 0xFFC0) << 4) | 
402
 
                                 (b >> 6) | 0xC0000000);
403
 
        }
404
 
 
405
 
        static AGG_INLINE color_type make_color(pixel_type p)
406
 
        {
407
 
            return color_type((p >> 14) & 0xFFC0, 
408
 
                              (p >> 4)  & 0xFFC0, 
409
 
                              (p << 6)  & 0xFFC0);
410
 
        }
411
 
    private:
412
 
        const Gamma* m_gamma;
413
 
    };
414
 
 
415
 
 
416
 
    //=====================================================blender_bgrAAA
417
 
    struct blender_bgrAAA
418
 
    {
419
 
        typedef rgba16 color_type;
420
 
        typedef color_type::value_type value_type;
421
 
        typedef color_type::calc_type calc_type;
422
 
        typedef int32u pixel_type;
423
 
 
424
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
425
 
                                         unsigned cr, unsigned cg, unsigned cb,
426
 
                                         unsigned alpha, 
427
 
                                         unsigned)
428
 
        {
429
 
            pixel_type bgr = *p;
430
 
            calc_type b = (bgr >> 14) & 0xFFC0;
431
 
            calc_type g = (bgr >> 4)  & 0xFFC0;
432
 
            calc_type r = (bgr << 6)  & 0xFFC0;
433
 
            *p = (pixel_type)
434
 
               (((((cb - b) * alpha + (b << 16)) >> 2)  & 0x3FF00000) |
435
 
                ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
436
 
                 (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000);
437
 
        }
438
 
 
439
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
440
 
        {
441
 
            return (pixel_type)(((b & 0xFFC0) << 14) | 
442
 
                                ((g & 0xFFC0) << 4) | 
443
 
                                 (r >> 6) | 0xC0000000);
444
 
        }
445
 
 
446
 
        static AGG_INLINE color_type make_color(pixel_type p)
447
 
        {
448
 
            return color_type((p << 6)  & 0xFFC0, 
449
 
                              (p >> 4)  & 0xFFC0, 
450
 
                              (p >> 14) & 0xFFC0);
451
 
        }
452
 
    };
453
 
 
454
 
 
455
 
 
456
 
    //=================================================blender_bgrAAA_pre
457
 
    struct blender_bgrAAA_pre
458
 
    {
459
 
        typedef rgba16 color_type;
460
 
        typedef color_type::value_type value_type;
461
 
        typedef color_type::calc_type calc_type;
462
 
        typedef int32u pixel_type;
463
 
 
464
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
465
 
                                         unsigned cr, unsigned cg, unsigned cb,
466
 
                                         unsigned alpha, 
467
 
                                         unsigned cover)
468
 
        {
469
 
            alpha = color_type::base_mask - alpha;
470
 
            cover = (cover + 1) << (color_type::base_shift - 8);
471
 
            pixel_type bgr = *p;
472
 
            calc_type b = (bgr >> 14) & 0xFFC0;
473
 
            calc_type g = (bgr >> 4)  & 0xFFC0;
474
 
            calc_type r = (bgr << 6)  & 0xFFC0;
475
 
            *p = (pixel_type)
476
 
               ((((b * alpha + cb * cover) >> 2)  & 0x3FF00000) |
477
 
                (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
478
 
                 ((r * alpha + cr * cover) >> 22) | 0xC0000000);
479
 
        }
480
 
 
481
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
482
 
        {
483
 
            return (pixel_type)(((b & 0xFFC0) << 14) | 
484
 
                                ((g & 0xFFC0) << 4) | 
485
 
                                 (r >> 6) | 0xC0000000);
486
 
        }
487
 
 
488
 
        static AGG_INLINE color_type make_color(pixel_type p)
489
 
        {
490
 
            return color_type((p << 6)  & 0xFFC0, 
491
 
                              (p >> 4)  & 0xFFC0, 
492
 
                              (p >> 14) & 0xFFC0);
493
 
        }
494
 
    };
495
 
 
496
 
 
497
 
 
498
 
    //=================================================blender_bgrAAA_gamma
499
 
    template<class Gamma> class blender_bgrAAA_gamma
500
 
    {
501
 
    public:
502
 
        typedef rgba16 color_type;
503
 
        typedef color_type::value_type value_type;
504
 
        typedef color_type::calc_type calc_type;
505
 
        typedef int32u pixel_type;
506
 
        typedef Gamma gamma_type;
507
 
 
508
 
        blender_bgrAAA_gamma() : m_gamma(0) {}
509
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
510
 
 
511
 
        AGG_INLINE void blend_pix(pixel_type* p, 
512
 
                                  unsigned cr, unsigned cg, unsigned cb,
513
 
                                  unsigned alpha, 
514
 
                                  unsigned)
515
 
        {
516
 
            pixel_type bgr = *p;
517
 
            calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0);
518
 
            calc_type g = m_gamma->dir((bgr >> 4)  & 0xFFC0);
519
 
            calc_type r = m_gamma->dir((bgr << 6)  & 0xFFC0);
520
 
            *p = (pixel_type)
521
 
               (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) |
522
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
523
 
                 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000);
524
 
        }
525
 
 
526
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
527
 
        {
528
 
            return (pixel_type)(((b & 0xFFC0) << 14) | 
529
 
                                ((g & 0xFFC0) << 4) | 
530
 
                                 (r >> 6) | 0xC0000000);
531
 
        }
532
 
 
533
 
        static AGG_INLINE color_type make_color(pixel_type p)
534
 
        {
535
 
            return color_type((p << 6)  & 0xFFC0, 
536
 
                              (p >> 4)  & 0xFFC0, 
537
 
                              (p >> 14) & 0xFFC0);
538
 
        }
539
 
 
540
 
    private:
541
 
        const Gamma* m_gamma;
542
 
    };
543
 
 
544
 
 
545
 
 
546
 
    //=====================================================blender_rgbBBA
547
 
    struct blender_rgbBBA
548
 
    {
549
 
        typedef rgba16 color_type;
550
 
        typedef color_type::value_type value_type;
551
 
        typedef color_type::calc_type calc_type;
552
 
        typedef int32u pixel_type;
553
 
 
554
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
555
 
                                         unsigned cr, unsigned cg, unsigned cb,
556
 
                                         unsigned alpha, 
557
 
                                         unsigned)
558
 
        {
559
 
            pixel_type rgb = *p;
560
 
            calc_type r = (rgb >> 16) & 0xFFE0;
561
 
            calc_type g = (rgb >> 5)  & 0xFFE0;
562
 
            calc_type b = (rgb << 6)  & 0xFFC0;
563
 
            *p = (pixel_type)
564
 
               (((((cr - r) * alpha + (r << 16))      ) & 0xFFE00000) |
565
 
                ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) |
566
 
                 (((cb - b) * alpha + (b << 16)) >> 22));
567
 
        }
568
 
 
569
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
570
 
        {
571
 
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
572
 
        }
573
 
 
574
 
        static AGG_INLINE color_type make_color(pixel_type p)
575
 
        {
576
 
            return color_type((p >> 16) & 0xFFE0, 
577
 
                              (p >> 5)  & 0xFFE0, 
578
 
                              (p << 6)  & 0xFFC0);
579
 
        }
580
 
    };
581
 
 
582
 
 
583
 
    //=================================================blender_rgbBBA_pre
584
 
    struct blender_rgbBBA_pre
585
 
    {
586
 
        typedef rgba16 color_type;
587
 
        typedef color_type::value_type value_type;
588
 
        typedef color_type::calc_type calc_type;
589
 
        typedef int32u pixel_type;
590
 
 
591
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
592
 
                                         unsigned cr, unsigned cg, unsigned cb,
593
 
                                         unsigned alpha, 
594
 
                                         unsigned cover)
595
 
        {
596
 
            alpha = color_type::base_mask - alpha;
597
 
            cover = (cover + 1) << (color_type::base_shift - 8);
598
 
            pixel_type rgb = *p;
599
 
            calc_type r = (rgb >> 16) & 0xFFE0;
600
 
            calc_type g = (rgb >> 5)  & 0xFFE0;
601
 
            calc_type b = (rgb << 6)  & 0xFFC0;
602
 
            *p = (pixel_type)
603
 
               ((((r * alpha + cr * cover)      ) & 0xFFE00000) |
604
 
                (((g * alpha + cg * cover) >> 11) & 0x001FFC00) |
605
 
                 ((b * alpha + cb * cover) >> 22));
606
 
        }
607
 
 
608
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
609
 
        {
610
 
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
611
 
        }
612
 
 
613
 
        static AGG_INLINE color_type make_color(pixel_type p)
614
 
        {
615
 
            return color_type((p >> 16) & 0xFFE0, 
616
 
                              (p >> 5)  & 0xFFE0, 
617
 
                              (p << 6)  & 0xFFC0);
618
 
        }
619
 
    };
620
 
 
621
 
 
622
 
 
623
 
    //=================================================blender_rgbBBA_gamma
624
 
    template<class Gamma> class blender_rgbBBA_gamma
625
 
    {
626
 
    public:
627
 
        typedef rgba16 color_type;
628
 
        typedef color_type::value_type value_type;
629
 
        typedef color_type::calc_type calc_type;
630
 
        typedef int32u pixel_type;
631
 
        typedef Gamma gamma_type;
632
 
 
633
 
        blender_rgbBBA_gamma() : m_gamma(0) {}
634
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
635
 
 
636
 
        AGG_INLINE void blend_pix(pixel_type* p, 
637
 
                                  unsigned cr, unsigned cg, unsigned cb,
638
 
                                  unsigned alpha, 
639
 
                                  unsigned)
640
 
        {
641
 
            pixel_type rgb = *p;
642
 
            calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0);
643
 
            calc_type g = m_gamma->dir((rgb >> 5)  & 0xFFE0);
644
 
            calc_type b = m_gamma->dir((rgb << 6)  & 0xFFC0);
645
 
            *p = (pixel_type)
646
 
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) |
647
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) |
648
 
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ));
649
 
        }
650
 
 
651
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
652
 
        {
653
 
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
654
 
        }
655
 
 
656
 
        static AGG_INLINE color_type make_color(pixel_type p)
657
 
        {
658
 
            return color_type((p >> 16) & 0xFFE0, 
659
 
                              (p >> 5)  & 0xFFE0, 
660
 
                              (p << 6)  & 0xFFC0);
661
 
        }
662
 
 
663
 
    private:
664
 
        const Gamma* m_gamma;
665
 
    };
666
 
 
667
 
 
668
 
    //=====================================================blender_bgrABB
669
 
    struct blender_bgrABB
670
 
    {
671
 
        typedef rgba16 color_type;
672
 
        typedef color_type::value_type value_type;
673
 
        typedef color_type::calc_type calc_type;
674
 
        typedef int32u pixel_type;
675
 
 
676
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
677
 
                                         unsigned cr, unsigned cg, unsigned cb,
678
 
                                         unsigned alpha, 
679
 
                                         unsigned)
680
 
        {
681
 
            pixel_type bgr = *p;
682
 
            calc_type b = (bgr >> 16) & 0xFFC0;
683
 
            calc_type g = (bgr >> 6)  & 0xFFE0;
684
 
            calc_type r = (bgr << 5)  & 0xFFE0;
685
 
            *p = (pixel_type)
686
 
               (((((cb - b) * alpha + (b << 16))      ) & 0xFFC00000) |
687
 
                ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) |
688
 
                 (((cr - r) * alpha + (r << 16)) >> 21));
689
 
        }
690
 
 
691
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
692
 
        {
693
 
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
694
 
        }
695
 
 
696
 
        static AGG_INLINE color_type make_color(pixel_type p)
697
 
        {
698
 
            return color_type((p << 5)  & 0xFFE0,
699
 
                              (p >> 6)  & 0xFFE0, 
700
 
                              (p >> 16) & 0xFFC0);
701
 
        }
702
 
    };
703
 
 
704
 
 
705
 
    //=================================================blender_bgrABB_pre
706
 
    struct blender_bgrABB_pre
707
 
    {
708
 
        typedef rgba16 color_type;
709
 
        typedef color_type::value_type value_type;
710
 
        typedef color_type::calc_type calc_type;
711
 
        typedef int32u pixel_type;
712
 
 
713
 
        static AGG_INLINE void blend_pix(pixel_type* p, 
714
 
                                         unsigned cr, unsigned cg, unsigned cb,
715
 
                                         unsigned alpha, 
716
 
                                         unsigned cover)
717
 
        {
718
 
            alpha = color_type::base_mask - alpha;
719
 
            cover = (cover + 1) << (color_type::base_shift - 8);
720
 
            pixel_type bgr = *p;
721
 
            calc_type b = (bgr >> 16) & 0xFFC0;
722
 
            calc_type g = (bgr >> 6)  & 0xFFE0;
723
 
            calc_type r = (bgr << 5)  & 0xFFE0;
724
 
            *p = (pixel_type)
725
 
               ((((b * alpha + cb * cover)      ) & 0xFFC00000) |
726
 
                (((g * alpha + cg * cover) >> 10) & 0x003FF800) |
727
 
                 ((r * alpha + cr * cover) >> 21));
728
 
        }
729
 
 
730
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
731
 
        {
732
 
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
733
 
        }
734
 
 
735
 
        static AGG_INLINE color_type make_color(pixel_type p)
736
 
        {
737
 
            return color_type((p << 5)  & 0xFFE0,
738
 
                              (p >> 6)  & 0xFFE0, 
739
 
                              (p >> 16) & 0xFFC0);
740
 
        }
741
 
    };
742
 
 
743
 
 
744
 
 
745
 
    //=================================================blender_bgrABB_gamma
746
 
    template<class Gamma> class blender_bgrABB_gamma
747
 
    {
748
 
    public:
749
 
        typedef rgba16 color_type;
750
 
        typedef color_type::value_type value_type;
751
 
        typedef color_type::calc_type calc_type;
752
 
        typedef int32u pixel_type;
753
 
        typedef Gamma gamma_type;
754
 
 
755
 
        blender_bgrABB_gamma() : m_gamma(0) {}
756
 
        void gamma(const gamma_type& g) { m_gamma = &g; }
757
 
 
758
 
        AGG_INLINE void blend_pix(pixel_type* p, 
759
 
                                  unsigned cr, unsigned cg, unsigned cb,
760
 
                                  unsigned alpha, 
761
 
                                  unsigned)
762
 
        {
763
 
            pixel_type bgr = *p;
764
 
            calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0);
765
 
            calc_type g = m_gamma->dir((bgr >> 6)  & 0xFFE0);
766
 
            calc_type r = m_gamma->dir((bgr << 5)  & 0xFFE0);
767
 
            *p = (pixel_type)
768
 
               (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) |
769
 
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) |
770
 
                 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 ));
771
 
        }
772
 
 
773
 
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
774
 
        {
775
 
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
776
 
        }
777
 
 
778
 
        static AGG_INLINE color_type make_color(pixel_type p)
779
 
        {
780
 
            return color_type((p << 5)  & 0xFFE0,
781
 
                              (p >> 6)  & 0xFFE0, 
782
 
                              (p >> 16) & 0xFFC0);
783
 
        }
784
 
 
785
 
    private:
786
 
        const Gamma* m_gamma;
787
 
    };
788
 
 
789
 
 
790
 
    
791
 
    //===========================================pixfmt_alpha_blend_rgb_packed
792
 
    template<class Blender,  class RenBuf> class pixfmt_alpha_blend_rgb_packed
793
 
    {
794
 
    public:
795
 
        typedef RenBuf   rbuf_type;
796
 
        typedef typename rbuf_type::row_data row_data;
797
 
        typedef Blender  blender_type;
798
 
        typedef typename blender_type::color_type color_type;
799
 
        typedef typename blender_type::pixel_type pixel_type;
800
 
        typedef int                               order_type; // A fake one
801
 
        typedef typename color_type::value_type   value_type;
802
 
        typedef typename color_type::calc_type    calc_type;
803
 
        enum base_scale_e 
804
 
        {
805
 
            base_shift = color_type::base_shift,
806
 
            base_scale = color_type::base_scale,
807
 
            base_mask  = color_type::base_mask,
808
 
            pix_width  = sizeof(pixel_type)
809
 
        };
810
 
 
811
 
    private:
812
 
        //--------------------------------------------------------------------
813
 
        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
814
 
        {
815
 
            if (c.a)
816
 
            {
817
 
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
818
 
                if(alpha == base_mask)
819
 
                {
820
 
                    *p = m_blender.make_pix(c.r, c.g, c.b);
821
 
                }
822
 
                else
823
 
                {
824
 
                    m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
825
 
                }
826
 
            }
827
 
        }
828
 
 
829
 
    public:
830
 
        //--------------------------------------------------------------------
831
 
        explicit pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {}
832
 
        void attach(rbuf_type& rb) { m_rbuf = &rb; }
833
 
 
834
 
        //--------------------------------------------------------------------
835
 
        template<class PixFmt>
836
 
        bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
837
 
        {
838
 
            rect_i r(x1, y1, x2, y2);
839
 
            if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
840
 
            {
841
 
                int stride = pixf.stride();
842
 
                m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 
843
 
                               (r.x2 - r.x1) + 1,
844
 
                               (r.y2 - r.y1) + 1,
845
 
                               stride);
846
 
                return true;
847
 
            }
848
 
            return false;
849
 
        }
850
 
 
851
 
        Blender& blender() { return m_blender; }
852
 
 
853
 
        //--------------------------------------------------------------------
854
 
        AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
855
 
        AGG_INLINE unsigned height() const { return m_rbuf->height(); }
856
 
        AGG_INLINE int      stride() const { return m_rbuf->stride(); }
857
 
 
858
 
        //--------------------------------------------------------------------
859
 
        AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
860
 
        AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
861
 
        AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
862
 
 
863
 
        //--------------------------------------------------------------------
864
 
        AGG_INLINE int8u* pix_ptr(int x, int y)
865
 
        {
866
 
            return m_rbuf->row_ptr(y) + x * pix_width;
867
 
        }
868
 
 
869
 
        AGG_INLINE const int8u* pix_ptr(int x, int y) const
870
 
        {
871
 
            return m_rbuf->row_ptr(y) + x * pix_width;
872
 
        }
873
 
 
874
 
        //--------------------------------------------------------------------
875
 
        AGG_INLINE void make_pix(int8u* p, const color_type& c)
876
 
        {
877
 
            *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
878
 
        }
879
 
 
880
 
        //--------------------------------------------------------------------
881
 
        AGG_INLINE color_type pixel(int x, int y) const
882
 
        {
883
 
            return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]);
884
 
        }
885
 
 
886
 
        //--------------------------------------------------------------------
887
 
        AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
888
 
        {
889
 
            ((pixel_type*)
890
 
                m_rbuf->row_ptr(x, y, 1))[x] = 
891
 
                    m_blender.make_pix(c.r, c.g, c.b);
892
 
        }
893
 
 
894
 
        //--------------------------------------------------------------------
895
 
        AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
896
 
        {
897
 
            copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover);
898
 
        }
899
 
 
900
 
        //--------------------------------------------------------------------
901
 
        AGG_INLINE void copy_hline(int x, int y, 
902
 
                                   unsigned len, 
903
 
                                   const color_type& c)
904
 
        {
905
 
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
906
 
            pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
907
 
            do
908
 
            {
909
 
                *p++ = v;
910
 
            }
911
 
            while(--len);
912
 
        }
913
 
 
914
 
        //--------------------------------------------------------------------
915
 
        AGG_INLINE void copy_vline(int x, int y,
916
 
                                   unsigned len, 
917
 
                                   const color_type& c)
918
 
        {
919
 
            pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
920
 
            do
921
 
            {
922
 
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
923
 
                *p = v;
924
 
            }
925
 
            while(--len);
926
 
        }
927
 
 
928
 
        //--------------------------------------------------------------------
929
 
        void blend_hline(int x, int y,
930
 
                         unsigned len, 
931
 
                         const color_type& c,
932
 
                         int8u cover)
933
 
        {
934
 
            if (c.a)
935
 
            {
936
 
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
937
 
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
938
 
                if(alpha == base_mask)
939
 
                {
940
 
                    pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
941
 
                    do
942
 
                    {
943
 
                        *p++ = v;
944
 
                    }
945
 
                    while(--len);
946
 
                }
947
 
                else
948
 
                {
949
 
                    do
950
 
                    {
951
 
                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
952
 
                        ++p;
953
 
                    }
954
 
                    while(--len);
955
 
                }
956
 
            }
957
 
        }
958
 
 
959
 
        //--------------------------------------------------------------------
960
 
        void blend_vline(int x, int y,
961
 
                         unsigned len, 
962
 
                         const color_type& c,
963
 
                         int8u cover)
964
 
        {
965
 
            if (c.a)
966
 
            {
967
 
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
968
 
                if(alpha == base_mask)
969
 
                {
970
 
                    pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
971
 
                    do
972
 
                    {
973
 
                        ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
974
 
                    }
975
 
                    while(--len);
976
 
                }
977
 
                else
978
 
                {
979
 
                    do
980
 
                    {
981
 
                        m_blender.blend_pix(
982
 
                            (pixel_type*)m_rbuf->row_ptr(x, y++, 1), 
983
 
                            c.r, c.g, c.b, alpha, cover);
984
 
                    }
985
 
                    while(--len);
986
 
                }
987
 
            }
988
 
        }
989
 
 
990
 
        //--------------------------------------------------------------------
991
 
        void blend_solid_hspan(int x, int y,
992
 
                               unsigned len, 
993
 
                               const color_type& c,
994
 
                               const int8u* covers)
995
 
        {
996
 
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
997
 
            do 
998
 
            {
999
 
                copy_or_blend_pix(p, c, *covers++);
1000
 
                ++p;
1001
 
            }
1002
 
            while(--len);
1003
 
        }
1004
 
 
1005
 
        //--------------------------------------------------------------------
1006
 
        void blend_solid_vspan(int x, int y,
1007
 
                               unsigned len, 
1008
 
                               const color_type& c,
1009
 
                               const int8u* covers)
1010
 
        {
1011
 
            do 
1012
 
            {
1013
 
                copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, 
1014
 
                                  c, *covers++);
1015
 
            }
1016
 
            while(--len);
1017
 
        }
1018
 
 
1019
 
        //--------------------------------------------------------------------
1020
 
        void copy_color_hspan(int x, int y,
1021
 
                              unsigned len, 
1022
 
                              const color_type* colors)
1023
 
        {
1024
 
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1025
 
            do 
1026
 
            {
1027
 
                *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
1028
 
                ++colors;
1029
 
            }
1030
 
            while(--len);
1031
 
        }
1032
 
 
1033
 
        //--------------------------------------------------------------------
1034
 
        void copy_color_vspan(int x, int y,
1035
 
                              unsigned len, 
1036
 
                              const color_type* colors)
1037
 
        {
1038
 
            do 
1039
 
            {
1040
 
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
1041
 
                *p = m_blender.make_pix(colors->r, colors->g, colors->b);
1042
 
                ++colors;
1043
 
            }
1044
 
            while(--len);
1045
 
        }
1046
 
 
1047
 
        //--------------------------------------------------------------------
1048
 
        void blend_color_hspan(int x, int y,
1049
 
                               unsigned len, 
1050
 
                               const color_type* colors,
1051
 
                               const int8u* covers,
1052
 
                               int8u cover)
1053
 
        {
1054
 
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1055
 
            do 
1056
 
            {
1057
 
                copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
1058
 
            }
1059
 
            while(--len);
1060
 
        }
1061
 
 
1062
 
        //--------------------------------------------------------------------
1063
 
        void blend_color_vspan(int x, int y,
1064
 
                               unsigned len, 
1065
 
                               const color_type* colors,
1066
 
                               const int8u* covers,
1067
 
                               int8u cover)
1068
 
        {
1069
 
            do 
1070
 
            {
1071
 
                copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, 
1072
 
                                  *colors++, covers ? *covers++ : cover);
1073
 
            }
1074
 
            while(--len);
1075
 
        }
1076
 
        
1077
 
        //--------------------------------------------------------------------
1078
 
        template<class RenBuf2>
1079
 
        void copy_from(const RenBuf2& from, 
1080
 
                       int xdst, int ydst,
1081
 
                       int xsrc, int ysrc,
1082
 
                       unsigned len)
1083
 
        {
1084
 
            const int8u* p = from.row_ptr(ysrc);
1085
 
            if(p)
1086
 
            {
1087
 
                memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
1088
 
                        p + xsrc * pix_width, 
1089
 
                        len * pix_width);
1090
 
            }
1091
 
        }
1092
 
 
1093
 
        //--------------------------------------------------------------------
1094
 
        template<class SrcPixelFormatRenderer>
1095
 
        void blend_from(const SrcPixelFormatRenderer& from, 
1096
 
                        int xdst, int ydst,
1097
 
                        int xsrc, int ysrc,
1098
 
                        unsigned len,
1099
 
                        int8u cover)
1100
 
        {
1101
 
            typedef typename SrcPixelFormatRenderer::order_type src_order;
1102
 
 
1103
 
            const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
1104
 
            if(psrc)
1105
 
            {
1106
 
                psrc += xsrc * 4;
1107
 
                pixel_type* pdst = 
1108
 
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1109
 
                do 
1110
 
                {
1111
 
                    value_type alpha = psrc[src_order::A];
1112
 
                    if(alpha)
1113
 
                    {
1114
 
                        if(alpha == base_mask && cover == 255)
1115
 
                        {
1116
 
                            *pdst = m_blender.make_pix(psrc[src_order::R], 
1117
 
                                                       psrc[src_order::G],
1118
 
                                                       psrc[src_order::B]);
1119
 
                        }
1120
 
                        else
1121
 
                        {
1122
 
                            m_blender.blend_pix(pdst, 
1123
 
                                                psrc[src_order::R],
1124
 
                                                psrc[src_order::G],
1125
 
                                                psrc[src_order::B],
1126
 
                                                alpha,
1127
 
                                                cover);
1128
 
                        }
1129
 
                    }
1130
 
                    psrc += 4;
1131
 
                    ++pdst;
1132
 
                }
1133
 
                while(--len);
1134
 
            }
1135
 
        }
1136
 
 
1137
 
        //--------------------------------------------------------------------
1138
 
        template<class SrcPixelFormatRenderer>
1139
 
        void blend_from_color(const SrcPixelFormatRenderer& from, 
1140
 
                              const color_type& color,
1141
 
                              int xdst, int ydst,
1142
 
                              int xsrc, int ysrc,
1143
 
                              unsigned len,
1144
 
                              int8u cover)
1145
 
        {
1146
 
            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
1147
 
            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
1148
 
            if(psrc)
1149
 
            {
1150
 
                pixel_type* pdst = 
1151
 
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1152
 
 
1153
 
                do 
1154
 
                {
1155
 
                    m_blender.blend_pix(pdst, 
1156
 
                                        color.r, color.g, color.b, color.a,
1157
 
                                        cover);
1158
 
                    ++psrc;
1159
 
                    ++pdst;
1160
 
                }
1161
 
                while(--len);
1162
 
            }
1163
 
        }
1164
 
 
1165
 
        //--------------------------------------------------------------------
1166
 
        template<class SrcPixelFormatRenderer>
1167
 
        void blend_from_lut(const SrcPixelFormatRenderer& from, 
1168
 
                            const color_type* color_lut,
1169
 
                            int xdst, int ydst,
1170
 
                            int xsrc, int ysrc,
1171
 
                            unsigned len,
1172
 
                            int8u cover)
1173
 
        {
1174
 
            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
1175
 
            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
1176
 
            if(psrc)
1177
 
            {
1178
 
                pixel_type* pdst = 
1179
 
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1180
 
 
1181
 
                do 
1182
 
                {
1183
 
                    const color_type& color = color_lut[*psrc];
1184
 
                    m_blender.blend_pix(pdst, 
1185
 
                                        color.r, color.g, color.b, color.a,
1186
 
                                        cover);
1187
 
                    ++psrc;
1188
 
                    ++pdst;
1189
 
                }
1190
 
                while(--len);
1191
 
            }
1192
 
        }
1193
 
 
1194
 
 
1195
 
 
1196
 
    private:
1197
 
        rbuf_type* m_rbuf;
1198
 
        Blender    m_blender;
1199
 
    };
1200
 
 
1201
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555
1202
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565
1203
 
 
1204
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
1205
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
1206
 
 
1207
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA
1208
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA
1209
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA
1210
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB
1211
 
 
1212
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
1213
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
1214
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
1215
 
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
1216
 
 
1217
 
 
1218
 
    //-----------------------------------------------------pixfmt_rgb555_gamma
1219
 
    template<class Gamma> class pixfmt_rgb555_gamma : 
1220
 
    public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, 
1221
 
                                         rendering_buffer>
1222
 
    {
1223
 
    public:
1224
 
        pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
1225
 
            pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, 
1226
 
                                          rendering_buffer>(rb) 
1227
 
        {
1228
 
            this->blender().gamma(g);
1229
 
        }
1230
 
    };
1231
 
 
1232
 
 
1233
 
    //-----------------------------------------------------pixfmt_rgb565_gamma
1234
 
    template<class Gamma> class pixfmt_rgb565_gamma : 
1235
 
    public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
1236
 
    {
1237
 
    public:
1238
 
        pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
1239
 
            pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb) 
1240
 
        {
1241
 
            this->blender().gamma(g);
1242
 
        }
1243
 
    };
1244
 
 
1245
 
 
1246
 
    //-----------------------------------------------------pixfmt_rgbAAA_gamma
1247
 
    template<class Gamma> class pixfmt_rgbAAA_gamma : 
1248
 
    public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, 
1249
 
                                         rendering_buffer>
1250
 
    {
1251
 
    public:
1252
 
        pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1253
 
            pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, 
1254
 
                                          rendering_buffer>(rb) 
1255
 
        {
1256
 
            this->blender().gamma(g);
1257
 
        }
1258
 
    };
1259
 
 
1260
 
 
1261
 
    //-----------------------------------------------------pixfmt_bgrAAA_gamma
1262
 
    template<class Gamma> class pixfmt_bgrAAA_gamma : 
1263
 
    public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, 
1264
 
                                         rendering_buffer>
1265
 
    {
1266
 
    public:
1267
 
        pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1268
 
            pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, 
1269
 
                                          rendering_buffer>(rb) 
1270
 
        {
1271
 
            this->blender().gamma(g);
1272
 
        }
1273
 
    };
1274
 
 
1275
 
 
1276
 
    //-----------------------------------------------------pixfmt_rgbBBA_gamma
1277
 
    template<class Gamma> class pixfmt_rgbBBA_gamma : 
1278
 
    public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, 
1279
 
                                         rendering_buffer>
1280
 
    {
1281
 
    public:
1282
 
        pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
1283
 
            pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, 
1284
 
                                          rendering_buffer>(rb) 
1285
 
        {
1286
 
            this->blender().gamma(g);
1287
 
        }
1288
 
    };
1289
 
 
1290
 
 
1291
 
    //-----------------------------------------------------pixfmt_bgrABB_gamma
1292
 
    template<class Gamma> class pixfmt_bgrABB_gamma : 
1293
 
    public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, 
1294
 
                                         rendering_buffer>
1295
 
    {
1296
 
    public:
1297
 
        pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
1298
 
            pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, 
1299
 
                                          rendering_buffer>(rb) 
1300
 
        {
1301
 
            this->blender().gamma(g);
1302
 
        }
1303
 
    };
1304
 
 
1305
 
 
1306
 
}
1307
 
 
1308
 
#endif
1309
 
 
 
1
//----------------------------------------------------------------------------
 
2
// Anti-Grain Geometry - Version 2.4
 
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
 
4
//
 
5
// Permission to copy, use, modify, sell and distribute this software 
 
6
// is granted provided this copyright notice appears in all copies. 
 
7
// This software is provided "as is" without express or implied
 
8
// warranty, and with no claim as to its suitability for any purpose.
 
9
//
 
10
//----------------------------------------------------------------------------
 
11
// Contact: mcseem@antigrain.com
 
12
//          mcseemagg@yahoo.com
 
13
//          http://www.antigrain.com
 
14
//----------------------------------------------------------------------------
 
15
//
 
16
// Adaptation for high precision colors has been sponsored by 
 
17
// Liberty Technology Systems, Inc., visit http://lib-sys.com
 
18
//
 
19
// Liberty Technology Systems, Inc. is the provider of
 
20
// PostScript and PDF technology for software developers.
 
21
// 
 
22
//----------------------------------------------------------------------------
 
23
 
 
24
#ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
 
25
#define AGG_PIXFMT_RGB_PACKED_INCLUDED
 
26
 
 
27
#include <string.h>
 
28
#include "agg_basics.h"
 
29
#include "agg_color_rgba.h"
 
30
#include "agg_rendering_buffer.h"
 
31
 
 
32
namespace agg
 
33
{
 
34
    //=========================================================blender_rgb555
 
35
    struct blender_rgb555
 
36
    {
 
37
        typedef rgba8 color_type;
 
38
        typedef color_type::value_type value_type;
 
39
        typedef color_type::calc_type calc_type;
 
40
        typedef int16u pixel_type;
 
41
 
 
42
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
43
                                         unsigned cr, unsigned cg, unsigned cb,
 
44
                                         unsigned alpha, 
 
45
                                         unsigned)
 
46
        {
 
47
            pixel_type rgb = *p;
 
48
            calc_type r = (rgb >> 7) & 0xF8;
 
49
            calc_type g = (rgb >> 2) & 0xF8;
 
50
            calc_type b = (rgb << 3) & 0xF8;
 
51
            *p = (pixel_type)
 
52
               (((((cr - r) * alpha + (r << 8)) >> 1)  & 0x7C00) |
 
53
                ((((cg - g) * alpha + (g << 8)) >> 6)  & 0x03E0) |
 
54
                 (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000);
 
55
        }
 
56
 
 
57
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
58
        {
 
59
            return (pixel_type)(((r & 0xF8) << 7) | 
 
60
                                ((g & 0xF8) << 2) | 
 
61
                                 (b >> 3) | 0x8000);
 
62
        }
 
63
 
 
64
        static AGG_INLINE color_type make_color(pixel_type p)
 
65
        {
 
66
            return color_type((p >> 7) & 0xF8, 
 
67
                              (p >> 2) & 0xF8, 
 
68
                              (p << 3) & 0xF8);
 
69
        }
 
70
    };
 
71
 
 
72
 
 
73
    //=====================================================blender_rgb555_pre
 
74
    struct blender_rgb555_pre
 
75
    {
 
76
        typedef rgba8 color_type;
 
77
        typedef color_type::value_type value_type;
 
78
        typedef color_type::calc_type calc_type;
 
79
        typedef int16u pixel_type;
 
80
 
 
81
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
82
                                         unsigned cr, unsigned cg, unsigned cb,
 
83
                                         unsigned alpha, 
 
84
                                         unsigned cover)
 
85
        {
 
86
            alpha = color_type::base_mask - alpha;
 
87
            pixel_type rgb = *p;
 
88
            calc_type r = (rgb >> 7) & 0xF8;
 
89
            calc_type g = (rgb >> 2) & 0xF8;
 
90
            calc_type b = (rgb << 3) & 0xF8;
 
91
            *p = (pixel_type)
 
92
               ((((r * alpha + cr * cover) >> 1)  & 0x7C00) |
 
93
                (((g * alpha + cg * cover) >> 6)  & 0x03E0) |
 
94
                 ((b * alpha + cb * cover) >> 11) | 0x8000);
 
95
        }
 
96
 
 
97
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
98
        {
 
99
            return (pixel_type)(((r & 0xF8) << 7) | 
 
100
                                ((g & 0xF8) << 2) | 
 
101
                                 (b >> 3) | 0x8000);
 
102
        }
 
103
 
 
104
        static AGG_INLINE color_type make_color(pixel_type p)
 
105
        {
 
106
            return color_type((p >> 7) & 0xF8, 
 
107
                              (p >> 2) & 0xF8, 
 
108
                              (p << 3) & 0xF8);
 
109
        }
 
110
    };
 
111
 
 
112
 
 
113
 
 
114
 
 
115
    //=====================================================blender_rgb555_gamma
 
116
    template<class Gamma> class blender_rgb555_gamma
 
117
    {
 
118
    public:
 
119
        typedef rgba8 color_type;
 
120
        typedef color_type::value_type value_type;
 
121
        typedef color_type::calc_type calc_type;
 
122
        typedef int16u pixel_type;
 
123
        typedef Gamma gamma_type;
 
124
 
 
125
        blender_rgb555_gamma() : m_gamma(0) {}
 
126
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
127
 
 
128
        AGG_INLINE void blend_pix(pixel_type* p, 
 
129
                                  unsigned cr, unsigned cg, unsigned cb,
 
130
                                  unsigned alpha, 
 
131
                                  unsigned)
 
132
        {
 
133
            pixel_type rgb = *p;
 
134
            calc_type r = m_gamma->dir((rgb >> 7) & 0xF8);
 
135
            calc_type g = m_gamma->dir((rgb >> 2) & 0xF8);
 
136
            calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
 
137
            *p = (pixel_type)
 
138
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) |
 
139
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) |
 
140
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000);
 
141
        }
 
142
 
 
143
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
144
        {
 
145
            return (pixel_type)(((r & 0xF8) << 7) | 
 
146
                                ((g & 0xF8) << 2) | 
 
147
                                 (b >> 3) | 0x8000);
 
148
        }
 
149
 
 
150
        static AGG_INLINE color_type make_color(pixel_type p)
 
151
        {
 
152
            return color_type((p >> 7) & 0xF8, 
 
153
                              (p >> 2) & 0xF8, 
 
154
                              (p << 3) & 0xF8);
 
155
        }
 
156
 
 
157
    private:
 
158
        const Gamma* m_gamma;
 
159
    };
 
160
 
 
161
 
 
162
 
 
163
 
 
164
 
 
165
    //=========================================================blender_rgb565
 
166
    struct blender_rgb565
 
167
    {
 
168
        typedef rgba8 color_type;
 
169
        typedef color_type::value_type value_type;
 
170
        typedef color_type::calc_type calc_type;
 
171
        typedef int16u pixel_type;
 
172
 
 
173
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
174
                                         unsigned cr, unsigned cg, unsigned cb,
 
175
                                         unsigned alpha, 
 
176
                                         unsigned)
 
177
        {
 
178
            pixel_type rgb = *p;
 
179
            calc_type r = (rgb >> 8) & 0xF8;
 
180
            calc_type g = (rgb >> 3) & 0xFC;
 
181
            calc_type b = (rgb << 3) & 0xF8;
 
182
            *p = (pixel_type)
 
183
               (((((cr - r) * alpha + (r << 8))     ) & 0xF800) |
 
184
                ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) |
 
185
                 (((cb - b) * alpha + (b << 8)) >> 11));
 
186
        }
 
187
 
 
188
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
189
        {
 
190
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
 
191
        }
 
192
 
 
193
        static AGG_INLINE color_type make_color(pixel_type p)
 
194
        {
 
195
            return color_type((p >> 8) & 0xF8, 
 
196
                              (p >> 3) & 0xFC, 
 
197
                              (p << 3) & 0xF8);
 
198
        }
 
199
    };
 
200
 
 
201
 
 
202
 
 
203
    //=====================================================blender_rgb565_pre
 
204
    struct blender_rgb565_pre
 
205
    {
 
206
        typedef rgba8 color_type;
 
207
        typedef color_type::value_type value_type;
 
208
        typedef color_type::calc_type calc_type;
 
209
        typedef int16u pixel_type;
 
210
 
 
211
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
212
                                         unsigned cr, unsigned cg, unsigned cb,
 
213
                                         unsigned alpha, 
 
214
                                         unsigned cover)
 
215
        {
 
216
            alpha = color_type::base_mask - alpha;
 
217
            pixel_type rgb = *p;
 
218
            calc_type r = (rgb >> 8) & 0xF8;
 
219
            calc_type g = (rgb >> 3) & 0xFC;
 
220
            calc_type b = (rgb << 3) & 0xF8;
 
221
            *p = (pixel_type)
 
222
               ((((r * alpha + cr * cover)      ) & 0xF800) |
 
223
                (((g * alpha + cg * cover) >> 5 ) & 0x07E0) |
 
224
                 ((b * alpha + cb * cover) >> 11));
 
225
        }
 
226
 
 
227
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
228
        {
 
229
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
 
230
        }
 
231
 
 
232
        static AGG_INLINE color_type make_color(pixel_type p)
 
233
        {
 
234
            return color_type((p >> 8) & 0xF8, 
 
235
                              (p >> 3) & 0xFC, 
 
236
                              (p << 3) & 0xF8);
 
237
        }
 
238
    };
 
239
 
 
240
 
 
241
 
 
242
    //=====================================================blender_rgb565_gamma
 
243
    template<class Gamma> class blender_rgb565_gamma
 
244
    {
 
245
    public:
 
246
        typedef rgba8 color_type;
 
247
        typedef color_type::value_type value_type;
 
248
        typedef color_type::calc_type calc_type;
 
249
        typedef int16u pixel_type;
 
250
        typedef Gamma gamma_type;
 
251
 
 
252
        blender_rgb565_gamma() : m_gamma(0) {}
 
253
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
254
 
 
255
        AGG_INLINE void blend_pix(pixel_type* p, 
 
256
                                  unsigned cr, unsigned cg, unsigned cb,
 
257
                                  unsigned alpha, 
 
258
                                  unsigned)
 
259
        {
 
260
            pixel_type rgb = *p;
 
261
            calc_type r = m_gamma->dir((rgb >> 8) & 0xF8);
 
262
            calc_type g = m_gamma->dir((rgb >> 3) & 0xFC);
 
263
            calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
 
264
            *p = (pixel_type)
 
265
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) |
 
266
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) |
 
267
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3));
 
268
        }
 
269
 
 
270
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
271
        {
 
272
            return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
 
273
        }
 
274
 
 
275
        static AGG_INLINE color_type make_color(pixel_type p)
 
276
        {
 
277
            return color_type((p >> 8) & 0xF8, 
 
278
                              (p >> 3) & 0xFC, 
 
279
                              (p << 3) & 0xF8);
 
280
        }
 
281
 
 
282
    private:
 
283
        const Gamma* m_gamma;
 
284
    };
 
285
 
 
286
 
 
287
 
 
288
    //=====================================================blender_rgbAAA
 
289
    struct blender_rgbAAA
 
290
    {
 
291
        typedef rgba16 color_type;
 
292
        typedef color_type::value_type value_type;
 
293
        typedef color_type::calc_type calc_type;
 
294
        typedef int32u pixel_type;
 
295
 
 
296
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
297
                                         unsigned cr, unsigned cg, unsigned cb,
 
298
                                         unsigned alpha, 
 
299
                                         unsigned)
 
300
        {
 
301
            pixel_type rgb = *p;
 
302
            calc_type r = (rgb >> 14) & 0xFFC0;
 
303
            calc_type g = (rgb >> 4)  & 0xFFC0;
 
304
            calc_type b = (rgb << 6)  & 0xFFC0;
 
305
            *p = (pixel_type)
 
306
               (((((cr - r) * alpha + (r << 16)) >> 2)  & 0x3FF00000) |
 
307
                ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
 
308
                 (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000);
 
309
        }
 
310
 
 
311
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
312
        {
 
313
            return (pixel_type)(((r & 0xFFC0) << 14) | 
 
314
                                ((g & 0xFFC0) << 4) | 
 
315
                                 (b >> 6) | 0xC0000000);
 
316
        }
 
317
 
 
318
        static AGG_INLINE color_type make_color(pixel_type p)
 
319
        {
 
320
            return color_type((p >> 14) & 0xFFC0, 
 
321
                              (p >> 4)  & 0xFFC0, 
 
322
                              (p << 6)  & 0xFFC0);
 
323
        }
 
324
    };
 
325
 
 
326
 
 
327
 
 
328
    //==================================================blender_rgbAAA_pre
 
329
    struct blender_rgbAAA_pre
 
330
    {
 
331
        typedef rgba16 color_type;
 
332
        typedef color_type::value_type value_type;
 
333
        typedef color_type::calc_type calc_type;
 
334
        typedef int32u pixel_type;
 
335
 
 
336
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
337
                                         unsigned cr, unsigned cg, unsigned cb,
 
338
                                         unsigned alpha, 
 
339
                                         unsigned cover)
 
340
        {
 
341
            alpha = color_type::base_mask - alpha;
 
342
            cover = (cover + 1) << (color_type::base_shift - 8);
 
343
            pixel_type rgb = *p;
 
344
            calc_type r = (rgb >> 14) & 0xFFC0;
 
345
            calc_type g = (rgb >> 4)  & 0xFFC0;
 
346
            calc_type b = (rgb << 6)  & 0xFFC0;
 
347
            *p = (pixel_type)
 
348
               ((((r * alpha + cr * cover) >> 2)  & 0x3FF00000) |
 
349
                (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
 
350
                 ((b * alpha + cb * cover) >> 22) | 0xC0000000);
 
351
        }
 
352
 
 
353
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
354
        {
 
355
            return (pixel_type)(((r & 0xFFC0) << 14) | 
 
356
                                ((g & 0xFFC0) << 4) | 
 
357
                                 (b >> 6) | 0xC0000000);
 
358
        }
 
359
 
 
360
        static AGG_INLINE color_type make_color(pixel_type p)
 
361
        {
 
362
            return color_type((p >> 14) & 0xFFC0, 
 
363
                              (p >> 4)  & 0xFFC0, 
 
364
                              (p << 6)  & 0xFFC0);
 
365
        }
 
366
    };
 
367
 
 
368
 
 
369
 
 
370
    //=================================================blender_rgbAAA_gamma
 
371
    template<class Gamma> class blender_rgbAAA_gamma
 
372
    {
 
373
    public:
 
374
        typedef rgba16 color_type;
 
375
        typedef color_type::value_type value_type;
 
376
        typedef color_type::calc_type calc_type;
 
377
        typedef int32u pixel_type;
 
378
        typedef Gamma gamma_type;
 
379
 
 
380
        blender_rgbAAA_gamma() : m_gamma(0) {}
 
381
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
382
 
 
383
        AGG_INLINE void blend_pix(pixel_type* p, 
 
384
                                  unsigned cr, unsigned cg, unsigned cb,
 
385
                                  unsigned alpha, 
 
386
                                  unsigned)
 
387
        {
 
388
            pixel_type rgb = *p;
 
389
            calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0);
 
390
            calc_type g = m_gamma->dir((rgb >> 4)  & 0xFFC0);
 
391
            calc_type b = m_gamma->dir((rgb << 6)  & 0xFFC0);
 
392
            *p = (pixel_type)
 
393
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) |
 
394
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
 
395
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000);
 
396
        }
 
397
 
 
398
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
399
        {
 
400
            return (pixel_type)(((r & 0xFFC0) << 14) | 
 
401
                                ((g & 0xFFC0) << 4) | 
 
402
                                 (b >> 6) | 0xC0000000);
 
403
        }
 
404
 
 
405
        static AGG_INLINE color_type make_color(pixel_type p)
 
406
        {
 
407
            return color_type((p >> 14) & 0xFFC0, 
 
408
                              (p >> 4)  & 0xFFC0, 
 
409
                              (p << 6)  & 0xFFC0);
 
410
        }
 
411
    private:
 
412
        const Gamma* m_gamma;
 
413
    };
 
414
 
 
415
 
 
416
    //=====================================================blender_bgrAAA
 
417
    struct blender_bgrAAA
 
418
    {
 
419
        typedef rgba16 color_type;
 
420
        typedef color_type::value_type value_type;
 
421
        typedef color_type::calc_type calc_type;
 
422
        typedef int32u pixel_type;
 
423
 
 
424
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
425
                                         unsigned cr, unsigned cg, unsigned cb,
 
426
                                         unsigned alpha, 
 
427
                                         unsigned)
 
428
        {
 
429
            pixel_type bgr = *p;
 
430
            calc_type b = (bgr >> 14) & 0xFFC0;
 
431
            calc_type g = (bgr >> 4)  & 0xFFC0;
 
432
            calc_type r = (bgr << 6)  & 0xFFC0;
 
433
            *p = (pixel_type)
 
434
               (((((cb - b) * alpha + (b << 16)) >> 2)  & 0x3FF00000) |
 
435
                ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
 
436
                 (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000);
 
437
        }
 
438
 
 
439
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
440
        {
 
441
            return (pixel_type)(((b & 0xFFC0) << 14) | 
 
442
                                ((g & 0xFFC0) << 4) | 
 
443
                                 (r >> 6) | 0xC0000000);
 
444
        }
 
445
 
 
446
        static AGG_INLINE color_type make_color(pixel_type p)
 
447
        {
 
448
            return color_type((p << 6)  & 0xFFC0, 
 
449
                              (p >> 4)  & 0xFFC0, 
 
450
                              (p >> 14) & 0xFFC0);
 
451
        }
 
452
    };
 
453
 
 
454
 
 
455
 
 
456
    //=================================================blender_bgrAAA_pre
 
457
    struct blender_bgrAAA_pre
 
458
    {
 
459
        typedef rgba16 color_type;
 
460
        typedef color_type::value_type value_type;
 
461
        typedef color_type::calc_type calc_type;
 
462
        typedef int32u pixel_type;
 
463
 
 
464
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
465
                                         unsigned cr, unsigned cg, unsigned cb,
 
466
                                         unsigned alpha, 
 
467
                                         unsigned cover)
 
468
        {
 
469
            alpha = color_type::base_mask - alpha;
 
470
            cover = (cover + 1) << (color_type::base_shift - 8);
 
471
            pixel_type bgr = *p;
 
472
            calc_type b = (bgr >> 14) & 0xFFC0;
 
473
            calc_type g = (bgr >> 4)  & 0xFFC0;
 
474
            calc_type r = (bgr << 6)  & 0xFFC0;
 
475
            *p = (pixel_type)
 
476
               ((((b * alpha + cb * cover) >> 2)  & 0x3FF00000) |
 
477
                (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
 
478
                 ((r * alpha + cr * cover) >> 22) | 0xC0000000);
 
479
        }
 
480
 
 
481
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
482
        {
 
483
            return (pixel_type)(((b & 0xFFC0) << 14) | 
 
484
                                ((g & 0xFFC0) << 4) | 
 
485
                                 (r >> 6) | 0xC0000000);
 
486
        }
 
487
 
 
488
        static AGG_INLINE color_type make_color(pixel_type p)
 
489
        {
 
490
            return color_type((p << 6)  & 0xFFC0, 
 
491
                              (p >> 4)  & 0xFFC0, 
 
492
                              (p >> 14) & 0xFFC0);
 
493
        }
 
494
    };
 
495
 
 
496
 
 
497
 
 
498
    //=================================================blender_bgrAAA_gamma
 
499
    template<class Gamma> class blender_bgrAAA_gamma
 
500
    {
 
501
    public:
 
502
        typedef rgba16 color_type;
 
503
        typedef color_type::value_type value_type;
 
504
        typedef color_type::calc_type calc_type;
 
505
        typedef int32u pixel_type;
 
506
        typedef Gamma gamma_type;
 
507
 
 
508
        blender_bgrAAA_gamma() : m_gamma(0) {}
 
509
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
510
 
 
511
        AGG_INLINE void blend_pix(pixel_type* p, 
 
512
                                  unsigned cr, unsigned cg, unsigned cb,
 
513
                                  unsigned alpha, 
 
514
                                  unsigned)
 
515
        {
 
516
            pixel_type bgr = *p;
 
517
            calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0);
 
518
            calc_type g = m_gamma->dir((bgr >> 4)  & 0xFFC0);
 
519
            calc_type r = m_gamma->dir((bgr << 6)  & 0xFFC0);
 
520
            *p = (pixel_type)
 
521
               (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) |
 
522
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
 
523
                 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000);
 
524
        }
 
525
 
 
526
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
527
        {
 
528
            return (pixel_type)(((b & 0xFFC0) << 14) | 
 
529
                                ((g & 0xFFC0) << 4) | 
 
530
                                 (r >> 6) | 0xC0000000);
 
531
        }
 
532
 
 
533
        static AGG_INLINE color_type make_color(pixel_type p)
 
534
        {
 
535
            return color_type((p << 6)  & 0xFFC0, 
 
536
                              (p >> 4)  & 0xFFC0, 
 
537
                              (p >> 14) & 0xFFC0);
 
538
        }
 
539
 
 
540
    private:
 
541
        const Gamma* m_gamma;
 
542
    };
 
543
 
 
544
 
 
545
 
 
546
    //=====================================================blender_rgbBBA
 
547
    struct blender_rgbBBA
 
548
    {
 
549
        typedef rgba16 color_type;
 
550
        typedef color_type::value_type value_type;
 
551
        typedef color_type::calc_type calc_type;
 
552
        typedef int32u pixel_type;
 
553
 
 
554
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
555
                                         unsigned cr, unsigned cg, unsigned cb,
 
556
                                         unsigned alpha, 
 
557
                                         unsigned)
 
558
        {
 
559
            pixel_type rgb = *p;
 
560
            calc_type r = (rgb >> 16) & 0xFFE0;
 
561
            calc_type g = (rgb >> 5)  & 0xFFE0;
 
562
            calc_type b = (rgb << 6)  & 0xFFC0;
 
563
            *p = (pixel_type)
 
564
               (((((cr - r) * alpha + (r << 16))      ) & 0xFFE00000) |
 
565
                ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) |
 
566
                 (((cb - b) * alpha + (b << 16)) >> 22));
 
567
        }
 
568
 
 
569
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
570
        {
 
571
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
 
572
        }
 
573
 
 
574
        static AGG_INLINE color_type make_color(pixel_type p)
 
575
        {
 
576
            return color_type((p >> 16) & 0xFFE0, 
 
577
                              (p >> 5)  & 0xFFE0, 
 
578
                              (p << 6)  & 0xFFC0);
 
579
        }
 
580
    };
 
581
 
 
582
 
 
583
    //=================================================blender_rgbBBA_pre
 
584
    struct blender_rgbBBA_pre
 
585
    {
 
586
        typedef rgba16 color_type;
 
587
        typedef color_type::value_type value_type;
 
588
        typedef color_type::calc_type calc_type;
 
589
        typedef int32u pixel_type;
 
590
 
 
591
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
592
                                         unsigned cr, unsigned cg, unsigned cb,
 
593
                                         unsigned alpha, 
 
594
                                         unsigned cover)
 
595
        {
 
596
            alpha = color_type::base_mask - alpha;
 
597
            cover = (cover + 1) << (color_type::base_shift - 8);
 
598
            pixel_type rgb = *p;
 
599
            calc_type r = (rgb >> 16) & 0xFFE0;
 
600
            calc_type g = (rgb >> 5)  & 0xFFE0;
 
601
            calc_type b = (rgb << 6)  & 0xFFC0;
 
602
            *p = (pixel_type)
 
603
               ((((r * alpha + cr * cover)      ) & 0xFFE00000) |
 
604
                (((g * alpha + cg * cover) >> 11) & 0x001FFC00) |
 
605
                 ((b * alpha + cb * cover) >> 22));
 
606
        }
 
607
 
 
608
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
609
        {
 
610
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
 
611
        }
 
612
 
 
613
        static AGG_INLINE color_type make_color(pixel_type p)
 
614
        {
 
615
            return color_type((p >> 16) & 0xFFE0, 
 
616
                              (p >> 5)  & 0xFFE0, 
 
617
                              (p << 6)  & 0xFFC0);
 
618
        }
 
619
    };
 
620
 
 
621
 
 
622
 
 
623
    //=================================================blender_rgbBBA_gamma
 
624
    template<class Gamma> class blender_rgbBBA_gamma
 
625
    {
 
626
    public:
 
627
        typedef rgba16 color_type;
 
628
        typedef color_type::value_type value_type;
 
629
        typedef color_type::calc_type calc_type;
 
630
        typedef int32u pixel_type;
 
631
        typedef Gamma gamma_type;
 
632
 
 
633
        blender_rgbBBA_gamma() : m_gamma(0) {}
 
634
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
635
 
 
636
        AGG_INLINE void blend_pix(pixel_type* p, 
 
637
                                  unsigned cr, unsigned cg, unsigned cb,
 
638
                                  unsigned alpha, 
 
639
                                  unsigned)
 
640
        {
 
641
            pixel_type rgb = *p;
 
642
            calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0);
 
643
            calc_type g = m_gamma->dir((rgb >> 5)  & 0xFFE0);
 
644
            calc_type b = m_gamma->dir((rgb << 6)  & 0xFFC0);
 
645
            *p = (pixel_type)
 
646
               (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) |
 
647
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) |
 
648
                 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ));
 
649
        }
 
650
 
 
651
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
652
        {
 
653
            return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
 
654
        }
 
655
 
 
656
        static AGG_INLINE color_type make_color(pixel_type p)
 
657
        {
 
658
            return color_type((p >> 16) & 0xFFE0, 
 
659
                              (p >> 5)  & 0xFFE0, 
 
660
                              (p << 6)  & 0xFFC0);
 
661
        }
 
662
 
 
663
    private:
 
664
        const Gamma* m_gamma;
 
665
    };
 
666
 
 
667
 
 
668
    //=====================================================blender_bgrABB
 
669
    struct blender_bgrABB
 
670
    {
 
671
        typedef rgba16 color_type;
 
672
        typedef color_type::value_type value_type;
 
673
        typedef color_type::calc_type calc_type;
 
674
        typedef int32u pixel_type;
 
675
 
 
676
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
677
                                         unsigned cr, unsigned cg, unsigned cb,
 
678
                                         unsigned alpha, 
 
679
                                         unsigned)
 
680
        {
 
681
            pixel_type bgr = *p;
 
682
            calc_type b = (bgr >> 16) & 0xFFC0;
 
683
            calc_type g = (bgr >> 6)  & 0xFFE0;
 
684
            calc_type r = (bgr << 5)  & 0xFFE0;
 
685
            *p = (pixel_type)
 
686
               (((((cb - b) * alpha + (b << 16))      ) & 0xFFC00000) |
 
687
                ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) |
 
688
                 (((cr - r) * alpha + (r << 16)) >> 21));
 
689
        }
 
690
 
 
691
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
692
        {
 
693
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
 
694
        }
 
695
 
 
696
        static AGG_INLINE color_type make_color(pixel_type p)
 
697
        {
 
698
            return color_type((p << 5)  & 0xFFE0,
 
699
                              (p >> 6)  & 0xFFE0, 
 
700
                              (p >> 16) & 0xFFC0);
 
701
        }
 
702
    };
 
703
 
 
704
 
 
705
    //=================================================blender_bgrABB_pre
 
706
    struct blender_bgrABB_pre
 
707
    {
 
708
        typedef rgba16 color_type;
 
709
        typedef color_type::value_type value_type;
 
710
        typedef color_type::calc_type calc_type;
 
711
        typedef int32u pixel_type;
 
712
 
 
713
        static AGG_INLINE void blend_pix(pixel_type* p, 
 
714
                                         unsigned cr, unsigned cg, unsigned cb,
 
715
                                         unsigned alpha, 
 
716
                                         unsigned cover)
 
717
        {
 
718
            alpha = color_type::base_mask - alpha;
 
719
            cover = (cover + 1) << (color_type::base_shift - 8);
 
720
            pixel_type bgr = *p;
 
721
            calc_type b = (bgr >> 16) & 0xFFC0;
 
722
            calc_type g = (bgr >> 6)  & 0xFFE0;
 
723
            calc_type r = (bgr << 5)  & 0xFFE0;
 
724
            *p = (pixel_type)
 
725
               ((((b * alpha + cb * cover)      ) & 0xFFC00000) |
 
726
                (((g * alpha + cg * cover) >> 10) & 0x003FF800) |
 
727
                 ((r * alpha + cr * cover) >> 21));
 
728
        }
 
729
 
 
730
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
731
        {
 
732
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
 
733
        }
 
734
 
 
735
        static AGG_INLINE color_type make_color(pixel_type p)
 
736
        {
 
737
            return color_type((p << 5)  & 0xFFE0,
 
738
                              (p >> 6)  & 0xFFE0, 
 
739
                              (p >> 16) & 0xFFC0);
 
740
        }
 
741
    };
 
742
 
 
743
 
 
744
 
 
745
    //=================================================blender_bgrABB_gamma
 
746
    template<class Gamma> class blender_bgrABB_gamma
 
747
    {
 
748
    public:
 
749
        typedef rgba16 color_type;
 
750
        typedef color_type::value_type value_type;
 
751
        typedef color_type::calc_type calc_type;
 
752
        typedef int32u pixel_type;
 
753
        typedef Gamma gamma_type;
 
754
 
 
755
        blender_bgrABB_gamma() : m_gamma(0) {}
 
756
        void gamma(const gamma_type& g) { m_gamma = &g; }
 
757
 
 
758
        AGG_INLINE void blend_pix(pixel_type* p, 
 
759
                                  unsigned cr, unsigned cg, unsigned cb,
 
760
                                  unsigned alpha, 
 
761
                                  unsigned)
 
762
        {
 
763
            pixel_type bgr = *p;
 
764
            calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0);
 
765
            calc_type g = m_gamma->dir((bgr >> 6)  & 0xFFE0);
 
766
            calc_type r = m_gamma->dir((bgr << 5)  & 0xFFE0);
 
767
            *p = (pixel_type)
 
768
               (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) |
 
769
                ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) |
 
770
                 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 ));
 
771
        }
 
772
 
 
773
        static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
 
774
        {
 
775
            return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
 
776
        }
 
777
 
 
778
        static AGG_INLINE color_type make_color(pixel_type p)
 
779
        {
 
780
            return color_type((p << 5)  & 0xFFE0,
 
781
                              (p >> 6)  & 0xFFE0, 
 
782
                              (p >> 16) & 0xFFC0);
 
783
        }
 
784
 
 
785
    private:
 
786
        const Gamma* m_gamma;
 
787
    };
 
788
 
 
789
 
 
790
    
 
791
    //===========================================pixfmt_alpha_blend_rgb_packed
 
792
    template<class Blender,  class RenBuf> class pixfmt_alpha_blend_rgb_packed
 
793
    {
 
794
    public:
 
795
        typedef RenBuf   rbuf_type;
 
796
        typedef typename rbuf_type::row_data row_data;
 
797
        typedef Blender  blender_type;
 
798
        typedef typename blender_type::color_type color_type;
 
799
        typedef typename blender_type::pixel_type pixel_type;
 
800
        typedef int                               order_type; // A fake one
 
801
        typedef typename color_type::value_type   value_type;
 
802
        typedef typename color_type::calc_type    calc_type;
 
803
        enum base_scale_e 
 
804
        {
 
805
            base_shift = color_type::base_shift,
 
806
            base_scale = color_type::base_scale,
 
807
            base_mask  = color_type::base_mask,
 
808
            pix_width  = sizeof(pixel_type),
 
809
        };
 
810
 
 
811
    private:
 
812
        //--------------------------------------------------------------------
 
813
        AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
 
814
        {
 
815
            if (c.a)
 
816
            {
 
817
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
 
818
                if(alpha == base_mask)
 
819
                {
 
820
                    *p = m_blender.make_pix(c.r, c.g, c.b);
 
821
                }
 
822
                else
 
823
                {
 
824
                    m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
 
825
                }
 
826
            }
 
827
        }
 
828
 
 
829
    public:
 
830
        //--------------------------------------------------------------------
 
831
        explicit pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {}
 
832
        void attach(rbuf_type& rb) { m_rbuf = &rb; }
 
833
 
 
834
        //--------------------------------------------------------------------
 
835
        template<class PixFmt>
 
836
        bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
 
837
        {
 
838
            rect_i r(x1, y1, x2, y2);
 
839
            if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
 
840
            {
 
841
                int stride = pixf.stride();
 
842
                m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 
 
843
                               (r.x2 - r.x1) + 1,
 
844
                               (r.y2 - r.y1) + 1,
 
845
                               stride);
 
846
                return true;
 
847
            }
 
848
            return false;
 
849
        }
 
850
 
 
851
        Blender& blender() { return m_blender; }
 
852
 
 
853
        //--------------------------------------------------------------------
 
854
        AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
 
855
        AGG_INLINE unsigned height() const { return m_rbuf->height(); }
 
856
        AGG_INLINE int      stride() const { return m_rbuf->stride(); }
 
857
 
 
858
        //--------------------------------------------------------------------
 
859
        AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
 
860
        AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
 
861
        AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
 
862
 
 
863
        //--------------------------------------------------------------------
 
864
        AGG_INLINE int8u* pix_ptr(int x, int y)
 
865
        {
 
866
            return m_rbuf->row_ptr(y) + x * pix_width;
 
867
        }
 
868
 
 
869
        AGG_INLINE const int8u* pix_ptr(int x, int y) const
 
870
        {
 
871
            return m_rbuf->row_ptr(y) + x * pix_width;
 
872
        }
 
873
 
 
874
        //--------------------------------------------------------------------
 
875
        AGG_INLINE void make_pix(int8u* p, const color_type& c)
 
876
        {
 
877
            *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
 
878
        }
 
879
 
 
880
        //--------------------------------------------------------------------
 
881
        AGG_INLINE color_type pixel(int x, int y) const
 
882
        {
 
883
            return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]);
 
884
        }
 
885
 
 
886
        //--------------------------------------------------------------------
 
887
        AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
 
888
        {
 
889
            ((pixel_type*)
 
890
                m_rbuf->row_ptr(x, y, 1))[x] = 
 
891
                    m_blender.make_pix(c.r, c.g, c.b);
 
892
        }
 
893
 
 
894
        //--------------------------------------------------------------------
 
895
        AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
 
896
        {
 
897
            copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover);
 
898
        }
 
899
 
 
900
        //--------------------------------------------------------------------
 
901
        AGG_INLINE void copy_hline(int x, int y, 
 
902
                                   unsigned len, 
 
903
                                   const color_type& c)
 
904
        {
 
905
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
 
906
            pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
 
907
            do
 
908
            {
 
909
                *p++ = v;
 
910
            }
 
911
            while(--len);
 
912
        }
 
913
 
 
914
        //--------------------------------------------------------------------
 
915
        AGG_INLINE void copy_vline(int x, int y,
 
916
                                   unsigned len, 
 
917
                                   const color_type& c)
 
918
        {
 
919
            pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
 
920
            do
 
921
            {
 
922
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
 
923
                *p = v;
 
924
            }
 
925
            while(--len);
 
926
        }
 
927
 
 
928
        //--------------------------------------------------------------------
 
929
        void blend_hline(int x, int y,
 
930
                         unsigned len, 
 
931
                         const color_type& c,
 
932
                         int8u cover)
 
933
        {
 
934
            if (c.a)
 
935
            {
 
936
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
 
937
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
 
938
                if(alpha == base_mask)
 
939
                {
 
940
                    pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
 
941
                    do
 
942
                    {
 
943
                        *p++ = v;
 
944
                    }
 
945
                    while(--len);
 
946
                }
 
947
                else
 
948
                {
 
949
                    do
 
950
                    {
 
951
                        m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
 
952
                        ++p;
 
953
                    }
 
954
                    while(--len);
 
955
                }
 
956
            }
 
957
        }
 
958
 
 
959
        //--------------------------------------------------------------------
 
960
        void blend_vline(int x, int y,
 
961
                         unsigned len, 
 
962
                         const color_type& c,
 
963
                         int8u cover)
 
964
        {
 
965
            if (c.a)
 
966
            {
 
967
                calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
 
968
                if(alpha == base_mask)
 
969
                {
 
970
                    pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
 
971
                    do
 
972
                    {
 
973
                        ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
 
974
                    }
 
975
                    while(--len);
 
976
                }
 
977
                else
 
978
                {
 
979
                    do
 
980
                    {
 
981
                        m_blender.blend_pix(
 
982
                            (pixel_type*)m_rbuf->row_ptr(x, y++, 1), 
 
983
                            c.r, c.g, c.b, alpha, cover);
 
984
                    }
 
985
                    while(--len);
 
986
                }
 
987
            }
 
988
        }
 
989
 
 
990
        //--------------------------------------------------------------------
 
991
        void blend_solid_hspan(int x, int y,
 
992
                               unsigned len, 
 
993
                               const color_type& c,
 
994
                               const int8u* covers)
 
995
        {
 
996
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
 
997
            do 
 
998
            {
 
999
                copy_or_blend_pix(p, c, *covers++);
 
1000
                ++p;
 
1001
            }
 
1002
            while(--len);
 
1003
        }
 
1004
 
 
1005
        //--------------------------------------------------------------------
 
1006
        void blend_solid_vspan(int x, int y,
 
1007
                               unsigned len, 
 
1008
                               const color_type& c,
 
1009
                               const int8u* covers)
 
1010
        {
 
1011
            do 
 
1012
            {
 
1013
                copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, 
 
1014
                                  c, *covers++);
 
1015
            }
 
1016
            while(--len);
 
1017
        }
 
1018
 
 
1019
        //--------------------------------------------------------------------
 
1020
        void copy_color_hspan(int x, int y,
 
1021
                              unsigned len, 
 
1022
                              const color_type* colors)
 
1023
        {
 
1024
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
 
1025
            do 
 
1026
            {
 
1027
                *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
 
1028
                ++colors;
 
1029
            }
 
1030
            while(--len);
 
1031
        }
 
1032
 
 
1033
        //--------------------------------------------------------------------
 
1034
        void copy_color_vspan(int x, int y,
 
1035
                              unsigned len, 
 
1036
                              const color_type* colors)
 
1037
        {
 
1038
            do 
 
1039
            {
 
1040
                pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
 
1041
                *p = m_blender.make_pix(colors->r, colors->g, colors->b);
 
1042
                ++colors;
 
1043
            }
 
1044
            while(--len);
 
1045
        }
 
1046
 
 
1047
        //--------------------------------------------------------------------
 
1048
        void blend_color_hspan(int x, int y,
 
1049
                               unsigned len, 
 
1050
                               const color_type* colors,
 
1051
                               const int8u* covers,
 
1052
                               int8u cover)
 
1053
        {
 
1054
            pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
 
1055
            do 
 
1056
            {
 
1057
                copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
 
1058
            }
 
1059
            while(--len);
 
1060
        }
 
1061
 
 
1062
        //--------------------------------------------------------------------
 
1063
        void blend_color_vspan(int x, int y,
 
1064
                               unsigned len, 
 
1065
                               const color_type* colors,
 
1066
                               const int8u* covers,
 
1067
                               int8u cover)
 
1068
        {
 
1069
            do 
 
1070
            {
 
1071
                copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, 
 
1072
                                  *colors++, covers ? *covers++ : cover);
 
1073
            }
 
1074
            while(--len);
 
1075
        }
 
1076
        
 
1077
        //--------------------------------------------------------------------
 
1078
        template<class RenBuf2>
 
1079
        void copy_from(const RenBuf2& from, 
 
1080
                       int xdst, int ydst,
 
1081
                       int xsrc, int ysrc,
 
1082
                       unsigned len)
 
1083
        {
 
1084
            const int8u* p = from.row_ptr(ysrc);
 
1085
            if(p)
 
1086
            {
 
1087
                memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 
 
1088
                        p + xsrc * pix_width, 
 
1089
                        len * pix_width);
 
1090
            }
 
1091
        }
 
1092
 
 
1093
        //--------------------------------------------------------------------
 
1094
        template<class SrcPixelFormatRenderer>
 
1095
        void blend_from(const SrcPixelFormatRenderer& from, 
 
1096
                        int xdst, int ydst,
 
1097
                        int xsrc, int ysrc,
 
1098
                        unsigned len,
 
1099
                        int8u cover)
 
1100
        {
 
1101
            typedef typename SrcPixelFormatRenderer::order_type src_order;
 
1102
 
 
1103
            const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
 
1104
            if(psrc)
 
1105
            {
 
1106
                psrc += xsrc * 4;
 
1107
                pixel_type* pdst = 
 
1108
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
 
1109
                do 
 
1110
                {
 
1111
                    value_type alpha = psrc[src_order::A];
 
1112
                    if(alpha)
 
1113
                    {
 
1114
                        if(alpha == base_mask && cover == 255)
 
1115
                        {
 
1116
                            *pdst = m_blender.make_pix(psrc[src_order::R], 
 
1117
                                                       psrc[src_order::G],
 
1118
                                                       psrc[src_order::B]);
 
1119
                        }
 
1120
                        else
 
1121
                        {
 
1122
                            m_blender.blend_pix(pdst, 
 
1123
                                                psrc[src_order::R],
 
1124
                                                psrc[src_order::G],
 
1125
                                                psrc[src_order::B],
 
1126
                                                alpha,
 
1127
                                                cover);
 
1128
                        }
 
1129
                    }
 
1130
                    psrc += 4;
 
1131
                    ++pdst;
 
1132
                }
 
1133
                while(--len);
 
1134
            }
 
1135
        }
 
1136
 
 
1137
        //--------------------------------------------------------------------
 
1138
        template<class SrcPixelFormatRenderer>
 
1139
        void blend_from_color(const SrcPixelFormatRenderer& from, 
 
1140
                              const color_type& color,
 
1141
                              int xdst, int ydst,
 
1142
                              int xsrc, int ysrc,
 
1143
                              unsigned len,
 
1144
                              int8u cover)
 
1145
        {
 
1146
            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
 
1147
            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
 
1148
            if(psrc)
 
1149
            {
 
1150
                psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
 
1151
                pixel_type* pdst = 
 
1152
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
 
1153
 
 
1154
                do 
 
1155
                {
 
1156
                    m_blender.blend_pix(pdst, 
 
1157
                                        color.r, color.g, color.b, color.a,
 
1158
                                        cover);
 
1159
                    psrc += SrcPixelFormatRenderer::pix_step;
 
1160
                    ++pdst;
 
1161
                }
 
1162
                while(--len);
 
1163
            }
 
1164
        }
 
1165
 
 
1166
        //--------------------------------------------------------------------
 
1167
        template<class SrcPixelFormatRenderer>
 
1168
        void blend_from_lut(const SrcPixelFormatRenderer& from, 
 
1169
                            const color_type* color_lut,
 
1170
                            int xdst, int ydst,
 
1171
                            int xsrc, int ysrc,
 
1172
                            unsigned len,
 
1173
                            int8u cover)
 
1174
        {
 
1175
            typedef typename SrcPixelFormatRenderer::value_type src_value_type;
 
1176
            const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
 
1177
            if(psrc)
 
1178
            {
 
1179
                psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
 
1180
                pixel_type* pdst = 
 
1181
                    (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
 
1182
 
 
1183
                do 
 
1184
                {
 
1185
                    const color_type& color = color_lut[*psrc];
 
1186
                    m_blender.blend_pix(pdst, 
 
1187
                                        color.r, color.g, color.b, color.a,
 
1188
                                        cover);
 
1189
                    psrc += SrcPixelFormatRenderer::pix_step;
 
1190
                    ++pdst;
 
1191
                }
 
1192
                while(--len);
 
1193
            }
 
1194
        }
 
1195
 
 
1196
 
 
1197
 
 
1198
    private:
 
1199
        rbuf_type* m_rbuf;
 
1200
        Blender    m_blender;
 
1201
    };
 
1202
 
 
1203
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555
 
1204
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565
 
1205
 
 
1206
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
 
1207
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
 
1208
 
 
1209
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA
 
1210
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA
 
1211
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA
 
1212
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB
 
1213
 
 
1214
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
 
1215
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
 
1216
    typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
 
1217
    typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
 
1218
 
 
1219
 
 
1220
    //-----------------------------------------------------pixfmt_rgb555_gamma
 
1221
    template<class Gamma> class pixfmt_rgb555_gamma : 
 
1222
    public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, 
 
1223
                                         rendering_buffer>
 
1224
    {
 
1225
    public:
 
1226
        pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
 
1227
            pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, 
 
1228
                                          rendering_buffer>(rb) 
 
1229
        {
 
1230
            this->blender().gamma(g);
 
1231
        }
 
1232
    };
 
1233
 
 
1234
 
 
1235
    //-----------------------------------------------------pixfmt_rgb565_gamma
 
1236
    template<class Gamma> class pixfmt_rgb565_gamma : 
 
1237
    public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
 
1238
    {
 
1239
    public:
 
1240
        pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
 
1241
            pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb) 
 
1242
        {
 
1243
            this->blender().gamma(g);
 
1244
        }
 
1245
    };
 
1246
 
 
1247
 
 
1248
    //-----------------------------------------------------pixfmt_rgbAAA_gamma
 
1249
    template<class Gamma> class pixfmt_rgbAAA_gamma : 
 
1250
    public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, 
 
1251
                                         rendering_buffer>
 
1252
    {
 
1253
    public:
 
1254
        pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
 
1255
            pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, 
 
1256
                                          rendering_buffer>(rb) 
 
1257
        {
 
1258
            this->blender().gamma(g);
 
1259
        }
 
1260
    };
 
1261
 
 
1262
 
 
1263
    //-----------------------------------------------------pixfmt_bgrAAA_gamma
 
1264
    template<class Gamma> class pixfmt_bgrAAA_gamma : 
 
1265
    public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, 
 
1266
                                         rendering_buffer>
 
1267
    {
 
1268
    public:
 
1269
        pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
 
1270
            pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, 
 
1271
                                          rendering_buffer>(rb) 
 
1272
        {
 
1273
            this->blender().gamma(g);
 
1274
        }
 
1275
    };
 
1276
 
 
1277
 
 
1278
    //-----------------------------------------------------pixfmt_rgbBBA_gamma
 
1279
    template<class Gamma> class pixfmt_rgbBBA_gamma : 
 
1280
    public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, 
 
1281
                                         rendering_buffer>
 
1282
    {
 
1283
    public:
 
1284
        pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
 
1285
            pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, 
 
1286
                                          rendering_buffer>(rb) 
 
1287
        {
 
1288
            this->blender().gamma(g);
 
1289
        }
 
1290
    };
 
1291
 
 
1292
 
 
1293
    //-----------------------------------------------------pixfmt_bgrABB_gamma
 
1294
    template<class Gamma> class pixfmt_bgrABB_gamma : 
 
1295
    public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, 
 
1296
                                         rendering_buffer>
 
1297
    {
 
1298
    public:
 
1299
        pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
 
1300
            pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, 
 
1301
                                          rendering_buffer>(rb) 
 
1302
        {
 
1303
            this->blender().gamma(g);
 
1304
        }
 
1305
    };
 
1306
 
 
1307
 
 
1308
}
 
1309
 
 
1310
#endif
 
1311