update dev300-m58
[ooovba.git] / agg / inc / agg_renderer_outline_image.h
blob12bb5bf13f124d001cb308a44a570368402413fb
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 //----------------------------------------------------------------------------
15 #ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
16 #define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
18 #include <math.h>
19 #include "agg_line_aa_basics.h"
20 #include "agg_dda_line.h"
21 #include "agg_rendering_buffer.h"
24 namespace agg
26 //========================================================line_image_scale
27 template<class Source> class line_image_scale
29 public:
30 typedef typename Source::color_type color_type;
32 line_image_scale(const Source& src, double height) :
33 m_source(src),
34 m_height(height),
35 m_scale(src.height() / height)
39 double width() const { return m_source.width(); }
40 double height() const { return m_height; }
42 color_type pixel(int x, int y) const
44 double src_y = (y + 0.5) * m_scale - 0.5;
45 int h = int(m_source.height()) - 1;
46 int y1 = int(floor(src_y));
47 int y2 = y1 + 1;
48 color_type pix1 = (y1 < 0) ? color_type::no_color() : m_source.pixel(x, y1);
49 color_type pix2 = (y2 > h) ? color_type::no_color() : m_source.pixel(x, y2);
50 return pix1.gradient(pix2, src_y - y1);
53 private:
54 line_image_scale(const line_image_scale<Source>&);
55 const line_image_scale<Source>& operator = (const line_image_scale<Source>&);
57 const Source& m_source;
58 double m_height;
59 double m_scale;
64 //======================================================line_image_pattern
65 template<class Filter> class line_image_pattern
67 public:
68 typedef Filter filter_type;
69 typedef typename filter_type::color_type color_type;
71 //--------------------------------------------------------------------
72 ~line_image_pattern()
74 delete [] m_data;
77 //--------------------------------------------------------------------
78 line_image_pattern(const Filter& filter) :
79 m_filter(&filter),
80 m_dilation(filter.dilation() + 1),
81 m_dilation_hr(m_dilation << line_subpixel_shift),
82 m_data(0),
83 m_width(0),
84 m_height(0),
85 m_width_hr(0),
86 m_half_height_hr(0),
87 m_offset_y_hr(0)
91 // Create
92 //--------------------------------------------------------------------
93 template<class Source>
94 line_image_pattern(const Filter& filter, const Source& src) :
95 m_filter(&filter),
96 m_dilation(filter.dilation() + 1),
97 m_dilation_hr(m_dilation << line_subpixel_shift),
98 m_data(0),
99 m_width(0),
100 m_height(0),
101 m_width_hr(0),
102 m_half_height_hr(0),
103 m_offset_y_hr(0)
105 create(src);
108 // Create
109 //--------------------------------------------------------------------
110 template<class Source> void create(const Source& src)
112 m_height = unsigned(ceil((double)src.height()));
113 m_width = unsigned(ceil((double)src.width()));
114 m_width_hr = int(src.width() * line_subpixel_size);
115 m_half_height_hr = int(src.height() * line_subpixel_size/2);
116 m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_size/2;
117 m_half_height_hr += line_subpixel_size/2;
119 delete [] m_data;
120 m_data = new color_type [(m_width + m_dilation * 2) * (m_height + m_dilation * 2)];
122 m_buf.attach(m_data, m_width + m_dilation * 2,
123 m_height + m_dilation * 2,
124 m_width + m_dilation * 2);
125 unsigned x, y;
126 color_type* d1;
127 color_type* d2;
128 for(y = 0; y < m_height; y++)
130 d1 = m_buf.row(y + m_dilation) + m_dilation;
131 for(x = 0; x < m_width; x++)
133 *d1++ = src.pixel(x, y);
137 const color_type* s1;
138 const color_type* s2;
139 for(y = 0; y < m_dilation; y++)
141 //s1 = m_buf.row(m_height + m_dilation - 1) + m_dilation;
142 //s2 = m_buf.row(m_dilation) + m_dilation;
143 d1 = m_buf.row(m_dilation + m_height + y) + m_dilation;
144 d2 = m_buf.row(m_dilation - y - 1) + m_dilation;
145 for(x = 0; x < m_width; x++)
147 //*d1++ = color_type(*s1++, 0);
148 //*d2++ = color_type(*s2++, 0);
149 *d1++ = color_type::no_color();
150 *d2++ = color_type::no_color();
154 unsigned h = m_height + m_dilation * 2;
155 for(y = 0; y < h; y++)
157 s1 = m_buf.row(y) + m_dilation;
158 s2 = m_buf.row(y) + m_dilation + m_width;
159 d1 = m_buf.row(y) + m_dilation + m_width;
160 d2 = m_buf.row(y) + m_dilation;
162 for(x = 0; x < m_dilation; x++)
164 *d1++ = *s1++;
165 *--d2 = *--s2;
170 //--------------------------------------------------------------------
171 int pattern_width() const { return m_width_hr; }
172 int line_width() const { return m_half_height_hr; }
174 //--------------------------------------------------------------------
175 void pixel(color_type* p, int x, int y) const
177 m_filter->pixel_high_res(m_buf.rows(),
179 x % m_width_hr + m_dilation_hr,
180 y + m_offset_y_hr);
183 //--------------------------------------------------------------------
184 const filter_type& filter() const { return *m_filter; }
186 private:
187 line_image_pattern(const line_image_pattern<filter_type>&);
188 const line_image_pattern<filter_type>&
189 operator = (const line_image_pattern<filter_type>&);
191 protected:
192 row_ptr_cache<color_type> m_buf;
193 const filter_type* m_filter;
194 unsigned m_dilation;
195 int m_dilation_hr;
196 color_type* m_data;
197 unsigned m_width;
198 unsigned m_height;
199 int m_width_hr;
200 int m_half_height_hr;
201 int m_offset_y_hr;
209 //=================================================line_image_pattern_pow2
210 template<class Filter> class line_image_pattern_pow2 :
211 public line_image_pattern<Filter>
213 public:
214 typedef Filter filter_type;
215 typedef typename filter_type::color_type color_type;
216 typedef line_image_pattern<Filter> base_type;
218 //--------------------------------------------------------------------
219 line_image_pattern_pow2(const Filter& filter) :
220 line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask) {}
222 //--------------------------------------------------------------------
223 template<class Source>
224 line_image_pattern_pow2(const Filter& filter, const Source& src) :
225 line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask)
227 create(src);
230 //--------------------------------------------------------------------
231 template<class Source> void create(const Source& src)
233 line_image_pattern<Filter>::create(src);
234 m_mask = 1;
235 while(m_mask < base_type::m_width)
237 m_mask <<= 1;
238 m_mask |= 1;
240 m_mask <<= line_subpixel_shift - 1;
241 m_mask |= line_subpixel_mask;
242 base_type::m_width_hr = m_mask + 1;
245 //--------------------------------------------------------------------
246 void pixel(color_type* p, int x, int y) const
248 base_type::m_filter->pixel_high_res(
249 base_type::m_buf.rows(),
251 (x & m_mask) + base_type::m_dilation_hr,
252 y + base_type::m_offset_y_hr);
254 private:
255 unsigned m_mask;
264 //===================================================distance_interpolator4
265 class distance_interpolator4
267 public:
268 //---------------------------------------------------------------------
269 distance_interpolator4() {}
270 distance_interpolator4(int x1, int y1, int x2, int y2,
271 int sx, int sy, int ex, int ey,
272 int len, double scale, int x, int y) :
273 m_dx(x2 - x1),
274 m_dy(y2 - y1),
275 m_dx_start(line_mr(sx) - line_mr(x1)),
276 m_dy_start(line_mr(sy) - line_mr(y1)),
277 m_dx_end(line_mr(ex) - line_mr(x2)),
278 m_dy_end(line_mr(ey) - line_mr(y2)),
280 m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
281 double(y + line_subpixel_size/2 - y2) * double(m_dx))),
283 m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
284 (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start),
286 m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end -
287 (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end),
288 m_len(int(len / scale))
290 double d = len * scale;
291 int dx = int(((x2 - x1) << line_subpixel_shift) / d);
292 int dy = int(((y2 - y1) << line_subpixel_shift) / d);
293 m_dx_pict = -dy;
294 m_dy_pict = dx;
295 m_dist_pict = ((x + line_subpixel_size/2 - (x1 - dy)) * m_dy_pict -
296 (y + line_subpixel_size/2 - (y1 + dx)) * m_dx_pict) >>
297 line_subpixel_shift;
299 m_dx <<= line_subpixel_shift;
300 m_dy <<= line_subpixel_shift;
301 m_dx_start <<= line_mr_subpixel_shift;
302 m_dy_start <<= line_mr_subpixel_shift;
303 m_dx_end <<= line_mr_subpixel_shift;
304 m_dy_end <<= line_mr_subpixel_shift;
307 //---------------------------------------------------------------------
308 void inc_x()
310 m_dist += m_dy;
311 m_dist_start += m_dy_start;
312 m_dist_pict += m_dy_pict;
313 m_dist_end += m_dy_end;
316 //---------------------------------------------------------------------
317 void dec_x()
319 m_dist -= m_dy;
320 m_dist_start -= m_dy_start;
321 m_dist_pict -= m_dy_pict;
322 m_dist_end -= m_dy_end;
325 //---------------------------------------------------------------------
326 void inc_y()
328 m_dist -= m_dx;
329 m_dist_start -= m_dx_start;
330 m_dist_pict -= m_dx_pict;
331 m_dist_end -= m_dx_end;
334 //---------------------------------------------------------------------
335 void dec_y()
337 m_dist += m_dx;
338 m_dist_start += m_dx_start;
339 m_dist_pict += m_dx_pict;
340 m_dist_end += m_dx_end;
343 //---------------------------------------------------------------------
344 void inc_x(int dy)
346 m_dist += m_dy;
347 m_dist_start += m_dy_start;
348 m_dist_pict += m_dy_pict;
349 m_dist_end += m_dy_end;
350 if(dy > 0)
352 m_dist -= m_dx;
353 m_dist_start -= m_dx_start;
354 m_dist_pict -= m_dx_pict;
355 m_dist_end -= m_dx_end;
357 if(dy < 0)
359 m_dist += m_dx;
360 m_dist_start += m_dx_start;
361 m_dist_pict += m_dx_pict;
362 m_dist_end += m_dx_end;
366 //---------------------------------------------------------------------
367 void dec_x(int dy)
369 m_dist -= m_dy;
370 m_dist_start -= m_dy_start;
371 m_dist_pict -= m_dy_pict;
372 m_dist_end -= m_dy_end;
373 if(dy > 0)
375 m_dist -= m_dx;
376 m_dist_start -= m_dx_start;
377 m_dist_pict -= m_dx_pict;
378 m_dist_end -= m_dx_end;
380 if(dy < 0)
382 m_dist += m_dx;
383 m_dist_start += m_dx_start;
384 m_dist_pict += m_dx_pict;
385 m_dist_end += m_dx_end;
389 //---------------------------------------------------------------------
390 void inc_y(int dx)
392 m_dist -= m_dx;
393 m_dist_start -= m_dx_start;
394 m_dist_pict -= m_dx_pict;
395 m_dist_end -= m_dx_end;
396 if(dx > 0)
398 m_dist += m_dy;
399 m_dist_start += m_dy_start;
400 m_dist_pict += m_dy_pict;
401 m_dist_end += m_dy_end;
403 if(dx < 0)
405 m_dist -= m_dy;
406 m_dist_start -= m_dy_start;
407 m_dist_pict -= m_dy_pict;
408 m_dist_end -= m_dy_end;
412 //---------------------------------------------------------------------
413 void dec_y(int dx)
415 m_dist += m_dx;
416 m_dist_start += m_dx_start;
417 m_dist_pict += m_dx_pict;
418 m_dist_end += m_dx_end;
419 if(dx > 0)
421 m_dist += m_dy;
422 m_dist_start += m_dy_start;
423 m_dist_pict += m_dy_pict;
424 m_dist_end += m_dy_end;
426 if(dx < 0)
428 m_dist -= m_dy;
429 m_dist_start -= m_dy_start;
430 m_dist_pict -= m_dy_pict;
431 m_dist_end -= m_dy_end;
435 //---------------------------------------------------------------------
436 int dist() const { return m_dist; }
437 int dist_start() const { return m_dist_start; }
438 int dist_pict() const { return m_dist_pict; }
439 int dist_end() const { return m_dist_end; }
441 //---------------------------------------------------------------------
442 int dx() const { return m_dx; }
443 int dy() const { return m_dy; }
444 int dx_start() const { return m_dx_start; }
445 int dy_start() const { return m_dy_start; }
446 int dx_pict() const { return m_dx_pict; }
447 int dy_pict() const { return m_dy_pict; }
448 int dx_end() const { return m_dx_end; }
449 int dy_end() const { return m_dy_end; }
450 int len() const { return m_len; }
452 private:
453 //---------------------------------------------------------------------
454 int m_dx;
455 int m_dy;
456 int m_dx_start;
457 int m_dy_start;
458 int m_dx_pict;
459 int m_dy_pict;
460 int m_dx_end;
461 int m_dy_end;
463 int m_dist;
464 int m_dist_start;
465 int m_dist_pict;
466 int m_dist_end;
467 int m_len;
474 //==================================================line_interpolator_image
475 template<class Renderer> class line_interpolator_image
477 public:
478 typedef Renderer renderer_type;
479 typedef typename Renderer::color_type color_type;
481 //---------------------------------------------------------------------
482 enum
484 max_half_width = 64
487 //---------------------------------------------------------------------
488 line_interpolator_image(renderer_type& ren, const line_parameters& lp,
489 int sx, int sy, int ex, int ey,
490 int pattern_start,
491 double scale_x) :
492 m_lp(lp),
493 m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
494 line_dbl_hr(lp.y2 - lp.y1),
495 lp.vertical ? abs(lp.y2 - lp.y1) :
496 abs(lp.x2 - lp.x1) + 1),
497 m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x,
498 lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask),
499 m_ren(ren),
500 m_x(lp.x1 >> line_subpixel_shift),
501 m_y(lp.y1 >> line_subpixel_shift),
502 m_old_x(m_x),
503 m_old_y(m_y),
504 m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
505 abs((lp.x2 >> line_subpixel_shift) - m_x))),
506 m_width(ren.subpixel_width()),
507 m_max_extent(m_width >> (line_subpixel_shift - 2)),
508 m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()),
509 m_step(0)
511 agg::dda2_line_interpolator li(0, lp.vertical ?
512 (lp.dy << agg::line_subpixel_shift) :
513 (lp.dx << agg::line_subpixel_shift),
514 lp.len);
516 unsigned i;
517 int stop = m_width + line_subpixel_size * 2;
518 for(i = 0; i < max_half_width; ++i)
520 m_dist_pos[i] = li.y();
521 if(m_dist_pos[i] >= stop) break;
522 ++li;
524 m_dist_pos[i] = 0x7FFF0000;
526 int dist1_start;
527 int dist2_start;
528 int npix = 1;
530 if(lp.vertical)
534 --m_li;
535 m_y -= lp.inc;
536 m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;
538 if(lp.inc > 0) m_di.dec_y(m_x - m_old_x);
539 else m_di.inc_y(m_x - m_old_x);
541 m_old_x = m_x;
543 dist1_start = dist2_start = m_di.dist_start();
545 int dx = 0;
546 if(dist1_start < 0) ++npix;
549 dist1_start += m_di.dy_start();
550 dist2_start -= m_di.dy_start();
551 if(dist1_start < 0) ++npix;
552 if(dist2_start < 0) ++npix;
553 ++dx;
555 while(m_dist_pos[dx] <= m_width);
556 if(npix == 0) break;
558 npix = 0;
560 while(--m_step >= -m_max_extent);
562 else
566 --m_li;
568 m_x -= lp.inc;
569 m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;
571 if(lp.inc > 0) m_di.dec_x(m_y - m_old_y);
572 else m_di.inc_x(m_y - m_old_y);
574 m_old_y = m_y;
576 dist1_start = dist2_start = m_di.dist_start();
578 int dy = 0;
579 if(dist1_start < 0) ++npix;
582 dist1_start -= m_di.dx_start();
583 dist2_start += m_di.dx_start();
584 if(dist1_start < 0) ++npix;
585 if(dist2_start < 0) ++npix;
586 ++dy;
588 while(m_dist_pos[dy] <= m_width);
589 if(npix == 0) break;
591 npix = 0;
593 while(--m_step >= -m_max_extent);
595 m_li.adjust_forward();
596 m_step -= m_max_extent;
599 //---------------------------------------------------------------------
600 bool step_hor()
602 ++m_li;
603 m_x += m_lp.inc;
604 m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;
606 if(m_lp.inc > 0) m_di.inc_x(m_y - m_old_y);
607 else m_di.dec_x(m_y - m_old_y);
609 m_old_y = m_y;
611 int s1 = m_di.dist() / m_lp.len;
612 int s2 = -s1;
614 if(m_lp.inc < 0) s1 = -s1;
616 int dist_start;
617 int dist_pict;
618 int dist_end;
619 int dy;
620 int dist;
622 dist_start = m_di.dist_start();
623 dist_pict = m_di.dist_pict() + m_start;
624 dist_end = m_di.dist_end();
625 color_type* p0 = m_colors + max_half_width + 2;
626 color_type* p1 = p0;
628 int npix = 0;
629 p1->clear();
630 if(dist_end > 0)
632 if(dist_start <= 0)
634 m_ren.pixel(p1, dist_pict, s2);
636 ++npix;
638 ++p1;
640 dy = 1;
641 while((dist = m_dist_pos[dy]) - s1 <= m_width)
643 dist_start -= m_di.dx_start();
644 dist_pict -= m_di.dx_pict();
645 dist_end -= m_di.dx_end();
646 p1->clear();
647 if(dist_end > 0 && dist_start <= 0)
649 if(m_lp.inc > 0) dist = -dist;
650 m_ren.pixel(p1, dist_pict, s2 - dist);
651 ++npix;
653 ++p1;
654 ++dy;
657 dy = 1;
658 dist_start = m_di.dist_start();
659 dist_pict = m_di.dist_pict() + m_start;
660 dist_end = m_di.dist_end();
661 while((dist = m_dist_pos[dy]) + s1 <= m_width)
663 dist_start += m_di.dx_start();
664 dist_pict += m_di.dx_pict();
665 dist_end += m_di.dx_end();
666 --p0;
667 p0->clear();
668 if(dist_end > 0 && dist_start <= 0)
670 if(m_lp.inc > 0) dist = -dist;
671 m_ren.pixel(p0, dist_pict, s2 + dist);
672 ++npix;
674 ++dy;
676 m_ren.blend_color_vspan(m_x,
677 m_y - dy + 1,
678 unsigned(p1 - p0),
679 p0);
680 return npix && ++m_step < m_count;
685 //---------------------------------------------------------------------
686 bool step_ver()
688 ++m_li;
689 m_y += m_lp.inc;
690 m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;
692 if(m_lp.inc > 0) m_di.inc_y(m_x - m_old_x);
693 else m_di.dec_y(m_x - m_old_x);
695 m_old_x = m_x;
697 int s1 = m_di.dist() / m_lp.len;
698 int s2 = -s1;
700 if(m_lp.inc > 0) s1 = -s1;
702 int dist_start;
703 int dist_pict;
704 int dist_end;
705 int dist;
706 int dx;
708 dist_start = m_di.dist_start();
709 dist_pict = m_di.dist_pict() + m_start;
710 dist_end = m_di.dist_end();
711 color_type* p0 = m_colors + max_half_width + 2;
712 color_type* p1 = p0;
714 int npix = 0;
715 p1->clear();
716 if(dist_end > 0)
718 if(dist_start <= 0)
720 m_ren.pixel(p1, dist_pict, s2);
722 ++npix;
724 ++p1;
726 dx = 1;
727 while((dist = m_dist_pos[dx]) - s1 <= m_width)
729 dist_start += m_di.dy_start();
730 dist_pict += m_di.dy_pict();
731 dist_end += m_di.dy_end();
732 p1->clear();
733 if(dist_end > 0 && dist_start <= 0)
735 if(m_lp.inc > 0) dist = -dist;
736 m_ren.pixel(p1, dist_pict, s2 + dist);
737 ++npix;
739 ++p1;
740 ++dx;
743 dx = 1;
744 dist_start = m_di.dist_start();
745 dist_pict = m_di.dist_pict() + m_start;
746 dist_end = m_di.dist_end();
747 while((dist = m_dist_pos[dx]) + s1 <= m_width)
749 dist_start -= m_di.dy_start();
750 dist_pict -= m_di.dy_pict();
751 dist_end -= m_di.dy_end();
752 --p0;
753 p0->clear();
754 if(dist_end > 0 && dist_start <= 0)
756 if(m_lp.inc > 0) dist = -dist;
757 m_ren.pixel(p0, dist_pict, s2 - dist);
758 ++npix;
760 ++dx;
762 m_ren.blend_color_hspan(m_x - dx + 1,
763 m_y,
764 unsigned(p1 - p0),
765 p0);
766 return npix && ++m_step < m_count;
770 //---------------------------------------------------------------------
771 int pattern_end() const { return m_start + m_di.len(); }
773 //---------------------------------------------------------------------
774 bool vertical() const { return m_lp.vertical; }
775 int width() const { return m_width; }
776 int count() const { return m_count; }
778 private:
779 line_interpolator_image(const line_interpolator_image<Renderer>&);
780 const line_interpolator_image<Renderer>&
781 operator = (const line_interpolator_image<Renderer>&);
783 protected:
784 const line_parameters& m_lp;
785 dda2_line_interpolator m_li;
786 distance_interpolator4 m_di;
787 renderer_type& m_ren;
788 int m_plen;
789 int m_x;
790 int m_y;
791 int m_old_x;
792 int m_old_y;
793 int m_count;
794 int m_width;
795 int m_max_extent;
796 int m_start;
797 int m_step;
798 int m_dist_pos[max_half_width + 1];
799 color_type m_colors[max_half_width * 2 + 4];
809 //===================================================renderer_outline_image
810 template<class BaseRenderer, class ImagePattern>
811 class renderer_outline_image
813 public:
814 //---------------------------------------------------------------------
815 typedef BaseRenderer base_ren_type;
816 typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type;
817 typedef typename base_ren_type::color_type color_type;
818 typedef ImagePattern pattern_type;
821 //---------------------------------------------------------------------
822 renderer_outline_image(base_ren_type& ren, const pattern_type& patt) :
823 m_ren(&ren),
824 m_pattern(&patt),
825 m_start(0),
826 m_scale_x(1.0)
830 //---------------------------------------------------------------------
831 void pattern(const pattern_type& p) { m_pattern = &p; }
832 const pattern_type& pattern() const { return *m_pattern; }
834 //---------------------------------------------------------------------
835 void scale_x(double s) { m_scale_x = s; }
836 double scale_x() const { return m_scale_x; }
838 //---------------------------------------------------------------------
839 void start_x(double s) { m_start = int(s * line_subpixel_size); }
840 double start_x() const { return double(m_start) / line_subpixel_size; }
842 //---------------------------------------------------------------------
843 int subpixel_width() const { return m_pattern->line_width(); }
844 int pattern_width() const { return m_pattern->pattern_width(); }
846 //-------------------------------------------------------------------------
847 void pixel(color_type* p, int x, int y) const
849 m_pattern->pixel(p, x, y);
852 //-------------------------------------------------------------------------
853 void blend_color_hspan(int x, int y, unsigned len, const color_type* colors)
855 m_ren->blend_color_hspan(x, y, len, colors, 0);
858 //-------------------------------------------------------------------------
859 void blend_color_vspan(int x, int y, unsigned len, const color_type* colors)
861 m_ren->blend_color_vspan(x, y, len, colors, 0);
864 //-------------------------------------------------------------------------
865 static bool accurate_join_only() { return true; }
867 //-------------------------------------------------------------------------
868 template<class Cmp>
869 void semidot(Cmp, int, int, int, int)
873 //-------------------------------------------------------------------------
874 void line0(const line_parameters&)
878 //-------------------------------------------------------------------------
879 void line1(const line_parameters&, int, int)
883 //-------------------------------------------------------------------------
884 void line2(const line_parameters&, int, int)
888 //-------------------------------------------------------------------------
889 void line3(const line_parameters& lp,
890 int sx, int sy, int ex, int ey)
892 fix_degenerate_bisectrix_start(lp, &sx, &sy);
893 fix_degenerate_bisectrix_end(lp, &ex, &ey);
894 line_interpolator_image<self_type> li(*this, lp,
895 sx, sy,
896 ex, ey,
897 m_start, m_scale_x);
898 if(li.vertical())
900 while(li.step_ver());
902 else
904 while(li.step_hor());
906 m_start = li.pattern_end();
909 private:
910 base_ren_type* m_ren;
911 const pattern_type* m_pattern;
912 int m_start;
913 double m_scale_x;
924 #endif