1 /* 2 * Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 * 5 * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 6 * 7 * 8 * Class scanline_p8_subpix_avrg_filtering, a slightly modified version of 9 * scanline_p8 customized to store 3 covers per pixel 10 * 11 */ 12 13 #ifndef AGG_SCANLINE_P_SUBPIX_INCLUDED 14 #define AGG_SCANLINE_P_SUBPIX_INCLUDED 15 16 #include "agg_array.h" 17 18 namespace agg 19 { 20 21 //======================================================scanline_p8_subpix 22 // 23 // This is a general purpose scaline container which supports the interface 24 // used in the rasterizer::render(). See description of scanline_u8 25 // for details. 26 // 27 //------------------------------------------------------------------------ 28 class scanline_p8_subpix 29 { 30 public: 31 typedef scanline_p8_subpix self_type; 32 typedef int8u cover_type; 33 typedef int16 coord_type; 34 35 //-------------------------------------------------------------------- 36 struct span 37 { 38 coord_type x; 39 coord_type len; // If negative, it's a solid span, covers is valid 40 const cover_type* covers; 41 }; 42 43 typedef span* iterator; 44 typedef const span* const_iterator; 45 scanline_p8_subpix()46 scanline_p8_subpix() : 47 m_last_x(0x7FFFFFF0), 48 m_covers(), 49 m_cover_ptr(0), 50 m_spans(), 51 m_cur_span(0) 52 { 53 } 54 55 //-------------------------------------------------------------------- reset(int min_x,int max_x)56 void reset(int min_x, int max_x) 57 { 58 unsigned max_len = 3*(max_x - min_x + 3); 59 if(max_len > m_spans.size()) 60 { 61 m_spans.resize(max_len); 62 m_covers.resize(max_len); 63 } 64 m_last_x = 0x7FFFFFF0; 65 m_cover_ptr = &m_covers[0]; 66 m_cur_span = &m_spans[0]; 67 m_cur_span->len = 0; 68 } 69 70 //-------------------------------------------------------------------- add_cell(int x,unsigned cover1,unsigned cover2,unsigned cover3)71 void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3) 72 { 73 m_cover_ptr[0] = (cover_type)cover1; 74 m_cover_ptr[1] = (cover_type)cover2; 75 m_cover_ptr[2] = (cover_type)cover3; 76 if(x == m_last_x+1 && m_cur_span->len > 0) 77 { 78 m_cur_span->len += 3; 79 } 80 else 81 { 82 m_cur_span++; 83 m_cur_span->covers = m_cover_ptr; 84 m_cur_span->x = (int16)x; 85 m_cur_span->len = 3; 86 } 87 m_last_x = x; 88 m_cover_ptr += 3; 89 } 90 91 //-------------------------------------------------------------------- add_cells(int x,unsigned len,const cover_type * covers)92 void add_cells(int x, unsigned len, const cover_type* covers) 93 { 94 memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type)); 95 if(x == m_last_x+1 && m_cur_span->len > 0) 96 { 97 m_cur_span->len += 3 * (int16)len; 98 } 99 else 100 { 101 m_cur_span++; 102 m_cur_span->covers = m_cover_ptr; 103 m_cur_span->x = (int16)x; 104 m_cur_span->len = 3 * (int16)len; 105 } 106 m_cover_ptr += 3 * len; 107 m_last_x = x + len - 1; 108 } 109 110 //-------------------------------------------------------------------- add_span(int x,unsigned len,unsigned cover)111 void add_span(int x, unsigned len, unsigned cover) 112 { 113 if(x == m_last_x+1 && 114 m_cur_span->len < 0 && 115 cover == *m_cur_span->covers) 116 { 117 m_cur_span->len -= 3 * (int16)len; 118 } 119 else 120 { 121 *m_cover_ptr = (cover_type)cover; 122 m_cur_span++; 123 m_cur_span->covers = m_cover_ptr; 124 m_cover_ptr += 3; 125 m_cur_span->x = (int16)x; 126 m_cur_span->len = 3 * (int16)(-int(len)); 127 } 128 m_last_x = x + len - 1; 129 } 130 131 //-------------------------------------------------------------------- finalize(int y)132 void finalize(int y) 133 { 134 m_y = y; 135 } 136 137 //-------------------------------------------------------------------- reset_spans()138 void reset_spans() 139 { 140 m_last_x = 0x7FFFFFF0; 141 m_cover_ptr = &m_covers[0]; 142 m_cur_span = &m_spans[0]; 143 m_cur_span->len = 0; 144 } 145 146 //-------------------------------------------------------------------- y()147 int y() const { return m_y; } num_spans()148 unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } begin()149 const_iterator begin() const { return &m_spans[1]; } 150 151 private: 152 scanline_p8_subpix(const self_type&); 153 const self_type& operator = (const self_type&); 154 155 int m_last_x; 156 int m_y; 157 pod_array<cover_type> m_covers; 158 cover_type* m_cover_ptr; 159 pod_array<span> m_spans; 160 span* m_cur_span; 161 }; 162 163 } 164 165 166 #endif 167 168