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