20 #ifndef AGG_RENDERER_BASE_INCLUDED 21 #define AGG_RENDERER_BASE_INCLUDED 23 #include "agg_basics.h" 24 #include "agg_rendering_buffer.h" 34 typedef typename pixfmt_type::color_type color_type;
35 typedef typename pixfmt_type::row_data row_data;
41 m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
43 void attach(pixfmt_type& ren)
46 m_clip_box =
rect_i(0, 0, ren.width() - 1, ren.height() - 1);
50 const pixfmt_type& ren()
const {
return *m_ren; }
51 pixfmt_type& ren() {
return *m_ren; }
54 unsigned width()
const {
return m_ren->width(); }
55 unsigned height()
const {
return m_ren->height(); }
58 bool clip_box(
int x1,
int y1,
int x2,
int y2)
62 if(cb.clip(
rect_i(0, 0, width() - 1, height() - 1)))
75 void reset_clipping(
bool visibility)
81 m_clip_box.x2 = width() - 1;
82 m_clip_box.y2 = height() - 1;
94 void clip_box_naked(
int x1,
int y1,
int x2,
int y2)
103 bool inbox(
int x,
int y)
const 105 return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
106 x <= m_clip_box.x2 && y <= m_clip_box.y2;
110 const rect_i& clip_box()
const {
return m_clip_box; }
111 int xmin()
const {
return m_clip_box.x1; }
112 int ymin()
const {
return m_clip_box.y1; }
113 int xmax()
const {
return m_clip_box.x2; }
114 int ymax()
const {
return m_clip_box.y2; }
117 const rect_i& bounding_clip_box()
const {
return m_clip_box; }
118 int bounding_xmin()
const {
return m_clip_box.x1; }
119 int bounding_ymin()
const {
return m_clip_box.y1; }
120 int bounding_xmax()
const {
return m_clip_box.x2; }
121 int bounding_ymax()
const {
return m_clip_box.y2; }
124 void clear(
const color_type& c)
129 for(y = 0; y < height(); y++)
131 m_ren->copy_hline(0, y, width(), c);
138 void fill(
const color_type& c)
143 for(y = 0; y < height(); y++)
145 m_ren->blend_hline(0, y, width(), c, cover_mask);
151 void copy_pixel(
int x,
int y,
const color_type& c)
155 m_ren->copy_pixel(x, y, c);
160 void blend_pixel(
int x,
int y,
const color_type& c, cover_type cover)
164 m_ren->blend_pixel(x, y, c, cover);
169 color_type pixel(
int x,
int y)
const 173 color_type::no_color();
177 void copy_hline(
int x1,
int y,
int x2,
const color_type& c)
179 if(x1 > x2) {
int t = x2; x2 = x1; x1 = t; }
180 if(y > ymax())
return;
181 if(y < ymin())
return;
182 if(x1 > xmax())
return;
183 if(x2 < xmin())
return;
185 if(x1 < xmin()) x1 = xmin();
186 if(x2 > xmax()) x2 = xmax();
188 m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
192 void copy_vline(
int x,
int y1,
int y2,
const color_type& c)
194 if(y1 > y2) {
int t = y2; y2 = y1; y1 = t; }
195 if(x > xmax())
return;
196 if(x < xmin())
return;
197 if(y1 > ymax())
return;
198 if(y2 < ymin())
return;
200 if(y1 < ymin()) y1 = ymin();
201 if(y2 > ymax()) y2 = ymax();
203 m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
207 void blend_hline(
int x1,
int y,
int x2,
208 const color_type& c, cover_type cover)
210 if(x1 > x2) {
int t = x2; x2 = x1; x1 = t; }
211 if(y > ymax())
return;
212 if(y < ymin())
return;
213 if(x1 > xmax())
return;
214 if(x2 < xmin())
return;
216 if(x1 < xmin()) x1 = xmin();
217 if(x2 > xmax()) x2 = xmax();
219 m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
223 void blend_vline(
int x,
int y1,
int y2,
224 const color_type& c, cover_type cover)
226 if(y1 > y2) {
int t = y2; y2 = y1; y1 = t; }
227 if(x > xmax())
return;
228 if(x < xmin())
return;
229 if(y1 > ymax())
return;
230 if(y2 < ymin())
return;
232 if(y1 < ymin()) y1 = ymin();
233 if(y2 > ymax()) y2 = ymax();
235 m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
240 void copy_bar(
int x1,
int y1,
int x2,
int y2,
const color_type& c)
242 rect_i rc(x1, y1, x2, y2);
244 if(rc.clip(clip_box()))
247 for(y = rc.y1; y <= rc.y2; y++)
249 m_ren->copy_hline(rc.x1, y,
unsigned(rc.x2 - rc.x1 + 1), c);
255 void blend_bar(
int x1,
int y1,
int x2,
int y2,
256 const color_type& c, cover_type cover)
258 rect_i rc(x1, y1, x2, y2);
260 if(rc.clip(clip_box()))
263 for(y = rc.y1; y <= rc.y2; y++)
265 m_ren->blend_hline(rc.x1,
267 unsigned(rc.x2 - rc.x1 + 1),
275 void blend_solid_hspan(
int x,
int y,
int len,
277 const cover_type* covers)
279 if(y > ymax())
return;
280 if(y < ymin())
return;
286 covers += xmin() - x;
291 len = xmax() - x + 1;
294 m_ren->blend_solid_hspan(x, y, len, c, covers);
298 void blend_solid_vspan(
int x,
int y,
int len,
300 const cover_type* covers)
302 if(x > xmax())
return;
303 if(x < xmin())
return;
309 covers += ymin() - y;
314 len = ymax() - y + 1;
317 m_ren->blend_solid_vspan(x, y, len, c, covers);
322 void copy_color_hspan(
int x,
int y,
int len,
const color_type* colors)
324 if(y > ymax())
return;
325 if(y < ymin())
return;
337 len = xmax() - x + 1;
340 m_ren->copy_color_hspan(x, y, len, colors);
345 void copy_color_vspan(
int x,
int y,
int len,
const color_type* colors)
347 if(x > xmax())
return;
348 if(x < xmin())
return;
360 len = ymax() - y + 1;
363 m_ren->copy_color_vspan(x, y, len, colors);
368 void blend_color_hspan(
int x,
int y,
int len,
369 const color_type* colors,
370 const cover_type* covers,
371 cover_type cover = agg::cover_full)
373 if(y > ymax())
return;
374 if(y < ymin())
return;
381 if(covers) covers += d;
387 len = xmax() - x + 1;
390 m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
394 void blend_color_vspan(
int x,
int y,
int len,
395 const color_type* colors,
396 const cover_type* covers,
397 cover_type cover = agg::cover_full)
399 if(x > xmax())
return;
400 if(x < xmin())
return;
407 if(covers) covers += d;
413 len = ymax() - y + 1;
416 m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
438 if(src.x2 > wsrc) src.x2 = wsrc;
439 if(src.y2 > hsrc) src.y2 = hsrc;
443 src.x1 += cb.x1 - dst.x1;
448 src.y1 += cb.y1 - dst.y1;
452 if(dst.x2 > cb.x2) dst.x2 = cb.x2;
453 if(dst.y2 > cb.y2) dst.y2 = cb.y2;
455 rc.x2 = dst.x2 - dst.x1;
456 rc.y2 = dst.y2 - dst.y1;
458 if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
459 if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
464 template<
class RenBuf>
465 void copy_from(
const RenBuf& src,
466 const rect_i* rect_src_ptr = 0,
470 rect_i rsrc(0, 0, src.width(), src.height());
473 rsrc.x1 = rect_src_ptr->x1;
474 rsrc.y1 = rect_src_ptr->y1;
475 rsrc.x2 = rect_src_ptr->x2 + 1;
476 rsrc.y2 = rect_src_ptr->y2 + 1;
483 rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
485 rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
490 if(rdst.y1 > rsrc.y1)
492 rsrc.y1 += rc.y2 - 1;
493 rdst.y1 += rc.y2 - 1;
498 m_ren->copy_from(src,
510 template<
class SrcPixelFormatRenderer>
511 void blend_from(
const SrcPixelFormatRenderer& src,
512 const rect_i* rect_src_ptr = 0,
515 cover_type cover = agg::cover_full)
517 rect_i rsrc(0, 0, src.width(), src.height());
520 rsrc.x1 = rect_src_ptr->x1;
521 rsrc.y1 = rect_src_ptr->y1;
522 rsrc.x2 = rect_src_ptr->x2 + 1;
523 rsrc.y2 = rect_src_ptr->y2 + 1;
530 rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
531 rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
536 if(rdst.y1 > rsrc.y1)
538 rsrc.y1 += rc.y2 - 1;
539 rdst.y1 += rc.y2 - 1;
544 typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
552 x1dst += rw.x1 - x1src;
553 len -= rw.x1 - x1src;
558 if(x1src + len-1 > rw.x2)
560 len -= x1src + len - rw.x2 - 1;
564 m_ren->blend_from(src,
580 template<
class SrcPixelFormatRenderer>
581 void blend_from_color(
const SrcPixelFormatRenderer& src,
582 const color_type& color,
583 const rect_i* rect_src_ptr = 0,
586 cover_type cover = agg::cover_full)
588 rect_i rsrc(0, 0, src.width(), src.height());
591 rsrc.x1 = rect_src_ptr->x1;
592 rsrc.y1 = rect_src_ptr->y1;
593 rsrc.x2 = rect_src_ptr->x2 + 1;
594 rsrc.y2 = rect_src_ptr->y2 + 1;
601 rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
602 rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
607 if(rdst.y1 > rsrc.y1)
609 rsrc.y1 += rc.y2 - 1;
610 rdst.y1 += rc.y2 - 1;
615 typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
623 x1dst += rw.x1 - x1src;
624 len -= rw.x1 - x1src;
629 if(x1src + len-1 > rw.x2)
631 len -= x1src + len - rw.x2 - 1;
635 m_ren->blend_from_color(src,
652 template<
class SrcPixelFormatRenderer>
653 void blend_from_lut(
const SrcPixelFormatRenderer& src,
654 const color_type* color_lut,
655 const rect_i* rect_src_ptr = 0,
658 cover_type cover = agg::cover_full)
660 rect_i rsrc(0, 0, src.width(), src.height());
663 rsrc.x1 = rect_src_ptr->x1;
664 rsrc.y1 = rect_src_ptr->y1;
665 rsrc.x2 = rect_src_ptr->x2 + 1;
666 rsrc.y2 = rect_src_ptr->y2 + 1;
673 rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
674 rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
679 if(rdst.y1 > rsrc.y1)
681 rsrc.y1 += rc.y2 - 1;
682 rdst.y1 += rc.y2 - 1;
687 typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
695 x1dst += rw.x1 - x1src;
696 len -= rw.x1 - x1src;
701 if(x1src + len-1 > rw.x2)
703 len -= x1src + len - rw.x2 - 1;
707 m_ren->blend_from_lut(src,