1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 #ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
16 #define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
18 #include "agg_array.h"
20 #include "agg_line_aa_basics.h"
21 #include "agg_dda_line.h"
22 #include "agg_rendering_buffer.h"
23 #include "agg_clip_liang_barsky.h"
28 //========================================================line_image_scale
29 template<class Source
> class line_image_scale
32 typedef typename
Source::color_type color_type
;
34 line_image_scale(const Source
& src
, double height
) :
37 m_scale(src
.height() / height
)
41 double width() const { return m_source
.width(); }
42 double height() const { return m_height
; }
44 color_type
pixel(int x
, int y
) const
46 double src_y
= (y
+ 0.5) * m_scale
- 0.5;
47 int h
= m_source
.height() - 1;
48 int y1
= ufloor(src_y
);
50 color_type pix1
= (y1
< 0) ? color_type::no_color() : m_source
.pixel(x
, y1
);
51 color_type pix2
= (y2
> h
) ? color_type::no_color() : m_source
.pixel(x
, y2
);
52 return pix1
.gradient(pix2
, src_y
- y1
);
56 line_image_scale(const line_image_scale
<Source
>&);
57 const line_image_scale
<Source
>& operator = (const line_image_scale
<Source
>&);
59 const Source
& m_source
;
66 //======================================================line_image_pattern
67 template<class Filter
> class line_image_pattern
70 typedef Filter filter_type
;
71 typedef typename
filter_type::color_type color_type
;
73 //--------------------------------------------------------------------
74 line_image_pattern(const Filter
& filter
) :
76 m_dilation(filter
.dilation() + 1),
77 m_dilation_hr(m_dilation
<< line_subpixel_shift
),
88 //--------------------------------------------------------------------
89 template<class Source
>
90 line_image_pattern(const Filter
& filter
, const Source
& src
) :
92 m_dilation(filter
.dilation() + 1),
93 m_dilation_hr(m_dilation
<< line_subpixel_shift
),
105 //--------------------------------------------------------------------
106 template<class Source
> void create(const Source
& src
)
108 m_height
= uceil(src
.height());
109 m_width
= uceil(src
.width());
110 m_width_hr
= uround(src
.width() * line_subpixel_scale
);
111 m_half_height_hr
= uround(src
.height() * line_subpixel_scale
/2);
112 m_offset_y_hr
= m_dilation_hr
+ m_half_height_hr
- line_subpixel_scale
/2;
113 m_half_height_hr
+= line_subpixel_scale
/2;
115 m_data
.resize((m_width
+ m_dilation
* 2) * (m_height
+ m_dilation
* 2));
117 m_buf
.attach(&m_data
[0], m_width
+ m_dilation
* 2,
118 m_height
+ m_dilation
* 2,
119 m_width
+ m_dilation
* 2);
123 for(y
= 0; y
< m_height
; y
++)
125 d1
= m_buf
.row_ptr(y
+ m_dilation
) + m_dilation
;
126 for(x
= 0; x
< m_width
; x
++)
128 *d1
++ = src
.pixel(x
, y
);
132 const color_type
* s1
;
133 const color_type
* s2
;
134 for(y
= 0; y
< m_dilation
; y
++)
136 //s1 = m_buf.row_ptr(m_height + m_dilation - 1) + m_dilation;
137 //s2 = m_buf.row_ptr(m_dilation) + m_dilation;
138 d1
= m_buf
.row_ptr(m_dilation
+ m_height
+ y
) + m_dilation
;
139 d2
= m_buf
.row_ptr(m_dilation
- y
- 1) + m_dilation
;
140 for(x
= 0; x
< m_width
; x
++)
142 //*d1++ = color_type(*s1++, 0);
143 //*d2++ = color_type(*s2++, 0);
144 *d1
++ = color_type::no_color();
145 *d2
++ = color_type::no_color();
149 unsigned h
= m_height
+ m_dilation
* 2;
150 for(y
= 0; y
< h
; y
++)
152 s1
= m_buf
.row_ptr(y
) + m_dilation
;
153 s2
= m_buf
.row_ptr(y
) + m_dilation
+ m_width
;
154 d1
= m_buf
.row_ptr(y
) + m_dilation
+ m_width
;
155 d2
= m_buf
.row_ptr(y
) + m_dilation
;
157 for(x
= 0; x
< m_dilation
; x
++)
165 //--------------------------------------------------------------------
166 int pattern_width() const { return m_width_hr
; }
167 int line_width() const { return m_half_height_hr
; }
168 double width() const { return m_height
; }
170 //--------------------------------------------------------------------
171 void pixel(color_type
* p
, int x
, int y
) const
173 m_filter
->pixel_high_res(m_buf
.rows(),
175 x
% m_width_hr
+ m_dilation_hr
,
179 //--------------------------------------------------------------------
180 const filter_type
& filter() const { return *m_filter
; }
183 line_image_pattern(const line_image_pattern
<filter_type
>&);
184 const line_image_pattern
<filter_type
>&
185 operator = (const line_image_pattern
<filter_type
>&);
188 row_ptr_cache
<color_type
> m_buf
;
189 const filter_type
* m_filter
;
192 pod_array
<color_type
> m_data
;
196 int m_half_height_hr
;
205 //=================================================line_image_pattern_pow2
206 template<class Filter
> class line_image_pattern_pow2
:
207 public line_image_pattern
<Filter
>
210 typedef Filter filter_type
;
211 typedef typename
filter_type::color_type color_type
;
212 typedef line_image_pattern
<Filter
> base_type
;
214 //--------------------------------------------------------------------
215 line_image_pattern_pow2(const Filter
& filter
) :
216 line_image_pattern
<Filter
>(filter
), m_mask(line_subpixel_mask
) {}
218 //--------------------------------------------------------------------
219 template<class Source
>
220 line_image_pattern_pow2(const Filter
& filter
, const Source
& src
) :
221 line_image_pattern
<Filter
>(filter
), m_mask(line_subpixel_mask
)
226 //--------------------------------------------------------------------
227 template<class Source
> void create(const Source
& src
)
229 line_image_pattern
<Filter
>::create(src
);
231 while(m_mask
< base_type::m_width
)
236 m_mask
<<= line_subpixel_shift
- 1;
237 m_mask
|= line_subpixel_mask
;
238 base_type::m_width_hr
= m_mask
+ 1;
241 //--------------------------------------------------------------------
242 void pixel(color_type
* p
, int x
, int y
) const
244 base_type::m_filter
->pixel_high_res(
245 base_type::m_buf
.rows(),
247 (x
& m_mask
) + base_type::m_dilation_hr
,
248 y
+ base_type::m_offset_y_hr
);
260 //===================================================distance_interpolator4
261 class distance_interpolator4
264 //---------------------------------------------------------------------
265 distance_interpolator4() {}
266 distance_interpolator4(int x1
, int y1
, int x2
, int y2
,
267 int sx
, int sy
, int ex
, int ey
,
268 int len
, double scale
, int x
, int y
) :
271 m_dx_start(line_mr(sx
) - line_mr(x1
)),
272 m_dy_start(line_mr(sy
) - line_mr(y1
)),
273 m_dx_end(line_mr(ex
) - line_mr(x2
)),
274 m_dy_end(line_mr(ey
) - line_mr(y2
)),
276 m_dist(iround(double(x
+ line_subpixel_scale
/2 - x2
) * double(m_dy
) -
277 double(y
+ line_subpixel_scale
/2 - y2
) * double(m_dx
))),
279 m_dist_start((line_mr(x
+ line_subpixel_scale
/2) - line_mr(sx
)) * m_dy_start
-
280 (line_mr(y
+ line_subpixel_scale
/2) - line_mr(sy
)) * m_dx_start
),
282 m_dist_end((line_mr(x
+ line_subpixel_scale
/2) - line_mr(ex
)) * m_dy_end
-
283 (line_mr(y
+ line_subpixel_scale
/2) - line_mr(ey
)) * m_dx_end
),
284 m_len(uround(len
/ scale
))
286 double d
= len
* scale
;
287 int dx
= iround(((x2
- x1
) << line_subpixel_shift
) / d
);
288 int dy
= iround(((y2
- y1
) << line_subpixel_shift
) / d
);
291 m_dist_pict
= ((x
+ line_subpixel_scale
/2 - (x1
- dy
)) * m_dy_pict
-
292 (y
+ line_subpixel_scale
/2 - (y1
+ dx
)) * m_dx_pict
) >>
295 m_dx
<<= line_subpixel_shift
;
296 m_dy
<<= line_subpixel_shift
;
297 m_dx_start
<<= line_mr_subpixel_shift
;
298 m_dy_start
<<= line_mr_subpixel_shift
;
299 m_dx_end
<<= line_mr_subpixel_shift
;
300 m_dy_end
<<= line_mr_subpixel_shift
;
303 //---------------------------------------------------------------------
307 m_dist_start
+= m_dy_start
;
308 m_dist_pict
+= m_dy_pict
;
309 m_dist_end
+= m_dy_end
;
312 //---------------------------------------------------------------------
316 m_dist_start
-= m_dy_start
;
317 m_dist_pict
-= m_dy_pict
;
318 m_dist_end
-= m_dy_end
;
321 //---------------------------------------------------------------------
325 m_dist_start
-= m_dx_start
;
326 m_dist_pict
-= m_dx_pict
;
327 m_dist_end
-= m_dx_end
;
330 //---------------------------------------------------------------------
334 m_dist_start
+= m_dx_start
;
335 m_dist_pict
+= m_dx_pict
;
336 m_dist_end
+= m_dx_end
;
339 //---------------------------------------------------------------------
343 m_dist_start
+= m_dy_start
;
344 m_dist_pict
+= m_dy_pict
;
345 m_dist_end
+= m_dy_end
;
349 m_dist_start
-= m_dx_start
;
350 m_dist_pict
-= m_dx_pict
;
351 m_dist_end
-= m_dx_end
;
356 m_dist_start
+= m_dx_start
;
357 m_dist_pict
+= m_dx_pict
;
358 m_dist_end
+= m_dx_end
;
362 //---------------------------------------------------------------------
366 m_dist_start
-= m_dy_start
;
367 m_dist_pict
-= m_dy_pict
;
368 m_dist_end
-= m_dy_end
;
372 m_dist_start
-= m_dx_start
;
373 m_dist_pict
-= m_dx_pict
;
374 m_dist_end
-= m_dx_end
;
379 m_dist_start
+= m_dx_start
;
380 m_dist_pict
+= m_dx_pict
;
381 m_dist_end
+= m_dx_end
;
385 //---------------------------------------------------------------------
389 m_dist_start
-= m_dx_start
;
390 m_dist_pict
-= m_dx_pict
;
391 m_dist_end
-= m_dx_end
;
395 m_dist_start
+= m_dy_start
;
396 m_dist_pict
+= m_dy_pict
;
397 m_dist_end
+= m_dy_end
;
402 m_dist_start
-= m_dy_start
;
403 m_dist_pict
-= m_dy_pict
;
404 m_dist_end
-= m_dy_end
;
408 //---------------------------------------------------------------------
412 m_dist_start
+= m_dx_start
;
413 m_dist_pict
+= m_dx_pict
;
414 m_dist_end
+= m_dx_end
;
418 m_dist_start
+= m_dy_start
;
419 m_dist_pict
+= m_dy_pict
;
420 m_dist_end
+= m_dy_end
;
425 m_dist_start
-= m_dy_start
;
426 m_dist_pict
-= m_dy_pict
;
427 m_dist_end
-= m_dy_end
;
431 //---------------------------------------------------------------------
432 int dist() const { return m_dist
; }
433 int dist_start() const { return m_dist_start
; }
434 int dist_pict() const { return m_dist_pict
; }
435 int dist_end() const { return m_dist_end
; }
437 //---------------------------------------------------------------------
438 int dx() const { return m_dx
; }
439 int dy() const { return m_dy
; }
440 int dx_start() const { return m_dx_start
; }
441 int dy_start() const { return m_dy_start
; }
442 int dx_pict() const { return m_dx_pict
; }
443 int dy_pict() const { return m_dy_pict
; }
444 int dx_end() const { return m_dx_end
; }
445 int dy_end() const { return m_dy_end
; }
446 int len() const { return m_len
; }
449 //---------------------------------------------------------------------
470 //==================================================line_interpolator_image
471 template<class Renderer
> class line_interpolator_image
474 typedef Renderer renderer_type
;
475 typedef typename
Renderer::color_type color_type
;
477 //---------------------------------------------------------------------
478 enum max_half_width_e
483 //---------------------------------------------------------------------
484 line_interpolator_image(renderer_type
& ren
, const line_parameters
& lp
,
485 int sx
, int sy
, int ex
, int ey
,
489 m_li(lp
.vertical
? line_dbl_hr(lp
.x2
- lp
.x1
) :
490 line_dbl_hr(lp
.y2
- lp
.y1
),
491 lp
.vertical
? abs(lp
.y2
- lp
.y1
) :
492 abs(lp
.x2
- lp
.x1
) + 1),
493 m_di(lp
.x1
, lp
.y1
, lp
.x2
, lp
.y2
, sx
, sy
, ex
, ey
, lp
.len
, scale_x
,
494 lp
.x1
& ~line_subpixel_mask
, lp
.y1
& ~line_subpixel_mask
),
496 m_x(lp
.x1
>> line_subpixel_shift
),
497 m_y(lp
.y1
>> line_subpixel_shift
),
500 m_count((lp
.vertical
? abs((lp
.y2
>> line_subpixel_shift
) - m_y
) :
501 abs((lp
.x2
>> line_subpixel_shift
) - m_x
))),
502 m_width(ren
.subpixel_width()),
503 //m_max_extent(m_width >> (line_subpixel_shift - 2)),
504 m_max_extent((m_width
+ line_subpixel_scale
) >> line_subpixel_shift
),
505 m_start(pattern_start
+ (m_max_extent
+ 2) * ren
.pattern_width()),
508 agg::dda2_line_interpolator
li(0, lp
.vertical
?
509 (lp
.dy
<< agg::line_subpixel_shift
) :
510 (lp
.dx
<< agg::line_subpixel_shift
),
514 int stop
= m_width
+ line_subpixel_scale
* 2;
515 for(i
= 0; i
< max_half_width
; ++i
)
517 m_dist_pos
[i
] = li
.y();
518 if(m_dist_pos
[i
] >= stop
) break;
521 m_dist_pos
[i
] = 0x7FFF0000;
533 m_x
= (m_lp
.x1
+ m_li
.y()) >> line_subpixel_shift
;
535 if(lp
.inc
> 0) m_di
.dec_y(m_x
- m_old_x
);
536 else m_di
.inc_y(m_x
- m_old_x
);
540 dist1_start
= dist2_start
= m_di
.dist_start();
543 if(dist1_start
< 0) ++npix
;
546 dist1_start
+= m_di
.dy_start();
547 dist2_start
-= m_di
.dy_start();
548 if(dist1_start
< 0) ++npix
;
549 if(dist2_start
< 0) ++npix
;
552 while(m_dist_pos
[dx
] <= m_width
);
557 while(--m_step
>= -m_max_extent
);
566 m_y
= (m_lp
.y1
+ m_li
.y()) >> line_subpixel_shift
;
568 if(lp
.inc
> 0) m_di
.dec_x(m_y
- m_old_y
);
569 else m_di
.inc_x(m_y
- m_old_y
);
573 dist1_start
= dist2_start
= m_di
.dist_start();
576 if(dist1_start
< 0) ++npix
;
579 dist1_start
-= m_di
.dx_start();
580 dist2_start
+= m_di
.dx_start();
581 if(dist1_start
< 0) ++npix
;
582 if(dist2_start
< 0) ++npix
;
585 while(m_dist_pos
[dy
] <= m_width
);
590 while(--m_step
>= -m_max_extent
);
592 m_li
.adjust_forward();
593 m_step
-= m_max_extent
;
596 //---------------------------------------------------------------------
601 m_y
= (m_lp
.y1
+ m_li
.y()) >> line_subpixel_shift
;
603 if(m_lp
.inc
> 0) m_di
.inc_x(m_y
- m_old_y
);
604 else m_di
.dec_x(m_y
- m_old_y
);
608 int s1
= m_di
.dist() / m_lp
.len
;
611 if(m_lp
.inc
< 0) s1
= -s1
;
619 dist_start
= m_di
.dist_start();
620 dist_pict
= m_di
.dist_pict() + m_start
;
621 dist_end
= m_di
.dist_end();
622 color_type
* p0
= m_colors
+ max_half_width
+ 2;
631 m_ren
.pixel(p1
, dist_pict
, s2
);
638 while((dist
= m_dist_pos
[dy
]) - s1
<= m_width
)
640 dist_start
-= m_di
.dx_start();
641 dist_pict
-= m_di
.dx_pict();
642 dist_end
-= m_di
.dx_end();
644 if(dist_end
> 0 && dist_start
<= 0)
646 if(m_lp
.inc
> 0) dist
= -dist
;
647 m_ren
.pixel(p1
, dist_pict
, s2
- dist
);
655 dist_start
= m_di
.dist_start();
656 dist_pict
= m_di
.dist_pict() + m_start
;
657 dist_end
= m_di
.dist_end();
658 while((dist
= m_dist_pos
[dy
]) + s1
<= m_width
)
660 dist_start
+= m_di
.dx_start();
661 dist_pict
+= m_di
.dx_pict();
662 dist_end
+= m_di
.dx_end();
665 if(dist_end
> 0 && dist_start
<= 0)
667 if(m_lp
.inc
> 0) dist
= -dist
;
668 m_ren
.pixel(p0
, dist_pict
, s2
+ dist
);
673 m_ren
.blend_color_vspan(m_x
,
677 return npix
&& ++m_step
< m_count
;
682 //---------------------------------------------------------------------
687 m_x
= (m_lp
.x1
+ m_li
.y()) >> line_subpixel_shift
;
689 if(m_lp
.inc
> 0) m_di
.inc_y(m_x
- m_old_x
);
690 else m_di
.dec_y(m_x
- m_old_x
);
694 int s1
= m_di
.dist() / m_lp
.len
;
697 if(m_lp
.inc
> 0) s1
= -s1
;
705 dist_start
= m_di
.dist_start();
706 dist_pict
= m_di
.dist_pict() + m_start
;
707 dist_end
= m_di
.dist_end();
708 color_type
* p0
= m_colors
+ max_half_width
+ 2;
717 m_ren
.pixel(p1
, dist_pict
, s2
);
724 while((dist
= m_dist_pos
[dx
]) - s1
<= m_width
)
726 dist_start
+= m_di
.dy_start();
727 dist_pict
+= m_di
.dy_pict();
728 dist_end
+= m_di
.dy_end();
730 if(dist_end
> 0 && dist_start
<= 0)
732 if(m_lp
.inc
> 0) dist
= -dist
;
733 m_ren
.pixel(p1
, dist_pict
, s2
+ dist
);
741 dist_start
= m_di
.dist_start();
742 dist_pict
= m_di
.dist_pict() + m_start
;
743 dist_end
= m_di
.dist_end();
744 while((dist
= m_dist_pos
[dx
]) + s1
<= m_width
)
746 dist_start
-= m_di
.dy_start();
747 dist_pict
-= m_di
.dy_pict();
748 dist_end
-= m_di
.dy_end();
751 if(dist_end
> 0 && dist_start
<= 0)
753 if(m_lp
.inc
> 0) dist
= -dist
;
754 m_ren
.pixel(p0
, dist_pict
, s2
- dist
);
759 m_ren
.blend_color_hspan(m_x
- dx
+ 1,
763 return npix
&& ++m_step
< m_count
;
767 //---------------------------------------------------------------------
768 int pattern_end() const { return m_start
+ m_di
.len(); }
770 //---------------------------------------------------------------------
771 bool vertical() const { return m_lp
.vertical
; }
772 int width() const { return m_width
; }
773 int count() const { return m_count
; }
776 line_interpolator_image(const line_interpolator_image
<Renderer
>&);
777 const line_interpolator_image
<Renderer
>&
778 operator = (const line_interpolator_image
<Renderer
>&);
781 const line_parameters
& m_lp
;
782 dda2_line_interpolator m_li
;
783 distance_interpolator4 m_di
;
784 renderer_type
& m_ren
;
795 int m_dist_pos
[max_half_width
+ 1];
796 color_type m_colors
[max_half_width
* 2 + 4];
806 //===================================================renderer_outline_image
807 template<class BaseRenderer
, class ImagePattern
>
808 class renderer_outline_image
811 //---------------------------------------------------------------------
812 typedef BaseRenderer base_ren_type
;
813 typedef renderer_outline_image
<BaseRenderer
, ImagePattern
> self_type
;
814 typedef typename
base_ren_type::color_type color_type
;
815 typedef ImagePattern pattern_type
;
818 //---------------------------------------------------------------------
819 renderer_outline_image(base_ren_type
& ren
, const pattern_type
& patt
) :
827 void attach(base_ren_type
& ren
) { m_ren
= &ren
; }
829 //---------------------------------------------------------------------
830 void pattern(const pattern_type
& p
) { m_pattern
= &p
; }
831 const pattern_type
& pattern() const { return *m_pattern
; }
833 //---------------------------------------------------------------------
834 void reset_clipping() { m_clipping
= false; }
835 void clip_box(double x1
, double y1
, double x2
, double y2
)
837 m_clip_box
.x1
= line_coord_sat::conv(x1
);
838 m_clip_box
.y1
= line_coord_sat::conv(y1
);
839 m_clip_box
.x2
= line_coord_sat::conv(x2
);
840 m_clip_box
.y2
= line_coord_sat::conv(y2
);
844 //---------------------------------------------------------------------
845 void scale_x(double s
) { m_scale_x
= s
; }
846 double scale_x() const { return m_scale_x
; }
848 //---------------------------------------------------------------------
849 void start_x(double s
) { m_start
= iround(s
* line_subpixel_scale
); }
850 double start_x() const { return double(m_start
) / line_subpixel_scale
; }
852 //---------------------------------------------------------------------
853 int subpixel_width() const { return m_pattern
->line_width(); }
854 int pattern_width() const { return m_pattern
->pattern_width(); }
855 double width() const { return double(subpixel_width()) / line_subpixel_scale
; }
857 //-------------------------------------------------------------------------
858 void pixel(color_type
* p
, int x
, int y
) const
860 m_pattern
->pixel(p
, x
, y
);
863 //-------------------------------------------------------------------------
864 void blend_color_hspan(int x
, int y
, unsigned len
, const color_type
* colors
)
866 m_ren
->blend_color_hspan(x
, y
, len
, colors
, 0);
869 //-------------------------------------------------------------------------
870 void blend_color_vspan(int x
, int y
, unsigned len
, const color_type
* colors
)
872 m_ren
->blend_color_vspan(x
, y
, len
, colors
, 0);
875 //-------------------------------------------------------------------------
876 static bool accurate_join_only() { return true; }
878 //-------------------------------------------------------------------------
880 void semidot(Cmp
, int, int, int, int)
884 //-------------------------------------------------------------------------
885 void pie(int, int, int, int, int, int)
889 //-------------------------------------------------------------------------
890 void line0(const line_parameters
&)
894 //-------------------------------------------------------------------------
895 void line1(const line_parameters
&, int, int)
899 //-------------------------------------------------------------------------
900 void line2(const line_parameters
&, int, int)
904 //-------------------------------------------------------------------------
905 void line3_no_clip(const line_parameters
& lp
,
906 int sx
, int sy
, int ex
, int ey
)
908 if(lp
.len
> line_max_length
)
910 line_parameters lp1
, lp2
;
912 int mx
= lp1
.x2
+ (lp1
.y2
- lp1
.y1
);
913 int my
= lp1
.y2
- (lp1
.x2
- lp1
.x1
);
914 line3_no_clip(lp1
, (lp
.x1
+ sx
) >> 1, (lp
.y1
+ sy
) >> 1, mx
, my
);
915 line3_no_clip(lp2
, mx
, my
, (lp
.x2
+ ex
) >> 1, (lp
.y2
+ ey
) >> 1);
919 fix_degenerate_bisectrix_start(lp
, &sx
, &sy
);
920 fix_degenerate_bisectrix_end(lp
, &ex
, &ey
);
921 line_interpolator_image
<self_type
> li(*this, lp
,
927 while(li
.step_ver());
931 while(li
.step_hor());
933 m_start
+= uround(lp
.len
/ m_scale_x
);
936 //-------------------------------------------------------------------------
937 void line3(const line_parameters
& lp
,
938 int sx
, int sy
, int ex
, int ey
)
946 unsigned flags
= clip_line_segment(&x1
, &y1
, &x2
, &y2
, m_clip_box
);
952 line_parameters
lp2(x1
, y1
, x2
, y2
,
953 uround(calc_distance(x1
, y1
, x2
, y2
)));
956 m_start
+= uround(calc_distance(lp
.x1
, lp
.y1
, x1
, y1
) / m_scale_x
);
962 while(abs(sx
- lp
.x1
) + abs(sy
- lp
.y1
) > lp2
.len
)
964 sx
= (lp
.x1
+ sx
) >> 1;
965 sy
= (lp
.y1
+ sy
) >> 1;
975 while(abs(ex
- lp
.x2
) + abs(ey
- lp
.y2
) > lp2
.len
)
977 ex
= (lp
.x2
+ ex
) >> 1;
978 ey
= (lp
.y2
+ ey
) >> 1;
981 line3_no_clip(lp2
, sx
, sy
, ex
, ey
);
985 line3_no_clip(lp
, sx
, sy
, ex
, ey
);
988 m_start
= start
+ uround(lp
.len
/ m_scale_x
);
992 line3_no_clip(lp
, sx
, sy
, ex
, ey
);
997 base_ren_type
* m_ren
;
998 const pattern_type
* m_pattern
;