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 <stdio.h> 13 #include <string.h> 14 #include <agg_basics.h> 15 #include <agg_color_rgba8.h> 16 #include <agg_rendering_buffer.h> 17 18 class PatternHandler; 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(d1, d2, d3, da, s1, s2, s3, a) \ 31 { \ 32 (d1) = (((((s1) - (d1)) * (a)) + ((d1) << 8)) >> 8); \ 33 (d2) = (((((s2) - (d2)) * (a)) + ((d2) << 8)) >> 8); \ 34 (d3) = (((((s3) - (d3)) * (a)) + ((d3) << 8)) >> 8); \ 35 (da) = max_c((da), (a)); \ 36 } 37 38 // BLEND_FROM 39 // 40 // This macro assumes source alpha in range 0..255 and 41 // ignores dest alpha (is assumed to equal 255). 42 // It uses two colors for the blending (f and s) and writes 43 // the result into a third color (d). 44 // TODO: We need the assignment of alpha only when drawing into bitmaps! 45 #define BLEND_FROM(d1, d2, d3, da, f1, f2, f3, s1, s2, s3, a) \ 46 { \ 47 (d1) = (((((s1) - (f1)) * (a)) + ((f1) << 8)) >> 8); \ 48 (d2) = (((((s2) - (f2)) * (a)) + ((f2) << 8)) >> 8); \ 49 (d3) = (((((s3) - (f3)) * (a)) + ((f3) << 8)) >> 8); \ 50 (da) = max_c((da), (a)); \ 51 } 52 53 // BLEND16 54 // 55 // This macro assumes source alpha in range 0..65025 and 56 // ignores dest alpha (is assumed to equal 255). 57 // TODO: We need the assignment of alpha only when drawing into bitmaps! 58 #define BLEND16(d1, d2, d3, da, s1, s2, s3, a) \ 59 { \ 60 (d1) = (((((s1) - (d1)) * (a)) + ((d1) << 16)) >> 16); \ 61 (d2) = (((((s2) - (d2)) * (a)) + ((d2) << 16)) >> 16); \ 62 (d3) = (((((s3) - (d3)) * (a)) + ((d3) << 16)) >> 16); \ 63 (da) = max_c((da), (a) >> 8); \ 64 } 65 66 // BLEND_COMPOSITE 67 // 68 // This macro assumes source alpha in range 0..255 and 69 // composes the source color over a possibly semi-transparent background. 70 #define BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, a) \ 71 { \ 72 if ((da) == 255) { \ 73 BLEND(d1, d2, d3, da, s1, s2, s3, a); \ 74 } else { \ 75 uint8 alphaRest = 255 - (a); \ 76 uint32 alphaTemp = (65025 - alphaRest * (255 - (da))); \ 77 uint32 alphaDest = (da) * alphaRest; \ 78 uint32 alphaSrc = 255 * (a); \ 79 (d1) = ((d1) * alphaDest + (s2) * alphaSrc) / alphaTemp; \ 80 (d2) = ((d2) * alphaDest + (s2) * alphaSrc) / alphaTemp; \ 81 (d3) = ((d3) * alphaDest + (s3) * alphaSrc) / alphaTemp; \ 82 (da) = alphaTemp >> 8; \ 83 } \ 84 } 85 86 // BLEND_COMPOSITE16 87 // 88 // This macro assumes source alpha in range 0..65025 and 89 // composes the source color over a possibly semi-transparent background. 90 // TODO: implement a faster version 91 #define BLEND_COMPOSITE16(d1, d2, d3, da, s1, s2, s3, a) \ 92 { \ 93 BLEND_COMPOSITE(d1, d2, d3, da, s1, s2, s3, (a) >> 8); \ 94 } 95 96 class DrawingMode { 97 public: 98 typedef agg::rgba8 color_type; 99 100 // constructor 101 DrawingMode() 102 : fBuffer(NULL) 103 { 104 } 105 106 // destructor 107 virtual ~DrawingMode() 108 { 109 } 110 111 // set_rendering_buffer 112 void set_rendering_buffer(agg::rendering_buffer* buffer) 113 { 114 fBuffer = buffer; 115 } 116 117 // set_pattern_handler 118 void set_pattern_handler(const PatternHandler* handler) 119 { 120 fPatternHandler = handler; 121 } 122 123 virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) = 0; 124 125 virtual void blend_hline(int x, int y, unsigned len, 126 const color_type& c, uint8 cover) = 0; 127 128 virtual void blend_vline(int x, int y, unsigned len, 129 const color_type& c, uint8 cover) = 0; 130 131 virtual void blend_solid_hspan(int x, int y, unsigned len, 132 const color_type& c, const uint8* covers) = 0; 133 134 virtual void blend_solid_vspan(int x, int y, unsigned len, 135 const color_type& c, const uint8* covers) = 0; 136 137 virtual void blend_color_hspan(int x, int y, unsigned len, 138 const color_type* colors, 139 const uint8* covers, 140 uint8 cover) = 0; 141 142 virtual void blend_color_vspan(int x, int y, unsigned len, 143 const color_type* colors, 144 const uint8* covers, 145 uint8 cover) = 0; 146 147 protected: 148 agg::rendering_buffer* fBuffer; 149 const PatternHandler* fPatternHandler; 150 151 152 }; 153 154 #endif // DRAWING_MODE_H 155 156