159e13a3fSStephan Aßmus /* 259e13a3fSStephan Aßmus * Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>. 359e13a3fSStephan Aßmus * All rights reserved. Distributed under the terms of the MIT License. 459e13a3fSStephan Aßmus * 559e13a3fSStephan Aßmus * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 659e13a3fSStephan Aßmus * 759e13a3fSStephan Aßmus * 859e13a3fSStephan Aßmus */ 959e13a3fSStephan Aßmus 1059e13a3fSStephan Aßmus #ifndef AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED 1159e13a3fSStephan Aßmus #define AGG_RASTERIZER_SCANLINE_AA_SUBPIX_INCLUDED 1259e13a3fSStephan Aßmus 1359e13a3fSStephan Aßmus #include "agg_rasterizer_cells_aa.h" 1459e13a3fSStephan Aßmus #include "agg_rasterizer_sl_clip.h" 1559e13a3fSStephan Aßmus #include "agg_gamma_functions.h" 1659e13a3fSStephan Aßmus 1759e13a3fSStephan Aßmus 1859e13a3fSStephan Aßmus namespace agg 1959e13a3fSStephan Aßmus { 2059e13a3fSStephan Aßmus template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_subpix 2159e13a3fSStephan Aßmus { 2259e13a3fSStephan Aßmus enum status 2359e13a3fSStephan Aßmus { 2459e13a3fSStephan Aßmus status_initial, 2559e13a3fSStephan Aßmus status_move_to, 2659e13a3fSStephan Aßmus status_line_to, 2759e13a3fSStephan Aßmus status_closed 2859e13a3fSStephan Aßmus }; 2959e13a3fSStephan Aßmus 3059e13a3fSStephan Aßmus public: 3159e13a3fSStephan Aßmus typedef Clip clip_type; 3259e13a3fSStephan Aßmus typedef typename Clip::conv_type conv_type; 3359e13a3fSStephan Aßmus typedef typename Clip::coord_type coord_type; 3459e13a3fSStephan Aßmus 3559e13a3fSStephan Aßmus enum aa_scale_e 3659e13a3fSStephan Aßmus { 3759e13a3fSStephan Aßmus aa_shift = 8, 3859e13a3fSStephan Aßmus aa_scale = 1 << aa_shift, 3959e13a3fSStephan Aßmus aa_mask = aa_scale - 1, 4059e13a3fSStephan Aßmus aa_scale2 = aa_scale * 2, 4159e13a3fSStephan Aßmus aa_mask2 = aa_scale2 - 1 4259e13a3fSStephan Aßmus }; 4359e13a3fSStephan Aßmus 4459e13a3fSStephan Aßmus //-------------------------------------------------------------------- rasterizer_scanline_aa_subpix()4559e13a3fSStephan Aßmus rasterizer_scanline_aa_subpix() : 4659e13a3fSStephan Aßmus m_outline(), 4759e13a3fSStephan Aßmus m_clipper(), 4859e13a3fSStephan Aßmus m_filling_rule(fill_non_zero), 4959e13a3fSStephan Aßmus m_auto_close(true), 5059e13a3fSStephan Aßmus m_start_x(0), 5159e13a3fSStephan Aßmus m_start_y(0), 5259e13a3fSStephan Aßmus m_status(status_initial) 5359e13a3fSStephan Aßmus { 5459e13a3fSStephan Aßmus int i; 5559e13a3fSStephan Aßmus for(i = 0; i < aa_scale; i++) m_gamma[i] = i; 5659e13a3fSStephan Aßmus } 5759e13a3fSStephan Aßmus 5859e13a3fSStephan Aßmus //-------------------------------------------------------------------- 5959e13a3fSStephan Aßmus template<class GammaF> rasterizer_scanline_aa_subpix(const GammaF & gamma_function)6059e13a3fSStephan Aßmus rasterizer_scanline_aa_subpix(const GammaF& gamma_function) : 6159e13a3fSStephan Aßmus m_outline(), 6259e13a3fSStephan Aßmus m_clipper(m_outline), 6359e13a3fSStephan Aßmus m_filling_rule(fill_non_zero), 6459e13a3fSStephan Aßmus m_auto_close(true), 6559e13a3fSStephan Aßmus m_start_x(0), 6659e13a3fSStephan Aßmus m_start_y(0), 6759e13a3fSStephan Aßmus m_status(status_initial) 6859e13a3fSStephan Aßmus { 6959e13a3fSStephan Aßmus gamma(gamma_function); 7059e13a3fSStephan Aßmus } 7159e13a3fSStephan Aßmus 7259e13a3fSStephan Aßmus //-------------------------------------------------------------------- 7359e13a3fSStephan Aßmus void reset(); 7459e13a3fSStephan Aßmus void reset_clipping(); 7559e13a3fSStephan Aßmus void clip_box(double x1, double y1, double x2, double y2); 7659e13a3fSStephan Aßmus void filling_rule(filling_rule_e filling_rule); auto_close(bool flag)7759e13a3fSStephan Aßmus void auto_close(bool flag) { m_auto_close = flag; } 7859e13a3fSStephan Aßmus 7959e13a3fSStephan Aßmus //-------------------------------------------------------------------- gamma(const GammaF & gamma_function)8059e13a3fSStephan Aßmus template<class GammaF> void gamma(const GammaF& gamma_function) 8159e13a3fSStephan Aßmus { 8259e13a3fSStephan Aßmus int i; 8359e13a3fSStephan Aßmus for(i = 0; i < aa_scale; i++) 8459e13a3fSStephan Aßmus { 8559e13a3fSStephan Aßmus m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask); 8659e13a3fSStephan Aßmus } 8759e13a3fSStephan Aßmus } 8859e13a3fSStephan Aßmus 8959e13a3fSStephan Aßmus //-------------------------------------------------------------------- apply_gamma(unsigned cover)9059e13a3fSStephan Aßmus unsigned apply_gamma(unsigned cover) const 9159e13a3fSStephan Aßmus { 9259e13a3fSStephan Aßmus return m_gamma[cover]; 9359e13a3fSStephan Aßmus } 9459e13a3fSStephan Aßmus 9559e13a3fSStephan Aßmus //-------------------------------------------------------------------- 9659e13a3fSStephan Aßmus void move_to(int x, int y); 9759e13a3fSStephan Aßmus void line_to(int x, int y); 9859e13a3fSStephan Aßmus void move_to_d(double x, double y); 9959e13a3fSStephan Aßmus void line_to_d(double x, double y); 10059e13a3fSStephan Aßmus void close_polygon(); 10159e13a3fSStephan Aßmus void add_vertex(double x, double y, unsigned cmd); 10259e13a3fSStephan Aßmus 10359e13a3fSStephan Aßmus void edge(int x1, int y1, int x2, int y2); 10459e13a3fSStephan Aßmus void edge_d(double x1, double y1, double x2, double y2); 10559e13a3fSStephan Aßmus 10659e13a3fSStephan Aßmus //------------------------------------------------------------------- 10759e13a3fSStephan Aßmus template<class VertexSource> 10859e13a3fSStephan Aßmus void add_path(VertexSource& vs, unsigned path_id=0) 10959e13a3fSStephan Aßmus { 110*70b978fdSMurai Takashi double x = 0; 111*70b978fdSMurai Takashi double y = 0; 11259e13a3fSStephan Aßmus 11359e13a3fSStephan Aßmus unsigned cmd; 11459e13a3fSStephan Aßmus vs.rewind(path_id); 11559e13a3fSStephan Aßmus if(m_outline.sorted()) reset(); 11659e13a3fSStephan Aßmus while(!is_stop(cmd = vs.vertex(&x, &y))) 11759e13a3fSStephan Aßmus { 11859e13a3fSStephan Aßmus if (is_vertex(cmd)) { 11959e13a3fSStephan Aßmus x *= 3; 12059e13a3fSStephan Aßmus } 12159e13a3fSStephan Aßmus add_vertex(x, y, cmd); 12259e13a3fSStephan Aßmus } 12359e13a3fSStephan Aßmus } 12459e13a3fSStephan Aßmus 12559e13a3fSStephan Aßmus //-------------------------------------------------------------------- min_x()12659e13a3fSStephan Aßmus int min_x() const { return m_outline.min_x() / 3; } min_y()12759e13a3fSStephan Aßmus int min_y() const { return m_outline.min_y(); } max_x()12859e13a3fSStephan Aßmus int max_x() const { return m_outline.max_x() / 3; } max_y()12959e13a3fSStephan Aßmus int max_y() const { return m_outline.max_y(); } 13059e13a3fSStephan Aßmus 13159e13a3fSStephan Aßmus //-------------------------------------------------------------------- 13259e13a3fSStephan Aßmus void sort(); 13359e13a3fSStephan Aßmus bool rewind_scanlines(); 13459e13a3fSStephan Aßmus bool navigate_scanline(int y); 13559e13a3fSStephan Aßmus 13659e13a3fSStephan Aßmus //-------------------------------------------------------------------- calculate_alpha(int area)13759e13a3fSStephan Aßmus AGG_INLINE unsigned calculate_alpha(int area) const 13859e13a3fSStephan Aßmus { 13959e13a3fSStephan Aßmus int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); 14059e13a3fSStephan Aßmus 14159e13a3fSStephan Aßmus if(cover < 0) cover = -cover; 14259e13a3fSStephan Aßmus if(m_filling_rule == fill_even_odd) 14359e13a3fSStephan Aßmus { 14459e13a3fSStephan Aßmus cover &= aa_mask2; 14559e13a3fSStephan Aßmus if(cover > aa_scale) 14659e13a3fSStephan Aßmus { 14759e13a3fSStephan Aßmus cover = aa_scale2 - cover; 14859e13a3fSStephan Aßmus } 14959e13a3fSStephan Aßmus } 15059e13a3fSStephan Aßmus if(cover > aa_mask) cover = aa_mask; 15159e13a3fSStephan Aßmus return m_gamma[cover]; 15259e13a3fSStephan Aßmus } 15359e13a3fSStephan Aßmus 15459e13a3fSStephan Aßmus //-------------------------------------------------------------------- sweep_scanline(Scanline & sl)15559e13a3fSStephan Aßmus template<class Scanline> bool sweep_scanline(Scanline& sl) 15659e13a3fSStephan Aßmus { 15759e13a3fSStephan Aßmus for(;;) 15859e13a3fSStephan Aßmus { 15959e13a3fSStephan Aßmus if(m_scan_y > m_outline.max_y()) return false; 16059e13a3fSStephan Aßmus sl.reset_spans(); 16159e13a3fSStephan Aßmus unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); 16259e13a3fSStephan Aßmus const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); 16359e13a3fSStephan Aßmus int cover = 0; 16459e13a3fSStephan Aßmus int cover2 = 0; 16559e13a3fSStephan Aßmus int cover3 = 0; 16659e13a3fSStephan Aßmus 16759e13a3fSStephan Aßmus while(num_cells) 16859e13a3fSStephan Aßmus { 16959e13a3fSStephan Aßmus const cell_aa* cur_cell = *cells; 17059e13a3fSStephan Aßmus int x = cur_cell->x; 17159e13a3fSStephan Aßmus int area1 = cur_cell->area; 17259e13a3fSStephan Aßmus int area2; 17359e13a3fSStephan Aßmus int area3; 17459e13a3fSStephan Aßmus unsigned alpha1; 17559e13a3fSStephan Aßmus unsigned alpha2; 17659e13a3fSStephan Aßmus unsigned alpha3; 17759e13a3fSStephan Aßmus 17859e13a3fSStephan Aßmus int last_cover = cover3; 17959e13a3fSStephan Aßmus cover = cover3; 18059e13a3fSStephan Aßmus cover += cur_cell->cover; 18159e13a3fSStephan Aßmus 18259e13a3fSStephan Aßmus while(--num_cells) 18359e13a3fSStephan Aßmus { 18459e13a3fSStephan Aßmus cur_cell = *++cells; 18559e13a3fSStephan Aßmus if(cur_cell->x != x) break; 18659e13a3fSStephan Aßmus area1 += cur_cell->area; 18759e13a3fSStephan Aßmus cover += cur_cell->cover; 18859e13a3fSStephan Aßmus } 18959e13a3fSStephan Aßmus 19059e13a3fSStephan Aßmus if (x % 3 == 0) 19159e13a3fSStephan Aßmus { 19259e13a3fSStephan Aßmus if (cur_cell->x == x + 1) 19359e13a3fSStephan Aßmus { 19459e13a3fSStephan Aßmus area2 = cur_cell->area; 19559e13a3fSStephan Aßmus cover2 = cover + cur_cell->cover; 19659e13a3fSStephan Aßmus 19759e13a3fSStephan Aßmus while (--num_cells) 19859e13a3fSStephan Aßmus { 19959e13a3fSStephan Aßmus cur_cell = *++cells; 20059e13a3fSStephan Aßmus if (cur_cell->x != x+1) break; 20159e13a3fSStephan Aßmus area2 += cur_cell->area; 20259e13a3fSStephan Aßmus cover2 += cur_cell->cover; 20359e13a3fSStephan Aßmus } 20459e13a3fSStephan Aßmus } 20559e13a3fSStephan Aßmus else 20659e13a3fSStephan Aßmus { 20759e13a3fSStephan Aßmus area2 = 0; 20859e13a3fSStephan Aßmus cover2 = cover; 20959e13a3fSStephan Aßmus } 21059e13a3fSStephan Aßmus 21159e13a3fSStephan Aßmus if (cur_cell->x == x + 2) 21259e13a3fSStephan Aßmus { 21359e13a3fSStephan Aßmus area3 = cur_cell->area; 21459e13a3fSStephan Aßmus cover3 = cover2 + cur_cell->cover; 21559e13a3fSStephan Aßmus 21659e13a3fSStephan Aßmus while (--num_cells) 21759e13a3fSStephan Aßmus { 21859e13a3fSStephan Aßmus cur_cell = *++cells; 21959e13a3fSStephan Aßmus if (cur_cell->x != x+2) break; 22059e13a3fSStephan Aßmus area3 += cur_cell->area; 22159e13a3fSStephan Aßmus cover3 += cur_cell->cover; 22259e13a3fSStephan Aßmus } 22359e13a3fSStephan Aßmus } 22459e13a3fSStephan Aßmus else 22559e13a3fSStephan Aßmus { 22659e13a3fSStephan Aßmus area3 = 0; 22759e13a3fSStephan Aßmus cover3 = cover2; 22859e13a3fSStephan Aßmus } 22959e13a3fSStephan Aßmus } 23059e13a3fSStephan Aßmus else if (x % 3 == 1) 23159e13a3fSStephan Aßmus { 23259e13a3fSStephan Aßmus area2 = area1; 23359e13a3fSStephan Aßmus area1 = 0; 23459e13a3fSStephan Aßmus cover2 = cover; 23559e13a3fSStephan Aßmus cover = last_cover; 23659e13a3fSStephan Aßmus if (cur_cell->x == x+1) 23759e13a3fSStephan Aßmus { 23859e13a3fSStephan Aßmus area3 = cur_cell->area; 23959e13a3fSStephan Aßmus cover3 = cover2 + cur_cell->cover; 24059e13a3fSStephan Aßmus 24159e13a3fSStephan Aßmus while (--num_cells) 24259e13a3fSStephan Aßmus { 24359e13a3fSStephan Aßmus cur_cell = *++cells; 24459e13a3fSStephan Aßmus if (cur_cell->x != x+1) break; 24559e13a3fSStephan Aßmus area3 += cur_cell->area; 24659e13a3fSStephan Aßmus cover3 += cur_cell->cover; 24759e13a3fSStephan Aßmus } 24859e13a3fSStephan Aßmus } 24959e13a3fSStephan Aßmus else 25059e13a3fSStephan Aßmus { 25159e13a3fSStephan Aßmus area3 = 0; 25259e13a3fSStephan Aßmus cover3 = cover2; 25359e13a3fSStephan Aßmus } 25459e13a3fSStephan Aßmus } 25559e13a3fSStephan Aßmus else // if (x % 3 == 2) 25659e13a3fSStephan Aßmus { 25759e13a3fSStephan Aßmus area3 = area1; 25859e13a3fSStephan Aßmus area2 = 0; 25959e13a3fSStephan Aßmus area1 = 0; 26059e13a3fSStephan Aßmus cover3 = cover; 26159e13a3fSStephan Aßmus cover = last_cover; 26259e13a3fSStephan Aßmus cover2 = last_cover; 26359e13a3fSStephan Aßmus } 26459e13a3fSStephan Aßmus 26559e13a3fSStephan Aßmus alpha1 = area1 ? calculate_alpha((cover 26659e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)) - area1) : 0; 26759e13a3fSStephan Aßmus alpha2 = area2 ? calculate_alpha((cover2 26859e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)) - area2) : 0; 26959e13a3fSStephan Aßmus alpha3 = area3 ? calculate_alpha((cover3 27059e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)) - area3) : 0; 27159e13a3fSStephan Aßmus if(alpha1 || alpha2 || alpha3) 27259e13a3fSStephan Aßmus { 27359e13a3fSStephan Aßmus x += 3 - (x % 3); 27459e13a3fSStephan Aßmus if (area1 && !area2 && area3) 27559e13a3fSStephan Aßmus { 27659e13a3fSStephan Aßmus alpha2 = calculate_alpha(cover 27759e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 27859e13a3fSStephan Aßmus } 27959e13a3fSStephan Aßmus else if (num_cells && cur_cell->x >= x) 28059e13a3fSStephan Aßmus { 28159e13a3fSStephan Aßmus if (area1 && !area2) 28259e13a3fSStephan Aßmus { 28359e13a3fSStephan Aßmus alpha2 = calculate_alpha(cover 28459e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 28559e13a3fSStephan Aßmus alpha3 = alpha2; 28659e13a3fSStephan Aßmus } 28759e13a3fSStephan Aßmus if (area2 && !area3) 28859e13a3fSStephan Aßmus { 28959e13a3fSStephan Aßmus alpha3 = calculate_alpha(cover2 29059e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 29159e13a3fSStephan Aßmus } 29259e13a3fSStephan Aßmus } 29359e13a3fSStephan Aßmus if (!area1) 29459e13a3fSStephan Aßmus { 29559e13a3fSStephan Aßmus if (area2) 29659e13a3fSStephan Aßmus { 29759e13a3fSStephan Aßmus alpha1 = calculate_alpha(cover 29859e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 29959e13a3fSStephan Aßmus } 30059e13a3fSStephan Aßmus else if (area3) 30159e13a3fSStephan Aßmus { 30259e13a3fSStephan Aßmus alpha2 = calculate_alpha(cover 30359e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 30459e13a3fSStephan Aßmus alpha1 = alpha2; 30559e13a3fSStephan Aßmus } 30659e13a3fSStephan Aßmus } 30759e13a3fSStephan Aßmus sl.add_cell(x / 3 - 1, alpha1, alpha2, alpha3); 30859e13a3fSStephan Aßmus } 30959e13a3fSStephan Aßmus 31059e13a3fSStephan Aßmus if (num_cells && cur_cell->x - x >= 3) 31159e13a3fSStephan Aßmus { 31259e13a3fSStephan Aßmus alpha1 = calculate_alpha(cover3 31359e13a3fSStephan Aßmus << (poly_subpixel_shift + 1)); 31459e13a3fSStephan Aßmus sl.add_span(x / 3, cur_cell->x / 3 - x / 3, alpha1); 31559e13a3fSStephan Aßmus } 31659e13a3fSStephan Aßmus } 31759e13a3fSStephan Aßmus 31859e13a3fSStephan Aßmus if(sl.num_spans()) break; 31959e13a3fSStephan Aßmus ++m_scan_y; 32059e13a3fSStephan Aßmus } 32159e13a3fSStephan Aßmus 32259e13a3fSStephan Aßmus sl.finalize(m_scan_y); 32359e13a3fSStephan Aßmus ++m_scan_y; 32459e13a3fSStephan Aßmus return true; 32559e13a3fSStephan Aßmus } 32659e13a3fSStephan Aßmus 32759e13a3fSStephan Aßmus //-------------------------------------------------------------------- 32859e13a3fSStephan Aßmus bool hit_test(int tx, int ty); 32959e13a3fSStephan Aßmus 33059e13a3fSStephan Aßmus 33159e13a3fSStephan Aßmus private: 33259e13a3fSStephan Aßmus //-------------------------------------------------------------------- 33359e13a3fSStephan Aßmus // Disable copying 33459e13a3fSStephan Aßmus rasterizer_scanline_aa_subpix(const rasterizer_scanline_aa_subpix<Clip>&); 33559e13a3fSStephan Aßmus const rasterizer_scanline_aa_subpix<Clip>& 33659e13a3fSStephan Aßmus operator = (const rasterizer_scanline_aa_subpix<Clip>&); 33759e13a3fSStephan Aßmus 33859e13a3fSStephan Aßmus private: 33959e13a3fSStephan Aßmus rasterizer_cells_aa<cell_aa> m_outline; 34059e13a3fSStephan Aßmus clip_type m_clipper; 34159e13a3fSStephan Aßmus int m_gamma[aa_scale]; 34259e13a3fSStephan Aßmus filling_rule_e m_filling_rule; 34359e13a3fSStephan Aßmus bool m_auto_close; 34459e13a3fSStephan Aßmus coord_type m_start_x; 34559e13a3fSStephan Aßmus coord_type m_start_y; 34659e13a3fSStephan Aßmus unsigned m_status; 34759e13a3fSStephan Aßmus int m_scan_y; 34859e13a3fSStephan Aßmus }; 34959e13a3fSStephan Aßmus 35059e13a3fSStephan Aßmus 35159e13a3fSStephan Aßmus 35259e13a3fSStephan Aßmus 35359e13a3fSStephan Aßmus 35459e13a3fSStephan Aßmus 35559e13a3fSStephan Aßmus 35659e13a3fSStephan Aßmus 35759e13a3fSStephan Aßmus 35859e13a3fSStephan Aßmus 35959e13a3fSStephan Aßmus 36059e13a3fSStephan Aßmus 36159e13a3fSStephan Aßmus //------------------------------------------------------------------------ 36259e13a3fSStephan Aßmus template<class Clip> reset()36359e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::reset() 36459e13a3fSStephan Aßmus { 36559e13a3fSStephan Aßmus m_outline.reset(); 36659e13a3fSStephan Aßmus m_status = status_initial; 36759e13a3fSStephan Aßmus } 36859e13a3fSStephan Aßmus 36959e13a3fSStephan Aßmus //------------------------------------------------------------------------ 37059e13a3fSStephan Aßmus template<class Clip> filling_rule(filling_rule_e filling_rule)37159e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::filling_rule(filling_rule_e filling_rule) 37259e13a3fSStephan Aßmus { 37359e13a3fSStephan Aßmus m_filling_rule = filling_rule; 37459e13a3fSStephan Aßmus } 37559e13a3fSStephan Aßmus 37659e13a3fSStephan Aßmus //------------------------------------------------------------------------ 37759e13a3fSStephan Aßmus template<class Clip> clip_box(double x1,double y1,double x2,double y2)37859e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::clip_box(double x1, double y1, 37959e13a3fSStephan Aßmus double x2, double y2) 38059e13a3fSStephan Aßmus { 38159e13a3fSStephan Aßmus reset(); 38259e13a3fSStephan Aßmus m_clipper.clip_box(3 * conv_type::downscale(x1), conv_type::upscale(y1), 38359e13a3fSStephan Aßmus conv_type::upscale(3 * x2), conv_type::upscale(y2)); 38459e13a3fSStephan Aßmus } 38559e13a3fSStephan Aßmus 38659e13a3fSStephan Aßmus //------------------------------------------------------------------------ 38759e13a3fSStephan Aßmus template<class Clip> reset_clipping()38859e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::reset_clipping() 38959e13a3fSStephan Aßmus { 39059e13a3fSStephan Aßmus reset(); 39159e13a3fSStephan Aßmus m_clipper.reset_clipping(); 39259e13a3fSStephan Aßmus } 39359e13a3fSStephan Aßmus 39459e13a3fSStephan Aßmus //------------------------------------------------------------------------ 39559e13a3fSStephan Aßmus template<class Clip> close_polygon()39659e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::close_polygon() 39759e13a3fSStephan Aßmus { 39859e13a3fSStephan Aßmus if(m_status == status_line_to) 39959e13a3fSStephan Aßmus { 40059e13a3fSStephan Aßmus m_clipper.line_to(m_outline, m_start_x, m_start_y); 40159e13a3fSStephan Aßmus m_status = status_closed; 40259e13a3fSStephan Aßmus } 40359e13a3fSStephan Aßmus } 40459e13a3fSStephan Aßmus 40559e13a3fSStephan Aßmus //------------------------------------------------------------------------ 40659e13a3fSStephan Aßmus template<class Clip> move_to(int x,int y)40759e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::move_to(int x, int y) 40859e13a3fSStephan Aßmus { 40959e13a3fSStephan Aßmus if(m_outline.sorted()) reset(); 41059e13a3fSStephan Aßmus if(m_auto_close) close_polygon(); 41159e13a3fSStephan Aßmus m_clipper.move_to(m_start_x = conv_type::downscale(x), 41259e13a3fSStephan Aßmus m_start_y = conv_type::downscale(y)); 41359e13a3fSStephan Aßmus m_status = status_move_to; 41459e13a3fSStephan Aßmus } 41559e13a3fSStephan Aßmus 41659e13a3fSStephan Aßmus //------------------------------------------------------------------------ 41759e13a3fSStephan Aßmus template<class Clip> line_to(int x,int y)41859e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::line_to(int x, int y) 41959e13a3fSStephan Aßmus { 42059e13a3fSStephan Aßmus m_clipper.line_to(m_outline, 42159e13a3fSStephan Aßmus conv_type::downscale(x), 42259e13a3fSStephan Aßmus conv_type::downscale(y)); 42359e13a3fSStephan Aßmus m_status = status_line_to; 42459e13a3fSStephan Aßmus } 42559e13a3fSStephan Aßmus 42659e13a3fSStephan Aßmus //------------------------------------------------------------------------ 42759e13a3fSStephan Aßmus template<class Clip> move_to_d(double x,double y)42859e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::move_to_d(double x, double y) 42959e13a3fSStephan Aßmus { 43059e13a3fSStephan Aßmus if(m_outline.sorted()) reset(); 43159e13a3fSStephan Aßmus if(m_auto_close) close_polygon(); 43259e13a3fSStephan Aßmus m_clipper.move_to(m_start_x = conv_type::upscale(x), 43359e13a3fSStephan Aßmus m_start_y = conv_type::upscale(y)); 43459e13a3fSStephan Aßmus m_status = status_move_to; 43559e13a3fSStephan Aßmus } 43659e13a3fSStephan Aßmus 43759e13a3fSStephan Aßmus //------------------------------------------------------------------------ 43859e13a3fSStephan Aßmus template<class Clip> line_to_d(double x,double y)43959e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::line_to_d(double x, double y) 44059e13a3fSStephan Aßmus { 44159e13a3fSStephan Aßmus m_clipper.line_to(m_outline, 44259e13a3fSStephan Aßmus conv_type::upscale(x), 44359e13a3fSStephan Aßmus conv_type::upscale(y)); 44459e13a3fSStephan Aßmus m_status = status_line_to; 44559e13a3fSStephan Aßmus } 44659e13a3fSStephan Aßmus 44759e13a3fSStephan Aßmus //------------------------------------------------------------------------ 44859e13a3fSStephan Aßmus template<class Clip> add_vertex(double x,double y,unsigned cmd)44959e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::add_vertex(double x, double y, unsigned cmd) 45059e13a3fSStephan Aßmus { 45159e13a3fSStephan Aßmus if(is_move_to(cmd)) 45259e13a3fSStephan Aßmus { 45359e13a3fSStephan Aßmus move_to_d(x, y); 45459e13a3fSStephan Aßmus } 45559e13a3fSStephan Aßmus else 45659e13a3fSStephan Aßmus if(is_vertex(cmd)) 45759e13a3fSStephan Aßmus { 45859e13a3fSStephan Aßmus line_to_d(x, y); 45959e13a3fSStephan Aßmus } 46059e13a3fSStephan Aßmus else 46159e13a3fSStephan Aßmus if(is_close(cmd)) 46259e13a3fSStephan Aßmus { 46359e13a3fSStephan Aßmus close_polygon(); 46459e13a3fSStephan Aßmus } 46559e13a3fSStephan Aßmus } 46659e13a3fSStephan Aßmus 46759e13a3fSStephan Aßmus //------------------------------------------------------------------------ 46859e13a3fSStephan Aßmus template<class Clip> edge(int x1,int y1,int x2,int y2)46959e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::edge(int x1, int y1, int x2, int y2) 47059e13a3fSStephan Aßmus { 47159e13a3fSStephan Aßmus if(m_outline.sorted()) reset(); 47259e13a3fSStephan Aßmus m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); 47359e13a3fSStephan Aßmus m_clipper.line_to(m_outline, 47459e13a3fSStephan Aßmus conv_type::downscale(x2), 47559e13a3fSStephan Aßmus conv_type::downscale(y2)); 47659e13a3fSStephan Aßmus m_status = status_move_to; 47759e13a3fSStephan Aßmus } 47859e13a3fSStephan Aßmus 47959e13a3fSStephan Aßmus //------------------------------------------------------------------------ 48059e13a3fSStephan Aßmus template<class Clip> edge_d(double x1,double y1,double x2,double y2)48159e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::edge_d(double x1, double y1, 48259e13a3fSStephan Aßmus double x2, double y2) 48359e13a3fSStephan Aßmus { 48459e13a3fSStephan Aßmus if(m_outline.sorted()) reset(); 48559e13a3fSStephan Aßmus m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); 48659e13a3fSStephan Aßmus m_clipper.line_to(m_outline, 48759e13a3fSStephan Aßmus conv_type::upscale(x2), 48859e13a3fSStephan Aßmus conv_type::upscale(y2)); 48959e13a3fSStephan Aßmus m_status = status_move_to; 49059e13a3fSStephan Aßmus } 49159e13a3fSStephan Aßmus 49259e13a3fSStephan Aßmus //------------------------------------------------------------------------ 49359e13a3fSStephan Aßmus template<class Clip> sort()49459e13a3fSStephan Aßmus void rasterizer_scanline_aa_subpix<Clip>::sort() 49559e13a3fSStephan Aßmus { 49659e13a3fSStephan Aßmus m_outline.sort_cells(); 49759e13a3fSStephan Aßmus } 49859e13a3fSStephan Aßmus 49959e13a3fSStephan Aßmus //------------------------------------------------------------------------ 50059e13a3fSStephan Aßmus template<class Clip> rewind_scanlines()50159e13a3fSStephan Aßmus AGG_INLINE bool rasterizer_scanline_aa_subpix<Clip>::rewind_scanlines() 50259e13a3fSStephan Aßmus { 50359e13a3fSStephan Aßmus if(m_auto_close) close_polygon(); 50459e13a3fSStephan Aßmus m_outline.sort_cells(); 50559e13a3fSStephan Aßmus if(m_outline.total_cells() == 0) 50659e13a3fSStephan Aßmus { 50759e13a3fSStephan Aßmus return false; 50859e13a3fSStephan Aßmus } 50959e13a3fSStephan Aßmus m_scan_y = m_outline.min_y(); 51059e13a3fSStephan Aßmus return true; 51159e13a3fSStephan Aßmus } 51259e13a3fSStephan Aßmus 51359e13a3fSStephan Aßmus 51459e13a3fSStephan Aßmus //------------------------------------------------------------------------ 51559e13a3fSStephan Aßmus template<class Clip> navigate_scanline(int y)51659e13a3fSStephan Aßmus AGG_INLINE bool rasterizer_scanline_aa_subpix<Clip>::navigate_scanline(int y) 51759e13a3fSStephan Aßmus { 51859e13a3fSStephan Aßmus if(m_auto_close) close_polygon(); 51959e13a3fSStephan Aßmus m_outline.sort_cells(); 52059e13a3fSStephan Aßmus if(m_outline.total_cells() == 0 || 52159e13a3fSStephan Aßmus y < m_outline.min_y() || 52259e13a3fSStephan Aßmus y > m_outline.max_y()) 52359e13a3fSStephan Aßmus { 52459e13a3fSStephan Aßmus return false; 52559e13a3fSStephan Aßmus } 52659e13a3fSStephan Aßmus m_scan_y = y; 52759e13a3fSStephan Aßmus return true; 52859e13a3fSStephan Aßmus } 52959e13a3fSStephan Aßmus 53059e13a3fSStephan Aßmus //------------------------------------------------------------------------ 53159e13a3fSStephan Aßmus template<class Clip> hit_test(int tx,int ty)53259e13a3fSStephan Aßmus bool rasterizer_scanline_aa_subpix<Clip>::hit_test(int tx, int ty) 53359e13a3fSStephan Aßmus { 53459e13a3fSStephan Aßmus if(!navigate_scanline(ty)) return false; 53559e13a3fSStephan Aßmus scanline_hit_test sl(tx); 53659e13a3fSStephan Aßmus sweep_scanline(sl); 53759e13a3fSStephan Aßmus return sl.hit(); 53859e13a3fSStephan Aßmus } 53959e13a3fSStephan Aßmus 54059e13a3fSStephan Aßmus 54159e13a3fSStephan Aßmus 54259e13a3fSStephan Aßmus } 54359e13a3fSStephan Aßmus 54459e13a3fSStephan Aßmus 54559e13a3fSStephan Aßmus 54659e13a3fSStephan Aßmus #endif 54759e13a3fSStephan Aßmus 548