15 #ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED 16 #define AGG_RASTERIZER_OUTLINE_AA_INCLUDED 19 #include "agg_basics.h" 20 #include "agg_line_aa_basics.h" 21 #include "agg_vertex_sequence.h" 27 inline bool cmp_dist_start(
int d) {
return d > 0; }
28 inline bool cmp_dist_end(
int d) {
return d <= 0; }
51 double dx = val.x - x;
52 double dy = val.y - y;
53 return (len = uround(std::sqrt(dx * dx + dy * dy))) >
54 (line_subpixel_scale + line_subpixel_scale / 2);
60 enum outline_aa_join_e
65 outline_miter_accurate_join
79 int xb1, yb1, xb2, yb2;
83 void draw(draw_vars& dv,
unsigned start,
unsigned end);
91 m_line_join(ren.accurate_join_only() ?
92 outline_miter_accurate_join :
98 void attach(Renderer& ren) { m_ren = &ren; }
101 void line_join(outline_aa_join_e join)
103 m_line_join = m_ren->accurate_join_only() ?
104 outline_miter_accurate_join :
107 bool line_join()
const {
return m_line_join; }
110 void round_cap(
bool v) { m_round_cap = v; }
111 bool round_cap()
const {
return m_round_cap; }
114 void move_to(
int x,
int y)
116 m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y));
120 void line_to(
int x,
int y)
122 m_src_vertices.add(vertex_type(x, y));
126 void move_to_d(
double x,
double y)
128 move_to(Coord::conv(x), Coord::conv(y));
132 void line_to_d(
double x,
double y)
134 line_to(Coord::conv(x), Coord::conv(y));
138 void render(
bool close_polygon);
141 void add_vertex(
double x,
double y,
unsigned cmd)
152 render(is_closed(cmd));
155 move_to(m_start_x, m_start_y);
166 template<
class VertexSource>
167 void add_path(VertexSource& vs,
unsigned path_id=0)
174 while(!is_stop(cmd = vs.vertex(&x, &y)))
176 add_vertex(x, y, cmd);
183 template<
class VertexSource,
class ColorStorage,
class PathId>
184 void render_all_paths(VertexSource& vs,
185 const ColorStorage& colors,
186 const PathId& path_id,
189 for(
unsigned i = 0; i < num_paths; i++)
191 m_ren->color(colors[i]);
192 add_path(vs, path_id[i]);
198 template<
class Ctrl>
void render_ctrl(Ctrl& c)
201 for(i = 0; i < c.num_paths(); i++)
203 m_ren->color(c.color(i));
214 vertex_storage_type m_src_vertices;
215 outline_aa_join_e m_line_join;
229 template<
class Renderer,
class Coord>
235 const vertex_storage_type::value_type* v;
237 for(i = start; i < end; i++)
239 if(m_line_join == outline_round_join)
241 dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
242 dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
243 dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
244 dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
249 case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2);
break;
250 case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2);
break;
251 case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1);
break;
252 case 3: m_ren->line0(dv.curr);
break;
255 if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
257 m_ren->pie(dv.curr.x2, dv.curr.y2,
258 dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
259 dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
260 dv.curr.x2 + (dv.next.y2 - dv.next.y1),
261 dv.curr.y2 - (dv.next.x2 - dv.next.x1));
267 dv.lnext = m_src_vertices[dv.idx].len;
270 if(dv.idx >= m_src_vertices.size()) dv.idx = 0;
272 v = &m_src_vertices[dv.idx];
283 case outline_no_join:
287 case outline_miter_join:
289 dv.flags |= ((dv.curr.diagonal_quadrant() ==
290 dv.next.diagonal_quadrant()) << 1);
291 if((dv.flags & 2) == 0)
293 bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
297 case outline_round_join:
299 dv.flags |= ((dv.curr.diagonal_quadrant() ==
300 dv.next.diagonal_quadrant()) << 1);
303 case outline_miter_accurate_join:
305 bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
315 template<
class Renderer,
class Coord>
318 m_src_vertices.close(close_polygon);
320 const vertex_storage_type::value_type* v;
329 if(m_src_vertices.size() >= 3)
333 v = &m_src_vertices[m_src_vertices.size() - 1];
338 v = &m_src_vertices[0];
344 v = &m_src_vertices[1];
350 v = &m_src_vertices[dv.idx];
362 case outline_no_join:
366 case outline_miter_join:
367 case outline_round_join:
369 (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
370 ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
373 case outline_miter_accurate_join:
378 if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
380 bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
383 if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
385 bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
387 draw(dv, 0, m_src_vertices.size());
392 switch(m_src_vertices.size())
400 v = &m_src_vertices[0];
404 v = &m_src_vertices[1];
410 m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
419 m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
428 v = &m_src_vertices[0];
432 v = &m_src_vertices[1];
436 v = &m_src_vertices[2];
444 m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
447 if(m_line_join == outline_round_join)
449 m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
450 x2 + (y2 - y1), y2 - (x2 - x1));
452 m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
453 x2 + (y3 - y2), y2 - (x3 - x2));
455 m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
456 x3 + (y3 - y2), y3 - (x3 - x2));
460 bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
461 m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
464 m_ren->line3(lp2, dv.xb1, dv.yb1,
465 x3 + (y3 - y2), y3 - (x3 - x2));
469 m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
478 v = &m_src_vertices[0];
483 v = &m_src_vertices[1];
489 v = &m_src_vertices[2];
495 v = &m_src_vertices[dv.idx];
507 case outline_no_join:
511 case outline_miter_join:
512 case outline_round_join:
514 (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
515 ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
518 case outline_miter_accurate_join:
525 m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
527 if((dv.flags & 1) == 0)
529 if(m_line_join == outline_round_join)
531 m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
532 x2 + (y2 - y1), y2 - (x2 - x1));
533 m_ren->pie(prev.x2, prev.y2,
534 x2 + (y2 - y1), y2 - (x2 - x1),
535 dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
536 dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
540 bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
541 m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
551 if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
553 bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
556 draw(dv, 1, m_src_vertices.size() - 2);
558 if((dv.flags & 1) == 0)
560 if(m_line_join == outline_round_join)
562 m_ren->line3(dv.curr,
563 dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
564 dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
565 dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
566 dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
570 m_ren->line3(dv.curr, dv.xb1, dv.yb1,
571 dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
572 dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
577 m_ren->line2(dv.curr,
578 dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
579 dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
583 m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
584 dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
585 dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
592 m_src_vertices.remove_all();