1//----------------------------------------------------------------------------
2// Anti-Grain Geometry - Version 2.4
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
16#include "agg_renderer_outline_aa.h"
17
18namespace agg
19{
20
21    //---------------------------------------------------------------------
22    void line_profile_aa::width(double w)
23    {
24        if(w < 0.0) w = 0.0;
25
26        if(w < m_smoother_width) w += w;
27        else                     w += m_smoother_width;
28
29        w *= 0.5;
30
31        w -= m_smoother_width;
32        double s = m_smoother_width;
33        if(w < 0.0)
34        {
35            s += w;
36            w = 0.0;
37        }
38        set(w, s);
39    }
40
41
42    //---------------------------------------------------------------------
43    line_profile_aa::value_type* line_profile_aa::profile(double w)
44    {
45        m_subpixel_width = uround(w * subpixel_scale);
46        unsigned size = m_subpixel_width + subpixel_scale * 6;
47        if(size > m_profile.size())
48        {
49            m_profile.resize(size);
50        }
51        return &m_profile[0];
52    }
53
54
55    //---------------------------------------------------------------------
56    void line_profile_aa::set(double center_width, double smoother_width)
57    {
58        double base_val = 1.0;
59        if(center_width == 0.0)   center_width = 1.0 / subpixel_scale;
60        if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale;
61
62        double width = center_width + smoother_width;
63        if(width < m_min_width)
64        {
65            double k = width / m_min_width;
66            base_val *= k;
67            center_width /= k;
68            smoother_width /= k;
69        }
70
71        value_type* ch = profile(center_width + smoother_width);
72
73        unsigned subpixel_center_width = unsigned(center_width * subpixel_scale);
74        unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale);
75
76        value_type* ch_center   = ch + subpixel_scale*2;
77        value_type* ch_smoother = ch_center + subpixel_center_width;
78
79        unsigned i;
80
81        unsigned val = m_gamma[unsigned(base_val * aa_mask)];
82        ch = ch_center;
83        for(i = 0; i < subpixel_center_width; i++)
84        {
85            *ch++ = (value_type)val;
86        }
87
88        for(i = 0; i < subpixel_smoother_width; i++)
89        {
90            *ch_smoother++ =
91                m_gamma[unsigned((base_val -
92                                  base_val *
93                                  (double(i) / subpixel_smoother_width)) * aa_mask)];
94        }
95
96        unsigned n_smoother = profile_size() -
97                              subpixel_smoother_width -
98                              subpixel_center_width -
99                              subpixel_scale*2;
100
101        val = m_gamma[0];
102        for(i = 0; i < n_smoother; i++)
103        {
104            *ch_smoother++ = (value_type)val;
105        }
106
107        ch = ch_center;
108        for(i = 0; i < subpixel_scale*2; i++)
109        {
110            *--ch = *ch_center++;
111        }
112    }
113
114
115}
116
117