Ticket #381: further_cairo_rendering_abstraction.patch

File further_cairo_rendering_abstraction.patch, 6.6 kB (added by springmeyer, 8 months ago)

Patch to further abstract cairo rendering and allow use of cairo formats via python even if pycairo is not used/available

  • src/image_util.cpp

     
    3535#include <mapnik/memory.hpp> 
    3636#include <mapnik/image_view.hpp> 
    3737 
     38#ifdef HAVE_CAIRO 
     39#include <mapnik/cairo_renderer.hpp> 
     40#endif 
     41 
    3842// stl 
    3943#include <string> 
    4044#include <iostream> 
     
    103107                } 
    104108            } 
    105109            else throw ImageWriterException("unknown file type: " + type); 
    106         }  
     110        } 
     111        else throw ImageWriterException("Could not write file to " + filename ); 
    107112    } 
     113 
    108114         
    109115    template <typename T> 
    110116    void save_to_file(T const& image,std::string const& filename) 
     
    112118        std::string type = type_from_filename(filename); 
    113119        save_to_file<T>(image,filename,type); 
    114120    } 
    115       
    116121 
     122 
     123#if defined(HAVE_CAIRO) 
     124 
     125    void save_to_cairo_file(mapnik::Map const& map, std::string const& filename) 
     126    { 
     127        std::string type = type_from_filename(filename); 
     128        save_to_cairo_file(map,filename,type); 
     129    } 
     130 
     131    void save_to_cairo_file(mapnik::Map const& map, 
     132                      std::string const& filename, 
     133                      std::string const& type) 
     134    { 
     135        std::ofstream file (filename.c_str(), std::ios::out|std::ios::trunc|std::ios::binary); 
     136        if (file) 
     137        { 
     138          Cairo::RefPtr<Cairo::Surface> surface; 
     139          if (type == "pdf") 
     140              surface = Cairo::PdfSurface::create(filename, map.getWidth(),map.getHeight()); 
     141          else if (type == "svg") 
     142              surface = Cairo::SvgSurface::create(filename, map.getWidth(),map.getHeight()); 
     143          else if (type == "ps") 
     144              surface = Cairo::PsSurface::create(filename, map.getWidth(),map.getHeight()); 
     145          else if (type == "ARGB32") 
     146              surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, map.getWidth(),map.getHeight()); 
     147          else if (type == "RGB24") 
     148              surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, map.getWidth(),map.getHeight()); 
     149          else  
     150              throw ImageWriterException("unknown file type: " + type);     
     151          Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface); 
     152     
     153          if (type == "ARGB32" | type == "RGB24")  
     154          {  
     155              context->set_antialias(Cairo::ANTIALIAS_NONE);  
     156          } 
     157     
     158          mapnik::cairo_renderer<Cairo::Context> ren(map, context); 
     159          ren.apply(); 
     160     
     161          if (type == "ARGB32" | type == "RGB24")  
     162          {  
     163              surface->write_to_png(filename); 
     164          } 
     165          surface->finish(); 
     166        } 
     167    } 
     168 
     169#endif 
     170 
    117171    template void save_to_file<ImageData32>(ImageData32 const&, 
    118172                                            std::string const&, 
    119173                                            std::string const&); 
    120  
     174                                             
    121175    template void save_to_file<ImageData32>(ImageData32 const&, 
    122176                                            std::string const&); 
    123177 
  • include/mapnik/image_util.hpp

     
    2727 
    2828// mapnik 
    2929#include <mapnik/config.hpp> 
     30#include <mapnik/map.hpp> 
    3031#include <mapnik/graphics.hpp> 
    3132 
    3233// boost 
     
    5354        } 
    5455    }; 
    5556 
     57   MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map, 
     58                                        std::string const& filename, 
     59                                        std::string const& type); 
     60 
    5661   template <typename T> 
    5762   MAPNIK_DECL void save_to_file(T const& image, 
    5863                                 std::string const& filename, 
     
    9196      return boost::algorithm::iends_with(filename,std::string(".tif")) || 
    9297         boost::algorithm::iends_with(filename,std::string(".tiff")); 
    9398   } 
    94     
     99 
     100   inline bool is_pdf (std::string const& filename) 
     101   { 
     102      return boost::algorithm::iends_with(filename,std::string(".pdf")); 
     103   } 
     104 
     105   inline bool is_svg (std::string const& filename) 
     106   { 
     107      return boost::algorithm::iends_with(filename,std::string(".svg")); 
     108   } 
     109 
     110   inline bool is_ps (std::string const& filename) 
     111   { 
     112      return boost::algorithm::iends_with(filename,std::string(".ps")); 
     113   } 
     114       
    95115   inline std::string type_from_filename(std::string const& filename) 
    96116   { 
    97117      if (is_png(filename)) return "png"; 
    98118      if (is_jpeg(filename)) return "jpeg"; 
    99119      if (is_tiff(filename)) return "tiff"; 
     120      if (is_pdf(filename)) return "pdf"; 
     121      if (is_svg(filename)) return "svg"; 
     122      if (is_ps(filename)) return "ps"; 
    100123      return "unknown"; 
    101124   } 
    102125 
  • bindings/python/mapnik_python.cpp

     
    194194                    const std::string& filename, 
    195195                    const std::string& format) 
    196196{ 
    197     mapnik::Image32 image(map.getWidth(),map.getHeight()); 
    198     render(map,image,0,0); 
    199     mapnik::save_to_file(image,filename,format);  
     197    if (format == "pdf" | format == "svg" | format =="ps" | format == "ARGB32" | format == "RGB24") 
     198    { 
     199#if defined(HAVE_CAIRO) 
     200        mapnik::save_to_cairo_file(map,filename,format); 
     201#else 
     202        throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); 
     203#endif 
     204    } 
     205    else  
     206    { 
     207        mapnik::Image32 image(map.getWidth(),map.getHeight()); 
     208        render(map,image,0,0); 
     209        mapnik::save_to_file(image,filename,format);  
     210    } 
    200211} 
    201212 
    202 void render_to_file2(const mapnik::Map& map, 
    203                     const std::string& filename) 
     213void render_to_file2(const mapnik::Map& map,const std::string& filename) 
    204214{ 
    205     mapnik::Image32 image(map.getWidth(),map.getHeight()); 
    206     render(map,image,0,0); 
    207     mapnik::save_to_file(image,filename);  
     215    std::string format = mapnik::guess_type(filename); 
     216    if (format == "pdf" | format == "svg" | format =="ps") 
     217    { 
     218#if defined(HAVE_CAIRO) 
     219        mapnik::save_to_cairo_file(map,filename,format); 
     220#else 
     221        throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); 
     222#endif 
     223    } 
     224    else  
     225    { 
     226        mapnik::Image32 image(map.getWidth(),map.getHeight()); 
     227        render(map,image,0,0); 
     228        mapnik::save_to_file(image,filename);  
     229    } 
    208230} 
    209231 
    210  
    211232double scale_denominator(mapnik::Map const &map, bool geographic) 
    212233{ 
    213234    return mapnik::scale_denominator(map, geographic);