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