update dev300-m58
[ooovba.git] / agg / inc / agg_renderer_base.h
blob973f38554857e91f3961406a4c7b633758476dca
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // class renderer_base
18 //----------------------------------------------------------------------------
20 #ifndef AGG_RENDERER_BASE_INCLUDED
21 #define AGG_RENDERER_BASE_INCLUDED
23 #include "agg_basics.h"
24 #include "agg_rendering_buffer.h"
26 namespace agg
29 //-----------------------------------------------------------renderer_base
30 template<class PixelFormat> class renderer_base
32 public:
33 typedef PixelFormat pixfmt_type;
34 typedef typename pixfmt_type::color_type color_type;
36 //--------------------------------------------------------------------
37 renderer_base(pixfmt_type& _ren) :
38 m_ren(&_ren),
39 m_clip_box(0, 0, _ren.width() - 1, _ren.height() - 1)
43 //--------------------------------------------------------------------
44 const pixfmt_type& ren() const { return *m_ren; }
45 pixfmt_type& ren() { return *m_ren; }
47 //--------------------------------------------------------------------
48 unsigned width() const { return m_ren->width(); }
49 unsigned height() const { return m_ren->height(); }
51 //--------------------------------------------------------------------
52 bool clip_box(int x1, int y1, int x2, int y2)
54 rect cb(x1, y1, x2, y2);
55 cb.normalize();
56 if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
58 m_clip_box = cb;
59 return true;
61 m_clip_box.x1 = 1;
62 m_clip_box.y1 = 1;
63 m_clip_box.x2 = 0;
64 m_clip_box.y2 = 0;
65 return false;
68 //--------------------------------------------------------------------
69 void reset_clipping(bool visibility)
71 if(visibility)
73 m_clip_box.x1 = 0;
74 m_clip_box.y1 = 0;
75 m_clip_box.x2 = width() - 1;
76 m_clip_box.y2 = height() - 1;
78 else
80 m_clip_box.x1 = 1;
81 m_clip_box.y1 = 1;
82 m_clip_box.x2 = 0;
83 m_clip_box.y2 = 0;
87 //--------------------------------------------------------------------
88 void clip_box_naked(int x1, int y1, int x2, int y2)
90 m_clip_box.x1 = x1;
91 m_clip_box.y1 = y1;
92 m_clip_box.x2 = x2;
93 m_clip_box.y2 = y2;
96 //--------------------------------------------------------------------
97 bool inbox(int x, int y) const
99 return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
100 x <= m_clip_box.x2 && y <= m_clip_box.y2;
103 //--------------------------------------------------------------------
104 void first_clip_box() {}
105 bool next_clip_box() { return false; }
107 //--------------------------------------------------------------------
108 const rect& clip_box() const { return m_clip_box; }
109 int xmin() const { return m_clip_box.x1; }
110 int ymin() const { return m_clip_box.y1; }
111 int xmax() const { return m_clip_box.x2; }
112 int ymax() const { return m_clip_box.y2; }
114 //--------------------------------------------------------------------
115 const rect& bounding_clip_box() const { return m_clip_box; }
116 int bounding_xmin() const { return m_clip_box.x1; }
117 int bounding_ymin() const { return m_clip_box.y1; }
118 int bounding_xmax() const { return m_clip_box.x2; }
119 int bounding_ymax() const { return m_clip_box.y2; }
121 //--------------------------------------------------------------------
122 void clear(const color_type& c)
124 unsigned y;
125 if(width())
127 for(y = 0; y < height(); y++)
129 m_ren->copy_hline(0, y, width(), c);
134 //--------------------------------------------------------------------
135 void copy_pixel(int x, int y, const color_type& c)
137 if(inbox(x, y))
139 m_ren->copy_pixel(x, y, c);
143 //--------------------------------------------------------------------
144 void blend_pixel(int x, int y, const color_type& c, cover_type cover)
146 if(inbox(x, y))
148 m_ren->blend_pixel(x, y, c, cover);
152 //--------------------------------------------------------------------
153 color_type pixel(int x, int y) const
155 return inbox(x, y) ?
156 m_ren->pixel(x, y) :
157 color_type::no_color();
160 //--------------------------------------------------------------------
161 void copy_hline(int x1, int y, int x2, const color_type& c)
163 if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
164 if(y > ymax()) return;
165 if(y < ymin()) return;
166 if(x1 > xmax()) return;
167 if(x2 < xmin()) return;
169 if(x1 < xmin()) x1 = xmin();
170 if(x2 > xmax()) x2 = xmax();
172 m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
175 //--------------------------------------------------------------------
176 void copy_vline(int x, int y1, int y2, const color_type& c)
178 if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
179 if(x > xmax()) return;
180 if(x < xmin()) return;
181 if(y1 > ymax()) return;
182 if(y2 < ymin()) return;
184 if(y1 < ymin()) y1 = ymin();
185 if(y2 > ymax()) y2 = ymax();
187 m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
190 //--------------------------------------------------------------------
191 void blend_hline(int x1, int y, int x2,
192 const color_type& c, cover_type cover)
194 if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
195 if(y > ymax()) return;
196 if(y < ymin()) return;
197 if(x1 > xmax()) return;
198 if(x2 < xmin()) return;
200 if(x1 < xmin()) x1 = xmin();
201 if(x2 > xmax()) x2 = xmax();
203 m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
206 //--------------------------------------------------------------------
207 void blend_vline(int x, int y1, int y2,
208 const color_type& c, cover_type cover)
210 if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
211 if(x > xmax()) return;
212 if(x < xmin()) return;
213 if(y1 > ymax()) return;
214 if(y2 < ymin()) return;
216 if(y1 < ymin()) y1 = ymin();
217 if(y2 > ymax()) y2 = ymax();
219 m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
223 //--------------------------------------------------------------------
224 void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
226 rect rc(x1, y1, x2, y2);
227 rc.normalize();
228 if(rc.clip(clip_box()))
230 int y;
231 for(y = rc.y1; y <= rc.y2; y++)
233 m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
238 //--------------------------------------------------------------------
239 void blend_bar(int x1, int y1, int x2, int y2,
240 const color_type& c, cover_type cover)
242 rect rc(x1, y1, x2, y2);
243 rc.normalize();
244 if(rc.clip(clip_box()))
246 int y;
247 for(y = rc.y1; y <= rc.y2; y++)
249 m_ren->blend_hline(rc.x1,
251 unsigned(rc.x2 - rc.x1 + 1),
253 cover);
259 //--------------------------------------------------------------------
260 void blend_solid_hspan(int x, int y, int len,
261 const color_type& c,
262 const cover_type* covers)
264 if(y > ymax()) return;
265 if(y < ymin()) return;
267 if(x < xmin())
269 len -= xmin() - x;
270 if(len <= 0) return;
271 covers += xmin() - x;
272 x = xmin();
274 if(x + len > xmax())
276 len = xmax() - x + 1;
277 if(len <= 0) return;
279 m_ren->blend_solid_hspan(x, y, len, c, covers);
282 //--------------------------------------------------------------------
283 void blend_solid_vspan(int x, int y, int len,
284 const color_type& c,
285 const cover_type* covers)
287 if(x > xmax()) return;
288 if(x < xmin()) return;
290 if(y < ymin())
292 len -= ymin() - y;
293 if(len <= 0) return;
294 covers += ymin() - y;
295 y = ymin();
297 if(y + len > ymax())
299 len = ymax() - y + 1;
300 if(len <= 0) return;
302 m_ren->blend_solid_vspan(x, y, len, c, covers);
305 //--------------------------------------------------------------------
306 void blend_color_hspan(int x, int y, int len,
307 const color_type* colors,
308 const cover_type* covers,
309 cover_type cover = cover_full)
311 if(y > ymax()) return;
312 if(y < ymin()) return;
314 if(x < xmin())
316 int d = xmin() - x;
317 len -= d;
318 if(len <= 0) return;
319 if(covers) covers += d;
320 colors += d;
321 x = xmin();
323 if(x + len > xmax())
325 len = xmax() - x + 1;
326 if(len <= 0) return;
328 m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
331 //--------------------------------------------------------------------
332 void blend_color_vspan(int x, int y, int len,
333 const color_type* colors,
334 const cover_type* covers,
335 cover_type cover = cover_full)
337 if(x > xmax()) return;
338 if(x < xmin()) return;
340 if(y < ymin())
342 int d = ymin() - y;
343 len -= d;
344 if(len <= 0) return;
345 if(covers) covers += d;
346 colors += d;
347 y = ymin();
349 if(y + len > ymax())
351 len = ymax() - y + 1;
352 if(len <= 0) return;
354 m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
358 //--------------------------------------------------------------------
359 void blend_opaque_color_hspan(int x, int y, int len,
360 const color_type* colors,
361 const cover_type* covers,
362 cover_type cover = cover_full)
364 if(y > ymax()) return;
365 if(y < ymin()) return;
367 if(x < xmin())
369 int d = xmin() - x;
370 len -= d;
371 if(len <= 0) return;
372 if(covers) covers += d;
373 colors += d;
374 x = xmin();
376 if(x + len > xmax())
378 len = xmax() - x + 1;
379 if(len <= 0) return;
381 m_ren->blend_opaque_color_hspan(x, y, len, colors, covers, cover);
384 //--------------------------------------------------------------------
385 void blend_opaque_color_vspan(int x, int y, int len,
386 const color_type* colors,
387 const cover_type* covers,
388 cover_type cover = cover_full)
390 if(x > xmax()) return;
391 if(x < xmin()) return;
393 if(y < ymin())
395 int d = ymin() - y;
396 len -= d;
397 if(len <= 0) return;
398 if(covers) covers += d;
399 colors += d;
400 y = ymin();
402 if(y + len > ymax())
404 len = ymax() - y + 1;
405 if(len <= 0) return;
407 m_ren->blend_opaque_color_vspan(x, y, len, colors, covers, cover);
411 //--------------------------------------------------------------------
412 void blend_color_hspan_no_clip(int x, int y, int len,
413 const color_type* colors,
414 const cover_type* covers,
415 cover_type cover = cover_full)
417 m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
420 //--------------------------------------------------------------------
421 void blend_color_vspan_no_clip(int x, int y, int len,
422 const color_type* colors,
423 const cover_type* covers,
424 cover_type cover = cover_full)
426 m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
429 //--------------------------------------------------------------------
430 void blend_opaque_color_hspan_no_clip(int x, int y, int len,
431 const color_type* colors,
432 const cover_type* covers,
433 cover_type cover = cover_full)
435 m_ren->blend_opaque_color_hspan(x, y, len, colors, covers, cover);
438 //--------------------------------------------------------------------
439 void blend_opaque_color_vspan_no_clip(int x, int y, int len,
440 const color_type* colors,
441 const cover_type* covers,
442 cover_type cover = cover_full)
444 m_ren->blend_opaque_color_vspan(x, y, len, colors, covers, cover);
447 //--------------------------------------------------------------------
448 rect clip_rect_area(rect& dst, rect& src, int wsrc, int hsrc) const
450 rect rc(0,0,0,0);
451 rect cb = clip_box();
452 ++cb.x2;
453 ++cb.y2;
455 if(src.x1 < 0)
457 dst.x1 -= src.x1;
458 src.x1 = 0;
460 if(src.y1 < 0)
462 dst.y1 -= src.y1;
463 src.y1 = 0;
466 if(src.x2 > wsrc) src.x2 = wsrc;
467 if(src.y2 > hsrc) src.y2 = hsrc;
469 if(dst.x1 < cb.x1)
471 src.x1 += cb.x1 - dst.x1;
472 dst.x1 = cb.x1;
474 if(dst.y1 < cb.y1)
476 src.y1 += cb.y1 - dst.y1;
477 dst.y1 = cb.y1;
480 if(dst.x2 > cb.x2) dst.x2 = cb.x2;
481 if(dst.y2 > cb.y2) dst.y2 = cb.y2;
483 rc.x2 = dst.x2 - dst.x1;
484 rc.y2 = dst.y2 - dst.y1;
486 if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
487 if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
488 return rc;
492 //--------------------------------------------------------------------
493 void copy_from(const rendering_buffer& src,
494 const rect* rect_src_ptr = 0,
495 int dx = 0,
496 int dy = 0)
498 rect rsrc(0, 0, src.width(), src.height());
499 if(rect_src_ptr)
501 rsrc.x1 = rect_src_ptr->x1;
502 rsrc.y1 = rect_src_ptr->y1;
503 rsrc.x2 = rect_src_ptr->x2 + 1;
504 rsrc.y2 = rect_src_ptr->y2 + 1;
507 // Version with xdst, ydst (absolute positioning)
508 //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
510 // Version with dx, dy (relative positioning)
511 rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
513 rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
515 if(rc.x2 > 0)
517 int incy = 1;
518 if(rdst.y1 > rsrc.y1)
520 rsrc.y1 += rc.y2 - 1;
521 rdst.y1 += rc.y2 - 1;
522 incy = -1;
524 while(rc.y2 > 0)
526 m_ren->copy_from(src,
527 rdst.x1, rdst.y1,
528 rsrc.x1, rsrc.y1,
529 rc.x2);
530 rdst.y1 += incy;
531 rsrc.y1 += incy;
532 --rc.y2;
539 //--------------------------------------------------------------------
540 template<class SrcPixelFormatRenderer>
541 void blend_from(const SrcPixelFormatRenderer& src,
542 const rect* rect_src_ptr = 0,
543 int dx = 0,
544 int dy = 0)
546 rect rsrc(0, 0, src.width(), src.height());
547 if(rect_src_ptr)
549 rsrc.x1 = rect_src_ptr->x1;
550 rsrc.y1 = rect_src_ptr->y1;
551 rsrc.x2 = rect_src_ptr->x2 + 1;
552 rsrc.y2 = rect_src_ptr->y2 + 1;
555 // Version with xdst, ydst (absolute positioning)
556 //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
558 // Version with dx, dy (relative positioning)
559 rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
561 rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
563 if(rc.x2 > 0)
565 int incy = 1;
566 if(rdst.y1 > rsrc.y1)
568 rsrc.y1 += rc.y2 - 1;
569 rdst.y1 += rc.y2 - 1;
570 incy = -1;
572 while(rc.y2 > 0)
574 typename SrcPixelFormatRenderer::row_data span = src.span(rsrc.x1, rsrc.y1);
575 if(span.ptr)
577 int x1src = rsrc.x1;
578 int x1dst = rdst.x1;
579 int len = rc.x2;
580 if(span.x1 > x1src)
582 x1dst += span.x1 - x1src;
583 len -= span.x1 - x1src;
584 x1src = span.x1;
586 if(len > 0)
588 if(x1src + len-1 > span.x2)
590 len -= x1src + len - span.x2 - 1;
592 if(len > 0)
594 m_ren->blend_from(src, span.ptr,
595 x1dst, rdst.y1,
596 x1src, rsrc.y1,
597 len);
601 rdst.y1 += incy;
602 rsrc.y1 += incy;
603 --rc.y2;
610 private:
611 pixfmt_type* m_ren;
612 rect m_clip_box;
618 #endif