예제 #1
0
파일: gradient.cpp 프로젝트: gischen/mapnik
void gradient::swap(const gradient& other) throw()
{
    gradient_type_=other.gradient_type_;
    stops_=other.stops_;
    units_=other.units_;
    transform_=other.transform_;
    other.get_control_points(x1_,y1_,x2_,y2_,r_);
}
예제 #2
0
    void render_gradient(Rasterizer& ras,
                         Scanline& sl,
                         Renderer& ren,
                         const gradient &grad,
                         agg::trans_affine const& mtx,
                         double opacity,
                         const box2d<double> &symbol_bbox,
                         const box2d<double> &path_bbox)
    {
        typedef agg::gamma_lut<agg::int8u, agg::int8u> gamma_lut_type;
        typedef agg::gradient_lut<agg::color_interpolator<agg::rgba8>, 1024> color_func_type;
        typedef agg::span_interpolator_linear<> interpolator_type;
        typedef agg::span_allocator<agg::rgba8> span_allocator_type;

        span_allocator_type             m_alloc;
        color_func_type                 m_gradient_lut;
        gamma_lut_type                  m_gamma_lut;

        double x1,x2,y1,y2,radius;
        grad.get_control_points(x1,y1,x2,y2,radius);

        m_gradient_lut.remove_all();
        BOOST_FOREACH ( mapnik::stop_pair const& st, grad.get_stop_array() )
        {
            mapnik::color const& stop_color = st.second;
            unsigned r = stop_color.red();
            unsigned g = stop_color.green();
            unsigned b = stop_color.blue();
            unsigned a = stop_color.alpha();
            //MAPNIK_LOG_DEBUG(svg_renderer) << "svg_renderer: r=" << r << ",g=" << g << ",b=" << b << ",a=" << a;
            m_gradient_lut.add_color(st.first, agg::rgba8(r, g, b, int(a * opacity)));
        }
        m_gradient_lut.build_lut();

        agg::trans_affine transform = mtx;
        transform.invert();
        agg::trans_affine tr;
        tr = grad.get_transform();
        tr.invert();
        transform *= tr;

        if (grad.get_units() != USER_SPACE_ON_USE)
        {
            double bx1=symbol_bbox.minx();
            double by1=symbol_bbox.miny();
            double bx2=symbol_bbox.maxx();
            double by2=symbol_bbox.maxy();

            if (grad.get_units() == OBJECT_BOUNDING_BOX)
            {
                bx1=path_bbox.minx();
                by1=path_bbox.miny();
                bx2=path_bbox.maxx();
                by2=path_bbox.maxy();
            }

            transform.translate(-bx1,-by1);
            transform.scale(1.0/(bx2-bx1),1.0/(by2-by1));
        }


        if (grad.get_gradient_type() == RADIAL)
        {
            typedef agg::gradient_radial_focus gradient_adaptor_type;
            typedef agg::span_gradient<agg::rgba8,
                interpolator_type,
                gradient_adaptor_type,
                color_func_type> span_gradient_type;

            // the agg radial gradient assumes it is centred on 0
            transform.translate(-x2,-y2);

            // scale everything up since agg turns things into integers a bit too soon
            int scaleup=255;
            radius*=scaleup;
            x1*=scaleup;
            y1*=scaleup;
            x2*=scaleup;
            y2*=scaleup;

            transform.scale(scaleup,scaleup);
            interpolator_type     span_interpolator(transform);
            gradient_adaptor_type gradient_adaptor(radius,(x1-x2),(y1-y2));

            span_gradient_type    span_gradient(span_interpolator,
                                                gradient_adaptor,
                                                m_gradient_lut,
                                                0, radius);

            render_scanlines_aa(ras, sl, ren, m_alloc, span_gradient);
        }
        else
        {
            typedef linear_gradient_from_segment gradient_adaptor_type;
            typedef agg::span_gradient<agg::rgba8,
                interpolator_type,
                gradient_adaptor_type,
                color_func_type> span_gradient_type;

            // scale everything up since agg turns things into integers a bit too soon
            int scaleup=255;
            x1*=scaleup;
            y1*=scaleup;
            x2*=scaleup;
            y2*=scaleup;

            transform.scale(scaleup,scaleup);

            interpolator_type     span_interpolator(transform);
            gradient_adaptor_type gradient_adaptor(x1,y1,x2,y2);

            span_gradient_type    span_gradient(span_interpolator,
                                                gradient_adaptor,
                                                m_gradient_lut,
                                                0, scaleup);

            render_scanlines_aa(ras, sl, ren, m_alloc, span_gradient);
        }
    }
