1 /* 2 * Copyright 2014, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 6 * 7 * Class clipped_alpha_mask, a modified version of alpha_mask_u8 that can 8 * offset the mask, and has a controllable value for the area outside it. 9 */ 10 11 #ifndef AGG_CLIPED_ALPHA_MASK_INCLUDED 12 #define AGG_CLIPED_ALPHA_MASK_INCLUDED 13 14 15 #include <agg_alpha_mask_u8.h> 16 #include <agg_rendering_buffer.h> 17 18 19 namespace agg 20 { 21 class clipped_alpha_mask 22 { 23 public: 24 typedef int8u cover_type; 25 enum cover_scale_e 26 { 27 cover_shift = 8, 28 cover_none = 0, 29 cover_full = 255 30 }; 31 32 clipped_alpha_mask() 33 : m_xOffset(0), m_yOffset(0), m_rbuf(0), m_outside(0) {} 34 clipped_alpha_mask(rendering_buffer& rbuf) 35 : m_xOffset(0), m_yOffset(0), m_rbuf(&rbuf), m_outside(0) {} 36 37 void attach(rendering_buffer& rbuf, int x, int y, int8u outside) 38 { 39 m_rbuf = &rbuf; 40 m_xOffset = x; 41 m_yOffset = y; 42 m_outside = outside; 43 } 44 45 void combine_hspan(int x, int y, cover_type* dst, int num_pix) const 46 { 47 x -= m_xOffset; 48 y -= m_yOffset; 49 50 int xmax = m_rbuf->width() - 1; 51 int ymax = m_rbuf->height() - 1; 52 53 int count = num_pix; 54 cover_type* covers = dst; 55 56 if(y < 0 || y > ymax) 57 { 58 memset(dst, m_outside, num_pix * sizeof(cover_type)); 59 return; 60 } 61 62 if(x < 0) 63 { 64 count += x; 65 if(count <= 0) 66 { 67 memset(dst, m_outside, num_pix * sizeof(cover_type)); 68 return; 69 } 70 memset(covers, m_outside, -x * sizeof(cover_type)); 71 covers -= x; 72 x = 0; 73 } 74 75 if(x + count > xmax) 76 { 77 int rest = x + count - xmax - 1; 78 count -= rest; 79 if(count <= 0) 80 { 81 memset(dst, m_outside, num_pix * sizeof(cover_type)); 82 return; 83 } 84 memset(covers + count, m_outside, rest * sizeof(cover_type)); 85 } 86 87 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 88 do 89 { 90 *covers = (cover_type)((cover_full + (*covers) * (*mask)) 91 >> cover_shift); 92 ++covers; 93 mask += Step; 94 } 95 while(--count); 96 } 97 98 private: 99 int m_xOffset; 100 int m_yOffset; 101 102 rendering_buffer* m_rbuf; 103 int8u m_outside; 104 105 static const int Step = 1; 106 static const int Offset = 0; 107 }; 108 } 109 110 111 #endif 112