1 /* 2 * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Base class for different drawing modes. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_H 10 #define DRAWING_MODE_H 11 12 #include "PatternHandler.h" 13 #include "PixelFormat.h" 14 15 class PatternHandler; 16 17 typedef PixelFormat::color_type color_type; 18 typedef PixelFormat::agg_buffer agg_buffer; 19 20 union pixel32 { 21 uint32 data32; 22 uint8 data8[4]; 23 }; 24 25 // BLEND 26 // 27 // This macro assumes source alpha in range 0..255 and 28 // ignores dest alpha (is assumed to equal 255). 29 // TODO: We need the assignment of alpha only when drawing into bitmaps! 30 #define BLEND(d, r, g, b, a) \ 31 { \ 32 pixel32 _p; \ 33 _p.data32 = *(uint32*)d; \ 34 d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \ 35 d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \ 36 d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \ 37 d[3] = 255; \ 38 } 39 40 // BLEND_FROM 41 // 42 // This macro assumes source alpha in range 0..255 and 43 // ignores dest alpha (is assumed to equal 255). 44 // It uses two colors for the blending (f and s) and writes 45 // the result into a third color (d). 46 // TODO: We need the assignment of alpha only when drawing into bitmaps! 47 #define BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a) \ 48 { \ 49 d[0] = (((((b2) - (b1)) * (a)) + ((b1) << 8)) >> 8); \ 50 d[1] = (((((g2) - (g1)) * (a)) + ((g1) << 8)) >> 8); \ 51 d[2] = (((((r2) - (r1)) * (a)) + ((r1) << 8)) >> 8); \ 52 d[3] = 255; \ 53 } 54 55 // BLEND16 56 // 57 // This macro assumes source alpha in range 0..65025 and 58 // ignores dest alpha (is assumed to equal 255). 59 // TODO: We need the assignment of alpha only when drawing into bitmaps! 60 // BLEND16 61 #define BLEND16(d, r, g, b, a) \ 62 { \ 63 pixel32 _p; \ 64 _p.data32 = *(uint32*)d; \ 65 d[0] = (((((b) - _p.data8[0]) * (a)) + (_p.data8[0] << 16)) >> 16); \ 66 d[1] = (((((g) - _p.data8[1]) * (a)) + (_p.data8[1] << 16)) >> 16); \ 67 d[2] = (((((r) - _p.data8[2]) * (a)) + (_p.data8[2] << 16)) >> 16); \ 68 d[3] = 255; \ 69 } 70 71 72 73 // BLEND_COMPOSITE 74 // 75 // This macro assumes source alpha in range 0..255 and 76 // composes the source color over a possibly semi-transparent background. 77 #define BLEND_COMPOSITE(d, r, g, b, a) \ 78 { \ 79 pixel32 _p; \ 80 _p.data32 = *(uint32*)d; \ 81 if (_p.data8[3] == 255) { \ 82 BLEND(d, r, g, b, a); \ 83 } else { \ 84 uint8 alphaRest = 255 - (a); \ 85 uint32 alphaTemp = (65025 - alphaRest * (255 - _p.data8[3])); \ 86 uint32 alphaDest = _p.data8[3] * alphaRest; \ 87 uint32 alphaSrc = 255 * (a); \ 88 d[0] = (_p.data8[0] * alphaDest + (b) * alphaSrc) / alphaTemp; \ 89 d[1] = (_p.data8[1] * alphaDest + (g) * alphaSrc) / alphaTemp; \ 90 d[2] = (_p.data8[2] * alphaDest + (r) * alphaSrc) / alphaTemp; \ 91 d[3] = alphaTemp >> 8; \ 92 } \ 93 } 94 95 // BLEND_COMPOSITE16 96 // 97 // This macro assumes source alpha in range 0..65025 and 98 // composes the source color over a possibly semi-transparent background. 99 // TODO: implement a faster version 100 #define BLEND_COMPOSITE16(d, r, g, b, a) \ 101 { \ 102 BLEND_COMPOSITE(d, r, g, b, (a) >> 8); \ 103 } 104 105 106 #endif // DRAWING_MODE_H 107 108