1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Contact: mcseem@antigrain.com
6 //          mcseemagg@yahoo.com
7 //          http://antigrain.com
8 //
9 // AGG is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // AGG is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with AGG; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23 //----------------------------------------------------------------------------
24 
25 #ifndef AGG_RENDERER_BASE_INCLUDED
26 #define AGG_RENDERER_BASE_INCLUDED
27 
28 #include "agg_basics.h"
29 #include "agg_rendering_buffer.h"
30 
31 namespace agg
32 {
33 
34     //-----------------------------------------------------------renderer_base
35     template<class PixelFormat> class renderer_base
36     {
37     public:
38         typedef PixelFormat pixfmt_type;
39         typedef typename pixfmt_type::color_type color_type;
40         typedef typename pixfmt_type::row_data row_data;
41 
42         //--------------------------------------------------------------------
renderer_base()43         renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
renderer_base(pixfmt_type & ren)44         explicit renderer_base(pixfmt_type& ren) :
45             m_ren(&ren),
46             m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
47         {}
attach(pixfmt_type & ren)48         void attach(pixfmt_type& ren)
49         {
50             m_ren = &ren;
51             m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
52         }
53 
54         //--------------------------------------------------------------------
ren()55         const pixfmt_type& ren() const { return *m_ren;  }
ren()56         pixfmt_type& ren() { return *m_ren;  }
57 
58         //--------------------------------------------------------------------
width()59         unsigned width()  const { return m_ren->width();  }
height()60         unsigned height() const { return m_ren->height(); }
61 
62         //--------------------------------------------------------------------
clip_box(int x1,int y1,int x2,int y2)63         bool clip_box(int x1, int y1, int x2, int y2)
64         {
65             rect_i cb(x1, y1, x2, y2);
66             cb.normalize();
67             if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
68             {
69                 m_clip_box = cb;
70                 return true;
71             }
72             m_clip_box.x1 = 1;
73             m_clip_box.y1 = 1;
74             m_clip_box.x2 = 0;
75             m_clip_box.y2 = 0;
76             return false;
77         }
78 
79         //--------------------------------------------------------------------
reset_clipping(bool visibility)80         void reset_clipping(bool visibility)
81         {
82             if(visibility)
83             {
84                 m_clip_box.x1 = 0;
85                 m_clip_box.y1 = 0;
86                 m_clip_box.x2 = width() - 1;
87                 m_clip_box.y2 = height() - 1;
88             }
89             else
90             {
91                 m_clip_box.x1 = 1;
92                 m_clip_box.y1 = 1;
93                 m_clip_box.x2 = 0;
94                 m_clip_box.y2 = 0;
95             }
96         }
97 
98         //--------------------------------------------------------------------
clip_box_naked(int x1,int y1,int x2,int y2)99         void clip_box_naked(int x1, int y1, int x2, int y2)
100         {
101             m_clip_box.x1 = x1;
102             m_clip_box.y1 = y1;
103             m_clip_box.x2 = x2;
104             m_clip_box.y2 = y2;
105         }
106 
107         //--------------------------------------------------------------------
inbox(int x,int y)108         bool inbox(int x, int y) const
109         {
110             return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
111                    x <= m_clip_box.x2 && y <= m_clip_box.y2;
112         }
113 
114         //--------------------------------------------------------------------
clip_box()115         const rect_i& clip_box() const { return m_clip_box;    }
xmin()116         int           xmin()     const { return m_clip_box.x1; }
ymin()117         int           ymin()     const { return m_clip_box.y1; }
xmax()118         int           xmax()     const { return m_clip_box.x2; }
ymax()119         int           ymax()     const { return m_clip_box.y2; }
120 
121         //--------------------------------------------------------------------
bounding_clip_box()122         const rect_i& bounding_clip_box() const { return m_clip_box;    }
bounding_xmin()123         int           bounding_xmin()     const { return m_clip_box.x1; }
bounding_ymin()124         int           bounding_ymin()     const { return m_clip_box.y1; }
bounding_xmax()125         int           bounding_xmax()     const { return m_clip_box.x2; }
bounding_ymax()126         int           bounding_ymax()     const { return m_clip_box.y2; }
127 
128         //--------------------------------------------------------------------
clear(const color_type & c)129         void clear(const color_type& c)
130         {
131             unsigned y;
132             if(width())
133             {
134                 for(y = 0; y < height(); y++)
135                 {
136                     m_ren->copy_hline(0, y, width(), c);
137                 }
138             }
139         }
140 
141 
142         //--------------------------------------------------------------------
copy_pixel(int x,int y,const color_type & c)143         void copy_pixel(int x, int y, const color_type& c)
144         {
145             if(inbox(x, y))
146             {
147                 m_ren->copy_pixel(x, y, c);
148             }
149         }
150 
151         //--------------------------------------------------------------------
blend_pixel(int x,int y,const color_type & c,cover_type cover)152         void blend_pixel(int x, int y, const color_type& c, cover_type cover)
153         {
154             if(inbox(x, y))
155             {
156                 m_ren->blend_pixel(x, y, c, cover);
157             }
158         }
159 
160         //--------------------------------------------------------------------
pixel(int x,int y)161         color_type pixel(int x, int y) const
162         {
163             return inbox(x, y) ?
164                    m_ren->pixel(x, y) :
165                    color_type::no_color();
166         }
167 
168         //--------------------------------------------------------------------
copy_hline(int x1,int y,int x2,const color_type & c)169         void copy_hline(int x1, int y, int x2, const color_type& c)
170         {
171             if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
172             if(y  > ymax()) return;
173             if(y  < ymin()) return;
174             if(x1 > xmax()) return;
175             if(x2 < xmin()) return;
176 
177             if(x1 < xmin()) x1 = xmin();
178             if(x2 > xmax()) x2 = xmax();
179 
180             m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
181         }
182 
183         //--------------------------------------------------------------------
copy_vline(int x,int y1,int y2,const color_type & c)184         void copy_vline(int x, int y1, int y2, const color_type& c)
185         {
186             if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
187             if(x  > xmax()) return;
188             if(x  < xmin()) return;
189             if(y1 > ymax()) return;
190             if(y2 < ymin()) return;
191 
192             if(y1 < ymin()) y1 = ymin();
193             if(y2 > ymax()) y2 = ymax();
194 
195             m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
196         }
197 
198         //--------------------------------------------------------------------
blend_hline(int x1,int y,int x2,const color_type & c,cover_type cover)199         void blend_hline(int x1, int y, int x2,
200                          const color_type& c, cover_type cover)
201         {
202             if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
203             if(y  > ymax()) return;
204             if(y  < ymin()) return;
205             if(x1 > xmax()) return;
206             if(x2 < xmin()) return;
207 
208             if(x1 < xmin()) x1 = xmin();
209             if(x2 > xmax()) x2 = xmax();
210 
211             m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
212         }
213 
214         //--------------------------------------------------------------------
blend_vline(int x,int y1,int y2,const color_type & c,cover_type cover)215         void blend_vline(int x, int y1, int y2,
216                          const color_type& c, cover_type cover)
217         {
218             if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
219             if(x  > xmax()) return;
220             if(x  < xmin()) return;
221             if(y1 > ymax()) return;
222             if(y2 < ymin()) return;
223 
224             if(y1 < ymin()) y1 = ymin();
225             if(y2 > ymax()) y2 = ymax();
226 
227             m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
228         }
229 
230 
231         //--------------------------------------------------------------------
copy_bar(int x1,int y1,int x2,int y2,const color_type & c)232         void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
233         {
234             rect_i rc(x1, y1, x2, y2);
235             rc.normalize();
236             if(rc.clip(clip_box()))
237             {
238                 int y;
239                 for(y = rc.y1; y <= rc.y2; y++)
240                 {
241                     m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
242                 }
243             }
244         }
245 
246         //--------------------------------------------------------------------
blend_bar(int x1,int y1,int x2,int y2,const color_type & c,cover_type cover)247         void blend_bar(int x1, int y1, int x2, int y2,
248                        const color_type& c, cover_type cover)
249         {
250             rect_i rc(x1, y1, x2, y2);
251             rc.normalize();
252             if(rc.clip(clip_box()))
253             {
254                 int y;
255                 for(y = rc.y1; y <= rc.y2; y++)
256                 {
257                     m_ren->blend_hline(rc.x1,
258                                        y,
259                                        unsigned(rc.x2 - rc.x1 + 1),
260                                        c,
261                                        cover);
262                 }
263             }
264         }
265 
266         //--------------------------------------------------------------------
blend_solid_hspan(int x,int y,int len,const color_type & c,const cover_type * covers)267         void blend_solid_hspan(int x, int y, int len,
268                                const color_type& c,
269                                const cover_type* covers)
270         {
271             if(y > ymax()) return;
272             if(y < ymin()) return;
273 
274             if(x < xmin())
275             {
276                 len -= xmin() - x;
277                 if(len <= 0) return;
278                 covers += xmin() - x;
279                 x = xmin();
280             }
281             if(x + len > xmax())
282             {
283                 len = xmax() - x + 1;
284                 if(len <= 0) return;
285             }
286             m_ren->blend_solid_hspan(x, y, len, c, covers);
287         }
288 
289         //--------------------------------------------------------------------
blend_solid_vspan(int x,int y,int len,const color_type & c,const cover_type * covers)290         void blend_solid_vspan(int x, int y, int len,
291                                const color_type& c,
292                                const cover_type* covers)
293         {
294             if(x > xmax()) return;
295             if(x < xmin()) return;
296 
297             if(y < ymin())
298             {
299                 len -= ymin() - y;
300                 if(len <= 0) return;
301                 covers += ymin() - y;
302                 y = ymin();
303             }
304             if(y + len > ymax())
305             {
306                 len = ymax() - y + 1;
307                 if(len <= 0) return;
308             }
309             m_ren->blend_solid_vspan(x, y, len, c, covers);
310         }
311 
312 
313         //--------------------------------------------------------------------
copy_color_hspan(int x,int y,int len,const color_type * colors)314         void copy_color_hspan(int x, int y, int len, const color_type* colors)
315         {
316             if(y > ymax()) return;
317             if(y < ymin()) return;
318 
319             if(x < xmin())
320             {
321                 int d = xmin() - x;
322                 len -= d;
323                 if(len <= 0) return;
324                 colors += d;
325                 x = xmin();
326             }
327             if(x + len > xmax())
328             {
329                 len = xmax() - x + 1;
330                 if(len <= 0) return;
331             }
332             m_ren->copy_color_hspan(x, y, len, colors);
333         }
334 
335 
336         //--------------------------------------------------------------------
copy_color_vspan(int x,int y,int len,const color_type * colors)337         void copy_color_vspan(int x, int y, int len, const color_type* colors)
338         {
339             if(x > xmax()) return;
340             if(x < xmin()) return;
341 
342             if(y < ymin())
343             {
344                 int d = ymin() - y;
345                 len -= d;
346                 if(len <= 0) return;
347                 colors += d;
348                 y = ymin();
349             }
350             if(y + len > ymax())
351             {
352                 len = ymax() - y + 1;
353                 if(len <= 0) return;
354             }
355             m_ren->copy_color_vspan(x, y, len, colors);
356         }
357 
358 
359         //--------------------------------------------------------------------
360         void blend_color_hspan(int x, int y, int len,
361                                const color_type* colors,
362                                const cover_type* covers,
363                                cover_type cover = agg::cover_full)
364         {
365             if(y > ymax()) return;
366             if(y < ymin()) return;
367 
368             if(x < xmin())
369             {
370                 int d = xmin() - x;
371                 len -= d;
372                 if(len <= 0) return;
373                 if(covers) covers += d;
374                 colors += d;
375                 x = xmin();
376             }
377             if(x + len > xmax())
378             {
379                 len = xmax() - x + 1;
380                 if(len <= 0) return;
381             }
382             m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
383         }
384 
385         //--------------------------------------------------------------------
386         void blend_color_vspan(int x, int y, int len,
387                                const color_type* colors,
388                                const cover_type* covers,
389                                cover_type cover = agg::cover_full)
390         {
391             if(x > xmax()) return;
392             if(x < xmin()) return;
393 
394             if(y < ymin())
395             {
396                 int d = ymin() - y;
397                 len -= d;
398                 if(len <= 0) return;
399                 if(covers) covers += d;
400                 colors += d;
401                 y = ymin();
402             }
403             if(y + len > ymax())
404             {
405                 len = ymax() - y + 1;
406                 if(len <= 0) return;
407             }
408             m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
409         }
410 
411         //--------------------------------------------------------------------
clip_rect_area(rect_i & dst,rect_i & src,int wsrc,int hsrc)412         rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
413         {
414             rect_i rc(0,0,0,0);
415             rect_i cb = clip_box();
416             ++cb.x2;
417             ++cb.y2;
418 
419             if(src.x1 < 0)
420             {
421                 dst.x1 -= src.x1;
422                 src.x1 = 0;
423             }
424             if(src.y1 < 0)
425             {
426                 dst.y1 -= src.y1;
427                 src.y1 = 0;
428             }
429 
430             if(src.x2 > wsrc) src.x2 = wsrc;
431             if(src.y2 > hsrc) src.y2 = hsrc;
432 
433             if(dst.x1 < cb.x1)
434             {
435                 src.x1 += cb.x1 - dst.x1;
436                 dst.x1 = cb.x1;
437             }
438             if(dst.y1 < cb.y1)
439             {
440                 src.y1 += cb.y1 - dst.y1;
441                 dst.y1 = cb.y1;
442             }
443 
444             if(dst.x2 > cb.x2) dst.x2 = cb.x2;
445             if(dst.y2 > cb.y2) dst.y2 = cb.y2;
446 
447             rc.x2 = dst.x2 - dst.x1;
448             rc.y2 = dst.y2 - dst.y1;
449 
450             if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
451             if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
452             return rc;
453         }
454 
455         //--------------------------------------------------------------------
456         template<class RenBuf>
457         void copy_from(const RenBuf& src,
458                        const rect_i* rect_src_ptr = 0,
459                        int dx = 0,
460                        int dy = 0)
461         {
462             rect_i rsrc(0, 0, src.width(), src.height());
463             if(rect_src_ptr)
464             {
465                 rsrc.x1 = rect_src_ptr->x1;
466                 rsrc.y1 = rect_src_ptr->y1;
467                 rsrc.x2 = rect_src_ptr->x2 + 1;
468                 rsrc.y2 = rect_src_ptr->y2 + 1;
469             }
470 
471             // Version with xdst, ydst (absolute positioning)
472             //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
473 
474             // Version with dx, dy (relative positioning)
475             rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
476 
477             rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
478 
479             if(rc.x2 > 0)
480             {
481                 int incy = 1;
482                 if(rdst.y1 > rsrc.y1)
483                 {
484                     rsrc.y1 += rc.y2 - 1;
485                     rdst.y1 += rc.y2 - 1;
486                     incy = -1;
487                 }
488                 while(rc.y2 > 0)
489                 {
490                     m_ren->copy_from(src,
491                                      rdst.x1, rdst.y1,
492                                      rsrc.x1, rsrc.y1,
493                                      rc.x2);
494                     rdst.y1 += incy;
495                     rsrc.y1 += incy;
496                     --rc.y2;
497                 }
498             }
499         }
500 
501         //--------------------------------------------------------------------
502         template<class SrcPixelFormatRenderer>
503         void blend_from(const SrcPixelFormatRenderer& src,
504                         const rect_i* rect_src_ptr = 0,
505                         int dx = 0,
506                         int dy = 0,
507                         cover_type cover = agg::cover_full)
508         {
509             rect_i rsrc(0, 0, src.width(), src.height());
510             if(rect_src_ptr)
511             {
512                 rsrc.x1 = rect_src_ptr->x1;
513                 rsrc.y1 = rect_src_ptr->y1;
514                 rsrc.x2 = rect_src_ptr->x2 + 1;
515                 rsrc.y2 = rect_src_ptr->y2 + 1;
516             }
517 
518             // Version with xdst, ydst (absolute positioning)
519             //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
520 
521             // Version with dx, dy (relative positioning)
522             rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
523             rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
524 
525             if(rc.x2 > 0)
526             {
527                 int incy = 1;
528                 if(rdst.y1 > rsrc.y1)
529                 {
530                     rsrc.y1 += rc.y2 - 1;
531                     rdst.y1 += rc.y2 - 1;
532                     incy = -1;
533                 }
534                 while(rc.y2 > 0)
535                 {
536                     typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
537                     if(rw.ptr)
538                     {
539                         int x1src = rsrc.x1;
540                         int x1dst = rdst.x1;
541                         int len   = rc.x2;
542                         if(rw.x1 > x1src)
543                         {
544                             x1dst += rw.x1 - x1src;
545                             len   -= rw.x1 - x1src;
546                             x1src  = rw.x1;
547                         }
548                         if(len > 0)
549                         {
550                             if(x1src + len-1 > rw.x2)
551                             {
552                                 len -= x1src + len - rw.x2 - 1;
553                             }
554                             if(len > 0)
555                             {
556                                 m_ren->blend_from(src,
557                                                   x1dst, rdst.y1,
558                                                   x1src, rsrc.y1,
559                                                   len,
560                                                   cover);
561                             }
562                         }
563                     }
564                     rdst.y1 += incy;
565                     rsrc.y1 += incy;
566                     --rc.y2;
567                 }
568             }
569         }
570 
571         //--------------------------------------------------------------------
572         template<class SrcPixelFormatRenderer>
573         void blend_from_color(const SrcPixelFormatRenderer& src,
574                               const color_type& color,
575                               const rect_i* rect_src_ptr = 0,
576                               int dx = 0,
577                               int dy = 0,
578                               cover_type cover = agg::cover_full)
579         {
580             rect_i rsrc(0, 0, src.width(), src.height());
581             if(rect_src_ptr)
582             {
583                 rsrc.x1 = rect_src_ptr->x1;
584                 rsrc.y1 = rect_src_ptr->y1;
585                 rsrc.x2 = rect_src_ptr->x2 + 1;
586                 rsrc.y2 = rect_src_ptr->y2 + 1;
587             }
588 
589             // Version with xdst, ydst (absolute positioning)
590             //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
591 
592             // Version with dx, dy (relative positioning)
593             rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
594             rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
595 
596             if(rc.x2 > 0)
597             {
598                 int incy = 1;
599                 if(rdst.y1 > rsrc.y1)
600                 {
601                     rsrc.y1 += rc.y2 - 1;
602                     rdst.y1 += rc.y2 - 1;
603                     incy = -1;
604                 }
605                 while(rc.y2 > 0)
606                 {
607                     typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
608                     if(rw.ptr)
609                     {
610                         int x1src = rsrc.x1;
611                         int x1dst = rdst.x1;
612                         int len   = rc.x2;
613                         if(rw.x1 > x1src)
614                         {
615                             x1dst += rw.x1 - x1src;
616                             len   -= rw.x1 - x1src;
617                             x1src  = rw.x1;
618                         }
619                         if(len > 0)
620                         {
621                             if(x1src + len-1 > rw.x2)
622                             {
623                                 len -= x1src + len - rw.x2 - 1;
624                             }
625                             if(len > 0)
626                             {
627                                 m_ren->blend_from_color(src,
628                                                         color,
629                                                         x1dst, rdst.y1,
630                                                         x1src, rsrc.y1,
631                                                         len,
632                                                         cover);
633                             }
634                         }
635                     }
636                     rdst.y1 += incy;
637                     rsrc.y1 += incy;
638                     --rc.y2;
639                 }
640             }
641         }
642 
643         //--------------------------------------------------------------------
644         template<class SrcPixelFormatRenderer>
645         void blend_from_lut(const SrcPixelFormatRenderer& src,
646                             const color_type* color_lut,
647                             const rect_i* rect_src_ptr = 0,
648                             int dx = 0,
649                             int dy = 0,
650                             cover_type cover = agg::cover_full)
651         {
652             rect_i rsrc(0, 0, src.width(), src.height());
653             if(rect_src_ptr)
654             {
655                 rsrc.x1 = rect_src_ptr->x1;
656                 rsrc.y1 = rect_src_ptr->y1;
657                 rsrc.x2 = rect_src_ptr->x2 + 1;
658                 rsrc.y2 = rect_src_ptr->y2 + 1;
659             }
660 
661             // Version with xdst, ydst (absolute positioning)
662             //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
663 
664             // Version with dx, dy (relative positioning)
665             rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
666             rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
667 
668             if(rc.x2 > 0)
669             {
670                 int incy = 1;
671                 if(rdst.y1 > rsrc.y1)
672                 {
673                     rsrc.y1 += rc.y2 - 1;
674                     rdst.y1 += rc.y2 - 1;
675                     incy = -1;
676                 }
677                 while(rc.y2 > 0)
678                 {
679                     typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
680                     if(rw.ptr)
681                     {
682                         int x1src = rsrc.x1;
683                         int x1dst = rdst.x1;
684                         int len   = rc.x2;
685                         if(rw.x1 > x1src)
686                         {
687                             x1dst += rw.x1 - x1src;
688                             len   -= rw.x1 - x1src;
689                             x1src  = rw.x1;
690                         }
691                         if(len > 0)
692                         {
693                             if(x1src + len-1 > rw.x2)
694                             {
695                                 len -= x1src + len - rw.x2 - 1;
696                             }
697                             if(len > 0)
698                             {
699                                 m_ren->blend_from_lut(src,
700                                                       color_lut,
701                                                       x1dst, rdst.y1,
702                                                       x1src, rsrc.y1,
703                                                       len,
704                                                       cover);
705                             }
706                         }
707                     }
708                     rdst.y1 += incy;
709                     rsrc.y1 += incy;
710                     --rc.y2;
711                 }
712             }
713         }
714 
715     private:
716         pixfmt_type* m_ren;
717         rect_i       m_clip_box;
718     };
719 
720 
721 }
722 
723 #endif
724