| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 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 | |
|---|
| 24 | extern "C" { |
|---|
| 25 | #include <librsvg/rsvg.h> |
|---|
| 26 | #include <librsvg/rsvg-cairo.h> |
|---|
| 27 | } |
|---|
| 28 | |
|---|
| 29 | class 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 | |
|---|
| 89 | |
|---|
| 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 | |
|---|
| 118 | |
|---|
| 119 | REGISTER_OSGPLUGIN(SVG, ReaderWriterSVG) |
|---|