29 #ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED 30 #define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED 33 #include "agg_rasterizer_cells_aa.h" 34 #include "agg_rasterizer_sl_clip.h" 54 x = std::numeric_limits<int>::max();
55 y = std::numeric_limits<int>::max();
62 int not_equal(
int ex,
int ey,
const cell_aa&)
const 64 return ((
unsigned)ex - (
unsigned)x) | ((unsigned)ey - (
unsigned)y);
111 typedef Clip clip_type;
112 typedef typename Clip::conv_type conv_type;
113 typedef typename Clip::coord_type coord_type;
118 aa_scale = 1 << aa_shift,
119 aa_mask = aa_scale - 1,
120 aa_scale2 = aa_scale * 2,
121 aa_mask2 = aa_scale2 - 1
126 m_outline(cell_block_limit),
128 m_filling_rule(fill_non_zero),
132 m_status(status_initial)
138 void reset_clipping();
139 void clip_box(
double x1,
double y1,
double x2,
double y2);
140 void filling_rule(filling_rule_e filling_rule);
141 void auto_close(
bool flag) { m_auto_close = flag; }
144 unsigned apply_gamma(
unsigned cover)
const 150 void move_to(
int x,
int y);
151 void line_to(
int x,
int y);
152 void move_to_d(
double x,
double y);
153 void line_to_d(
double x,
double y);
154 void close_polygon();
155 void add_vertex(
double x,
double y,
unsigned cmd);
157 void edge(
int x1,
int y1,
int x2,
int y2);
158 void edge_d(
double x1,
double y1,
double x2,
double y2);
161 template<
class VertexSource>
162 void add_path(VertexSource& vs,
unsigned path_id=0)
169 if(m_outline.sorted()) reset();
170 while(!is_stop(cmd = vs.vertex(&x, &y)))
172 add_vertex(x, y, cmd);
177 int min_x()
const {
return m_outline.min_x(); }
178 int min_y()
const {
return m_outline.min_y(); }
179 int max_x()
const {
return m_outline.max_x(); }
180 int max_y()
const {
return m_outline.max_y(); }
184 bool rewind_scanlines();
185 bool navigate_scanline(
int y);
188 AGG_INLINE
unsigned calculate_alpha(
int area)
const 190 int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
192 if(cover < 0) cover = -cover;
193 if(m_filling_rule == fill_even_odd)
198 cover = aa_scale2 - cover;
201 if(cover > aa_mask) cover = aa_mask;
206 template<
class Scanline>
bool sweep_scanline(Scanline& sl)
210 if(m_scan_y > m_outline.max_y())
return false;
212 unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
213 const cell_aa*
const* cells = m_outline.scanline_cells(m_scan_y);
218 const cell_aa* cur_cell = *cells;
220 int area = cur_cell->area;
223 cover += cur_cell->cover;
229 if(cur_cell->x != x)
break;
230 area += cur_cell->area;
231 cover += cur_cell->cover;
236 alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
239 sl.add_cell(x, alpha);
244 if(num_cells && cur_cell->x > x)
246 alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
249 sl.add_span(x, cur_cell->x - x, alpha);
254 if(sl.num_spans())
break;
258 sl.finalize(m_scan_y);
264 bool hit_test(
int tx,
int ty);
277 filling_rule_e m_filling_rule;
279 coord_type m_start_x;
280 coord_type m_start_y;
301 m_status = status_initial;
308 m_filling_rule = filling_rule;
314 double x2,
double y2)
317 m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
318 conv_type::upscale(x2), conv_type::upscale(y2));
326 m_clipper.reset_clipping();
333 if(m_status == status_line_to)
335 m_clipper.line_to(m_outline, m_start_x, m_start_y);
336 m_status = status_closed;
344 if(m_outline.sorted()) reset();
345 if(m_auto_close) close_polygon();
346 m_clipper.move_to(m_start_x = conv_type::downscale(x),
347 m_start_y = conv_type::downscale(y));
348 m_status = status_move_to;
355 m_clipper.line_to(m_outline,
356 conv_type::downscale(x),
357 conv_type::downscale(y));
358 m_status = status_line_to;
365 if(m_outline.sorted()) reset();
366 if(m_auto_close) close_polygon();
367 m_clipper.move_to(m_start_x = conv_type::upscale(x),
368 m_start_y = conv_type::upscale(y));
369 m_status = status_move_to;
376 m_clipper.line_to(m_outline,
377 conv_type::upscale(x),
378 conv_type::upscale(y));
379 m_status = status_line_to;
406 if(m_outline.sorted()) reset();
407 m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
408 m_clipper.line_to(m_outline,
409 conv_type::downscale(x2),
410 conv_type::downscale(y2));
411 m_status = status_move_to;
417 double x2,
double y2)
419 if(m_outline.sorted()) reset();
420 m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
421 m_clipper.line_to(m_outline,
422 conv_type::upscale(x2),
423 conv_type::upscale(y2));
424 m_status = status_move_to;
431 if(m_auto_close) close_polygon();
432 m_outline.sort_cells();
439 if(m_auto_close) close_polygon();
440 m_outline.sort_cells();
441 if(m_outline.total_cells() == 0)
445 m_scan_y = m_outline.min_y();
454 if(m_auto_close) close_polygon();
455 m_outline.sort_cells();
456 if(m_outline.total_cells() == 0 ||
457 y < m_outline.min_y() ||
458 y > m_outline.max_y())
470 if(!navigate_scanline(ty))
return false;