ultimatepp/uppdev/aggdraw/agg_line_profile_aa.cpp

125 lines
3.9 KiB
C++

//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#include "agg_renderer_outline_aa.h"
namespace agg
{
//---------------------------------------------------------------------
void line_profile_aa::width(double w)
{
if(w < 0.0) w = 0.0;
if(w < m_smoother_width) w += w;
else w += m_smoother_width;
w *= 0.5;
w -= m_smoother_width;
double s = m_smoother_width;
if(w < 0.0)
{
s += w;
w = 0.0;
}
set(w, s);
}
//---------------------------------------------------------------------
line_profile_aa::value_type* line_profile_aa::profile(double w)
{
m_subpixel_width = uround(w * subpixel_scale);
unsigned size = m_subpixel_width + subpixel_scale * 6;
if(size > m_profile.size())
{
m_profile.resize(size);
}
return &m_profile[0];
}
//---------------------------------------------------------------------
void line_profile_aa::set(double center_width, double smoother_width)
{
double base_val = 1.0;
if(center_width == 0.0) center_width = 1.0 / subpixel_scale;
if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale;
double width = center_width + smoother_width;
if(width < m_min_width)
{
double k = width / m_min_width;
base_val *= k;
center_width /= k;
smoother_width /= k;
}
value_type* ch = profile(center_width + smoother_width);
unsigned subpixel_center_width = unsigned(center_width * subpixel_scale);
unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale);
value_type* ch_center = ch + subpixel_scale*2;
value_type* ch_smoother = ch_center + subpixel_center_width;
unsigned i;
unsigned val = m_gamma[unsigned(base_val * aa_mask)];
ch = ch_center;
for(i = 0; i < subpixel_center_width; i++)
{
*ch++ = (value_type)val;
}
for(i = 0; i < subpixel_smoother_width; i++)
{
*ch_smoother++ =
m_gamma[unsigned((base_val -
base_val *
(double(i) / subpixel_smoother_width)) * aa_mask)];
}
unsigned n_smoother = profile_size() -
subpixel_smoother_width -
subpixel_center_width -
subpixel_scale*2;
val = m_gamma[0];
for(i = 0; i < n_smoother; i++)
{
*ch_smoother++ = (value_type)val;
}
ch = ch_center;
for(i = 0; i < subpixel_scale*2; i++)
{
*--ch = *ch_center++;
}
}
}