root/OpenSceneGraph/trunk/src/osgPlugins/svg/ReaderWriterSVG.cpp @ 13041

Revision 13041, 4.5 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- Copyright (C) 2008 Miguel Escriva Gregori
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <iostream>
15#include <sstream>
16#include <osg/Image>
17#include <osg/Notify>
18
19#include <osgDB/Registry>
20#include <osgDB/FileNameUtils>
21#include <osgDB/FileUtils>
22#include <osgDB/ImageOptions>
23
24extern "C" {
25        #include <librsvg/rsvg.h>
26        #include <librsvg/rsvg-cairo.h>
27}
28
29class ReaderWriterSVG : public osgDB::ReaderWriter
30{
31    public:
32
33        ReaderWriterSVG()
34        {
35                supportsExtension("svg","Scalar Vector Graphics format");
36                rsvg_init();
37        }
38
39        virtual const char* className() const { return "SVG Image Reader"; }
40
41        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
42        {
43                return readImage(file, options);
44        }
45
46        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
47        {
48                std::string ext = osgDB::getLowerCaseFileExtension(file);
49                if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
50
51                std::string fileName = osgDB::findDataFile( file, options );
52                if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
53
54                RsvgDimensionData dimensionData;
55                RsvgHandle* handle = rsvg_handle_new_from_file (fileName.c_str(), NULL);
56                rsvg_handle_get_dimensions( handle, &dimensionData);
57
58                osg::Image *image;
59                if (options)
60                {
61                        unsigned int w=0, h=0;
62                        std::string op = options->getOptionString();
63                        size_t i = op.find("x");
64
65                        std::stringstream ss1(op.substr(0, i));
66                        std::stringstream ss2(op.substr(i+1, op.size()));
67                        ss1 >> w;
68                        ss2 >> h;
69                        if (w==0 || h==0){
70                                image = createImage(handle, dimensionData.width, dimensionData.height);
71                        }
72                        else{
73                                image = createImage(handle, w, h);
74                        }
75                }
76                else{
77                        image = createImage(handle, dimensionData.width, dimensionData.height);
78                }
79                rsvg_handle_free(handle);
80                image->setFileName(file);
81                return image;
82        }
83
84        osg::Image* createImage(RsvgHandle *handle, unsigned int width, unsigned int height) const
85        {
86                RsvgDimensionData dimensionData;
87                rsvg_handle_get_dimensions( handle, &dimensionData);
88                // If image resollution < 128, cairo produces some artifacts.
89                // I don't know why, but we check the size...
90                if (width < 128) width = 128;
91                if (height < 128) height = 128;
92                width = osg::Image::computeNearestPowerOfTwo(width);
93                height = osg::Image::computeNearestPowerOfTwo(height);
94                osg::Image *image = new osg::Image();
95                image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
96                image->setPixelFormat(GL_BGRA);
97
98                cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(image->data(),
99                                        CAIRO_FORMAT_ARGB32, width, height, image->getRowSizeInBytes());
100                cairo_t *cr = cairo_create(cairo_surface);
101                cairo_scale(cr,((float)width)/dimensionData.width, ((float)height)/dimensionData.height);
102                rsvg_handle_render_cairo(handle, cr);
103
104                cairo_destroy(cr);
105                cairo_surface_destroy(cairo_surface);
106
107                image->flipVertical();
108                return image;
109        }
110    protected:
111        virtual ~ReaderWriterSVG()
112        {
113                rsvg_term();
114        }
115};
116
117// now register with Registry to instantiate the above
118// reader/writer.
119REGISTER_OSGPLUGIN(SVG, ReaderWriterSVG)
Note: See TracBrowser for help on using the browser.