예제 #3
0
    void render_gradient(Rasterizer& ras,
                         Scanline& sl,
                         Renderer& ren,
                         gradient const& grad,
                         agg::trans_affine const& mtx,
                         double opacity,
                         box2d<double> const& symbol_bbox,
                         curved_trans_type & curved_trans,
                         unsigned path_id)
    {
        using gamma_lut_type = agg::gamma_lut<agg::int8u, agg::int8u>;
        using color_func_type = agg::gradient_lut<agg::color_interpolator<agg::rgba8>, 1024>;
        using interpolator_type = agg::span_interpolator_linear<>;
        using span_allocator_type = agg::span_allocator<agg::rgba8>;

        span_allocator_type             m_alloc;
        color_func_type                 m_gradient_lut;
        gamma_lut_type                  m_gamma_lut;

        double x1,x2,y1,y2,radius;
        grad.get_control_points(x1,y1,x2,y2,radius);

        m_gradient_lut.remove_all();
        for ( mapnik::stop_pair const& st : grad.get_stop_array() )
        {
            mapnik::color const& stop_color = st.second;
            unsigned r = stop_color.red();
            unsigned g = stop_color.green();
            unsigned b = stop_color.blue();
            unsigned a = stop_color.alpha();
            m_gradient_lut.add_color(st.first, agg::rgba8_pre(r, g, b, int(a * opacity)));
        }
        if (m_gradient_lut.build_lut())
        {
            agg::trans_affine transform = mtx;
            transform.invert();
            agg::trans_affine tr;
            tr = grad.get_transform();
            tr.invert();
            transform *= tr;

            if (grad.get_units() != USER_SPACE_ON_USE)
            {
                double bx1=symbol_bbox.minx();
                double by1=symbol_bbox.miny();
                double bx2=symbol_bbox.maxx();
                double by2=symbol_bbox.maxy();

                if (grad.get_units() == OBJECT_BOUNDING_BOX)
                {
                    bounding_rect_single(curved_trans, path_id, &bx1, &by1, &bx2, &by2);
                }

                transform.translate(-bx1,-by1);
                transform.scale(1.0/(bx2-bx1),1.0/(by2-by1));
            }

            if (grad.get_gradient_type() == RADIAL)
            {
                using gradient_adaptor_type = agg::gradient_radial_focus;
                using span_gradient_type = agg::span_gradient<agg::rgba8,
                                                              interpolator_type,
                                                              gradient_adaptor_type,
                                                              color_func_type>;

                // the agg radial gradient assumes it is centred on 0
                transform.translate(-x2,-y2);

                // scale everything up since agg turns things into integers a bit too soon
                int scaleup=255;
                radius *= scaleup;
                x1 *= scaleup;
                y1 *= scaleup;
                x2 *= scaleup;
                y2 *= scaleup;

                transform.scale(scaleup,scaleup);
                interpolator_type     span_interpolator(transform);
                gradient_adaptor_type gradient_adaptor(radius,(x1-x2),(y1-y2));

                span_gradient_type    span_gradient(span_interpolator,
                                                    gradient_adaptor,
                                                    m_gradient_lut,
                                                    0, radius);

                render_scanlines_aa(ras, sl, ren, m_alloc, span_gradient);
            }
            else
            {
                using gradient_adaptor_type = linear_gradient_from_segment;
                using span_gradient_type = agg::span_gradient<agg::rgba8,
                                                              interpolator_type,
                                                              gradient_adaptor_type,
                                                              color_func_type>;
                // scale everything up since agg turns things into integers a bit too soon
                int scaleup=255;
                x1 *= scaleup;
                y1 *= scaleup;
                x2 *= scaleup;
                y2 *= scaleup;

                transform.scale(scaleup,scaleup);

                interpolator_type     span_interpolator(transform);
                gradient_adaptor_type gradient_adaptor(x1,y1,x2,y2);

                span_gradient_type    span_gradient(span_interpolator,
                                                    gradient_adaptor,
                                                    m_gradient_lut,
                                                    0, scaleup);

                render_scanlines_aa(ras, sl, ren, m_alloc, span_gradient);
            }
        }
    }