Intoduce new osgWidget::PdfReader and osgWidget::VncClient front ends to osgWidget,
with new pdf plugin and updated vnc plugin that now support these front ends. Updated osgpdf and osgvnc examples to new these new interfaces.
This commit is contained in:
parent
0114ac4734
commit
6f356aeb97
@ -133,9 +133,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgwidgettable)
|
||||
ADD_SUBDIRECTORY(osgwidgetwindow)
|
||||
|
||||
IF (POPPLER_FOUND AND CAIRO_FOUND)
|
||||
ADD_SUBDIRECTORY(osgpdf)
|
||||
ENDIF(POPPLER_FOUND AND CAIRO_FOUND)
|
||||
|
||||
IF (BUILD_OSG_WRAPPERS)
|
||||
ADD_SUBDIRECTORY(osgintrospection)
|
||||
|
@ -1,10 +1,6 @@
|
||||
SET(TARGET_SRC osgpdf.cpp)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CAIRO_INCLUDE_DIRS} ${POPPLER_INCLUDE_DIRS} )
|
||||
LINK_DIRECTORIES(${CAIRO_LIBRARY_DIRS} ${POPPLER_LIB_DIRS})
|
||||
|
||||
#SET(TARGET_EXTERNAL_LIBRARIES ${CAIRO_LIBRARIES} poppler poppler-glib)
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${CAIRO_LIBRARIES} ${POPPLER_LIBRARIES})
|
||||
SET(TARGET_ADDED_LIBRARIES osgWidget )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgpdf)
|
||||
|
@ -10,315 +10,38 @@
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <poppler.h>
|
||||
|
||||
class CarioImage : public osg::Image
|
||||
{
|
||||
public:
|
||||
|
||||
CarioImage():
|
||||
_surface(0),
|
||||
_context(0) {}
|
||||
|
||||
|
||||
void create(unsigned int width, unsigned int height)
|
||||
{
|
||||
if (data() && width==s() && height==t()) return;
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Create cario surface/context "<<width<<", "<<height<<std::endl;
|
||||
|
||||
// allocate the image data
|
||||
allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
setPixelFormat(GL_BGRA);
|
||||
setDataVariance(osg::Object::DYNAMIC);
|
||||
setOrigin(osg::Image::TOP_LEFT);
|
||||
|
||||
|
||||
// create a cairo surface for this image data
|
||||
_surface = cairo_image_surface_create_for_data(
|
||||
data(),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width, height,
|
||||
getRowSizeInBytes());
|
||||
|
||||
// create a context for the surface
|
||||
_context = cairo_create(_surface);
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (_surface) cairo_surface_destroy(_surface);
|
||||
if (_context) cairo_destroy(_context);
|
||||
}
|
||||
|
||||
cairo_surface_t* getSurface() { return _surface; }
|
||||
const cairo_surface_t* getSurface() const { return _surface; }
|
||||
|
||||
cairo_t* getContext() { return _context; }
|
||||
const cairo_t* getContext() const { return _context; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~CarioImage()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
cairo_surface_t* _surface;
|
||||
cairo_t* _context;
|
||||
};
|
||||
|
||||
class PdfImage : public CarioImage
|
||||
{
|
||||
public:
|
||||
|
||||
PdfImage():
|
||||
_doc(0),
|
||||
_pageNum(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~PdfImage()
|
||||
{
|
||||
if (_doc)
|
||||
{
|
||||
g_object_unref(_doc);
|
||||
}
|
||||
}
|
||||
|
||||
PopplerDocument* _doc;
|
||||
int _pageNum;
|
||||
|
||||
int getNumOfPages() { return _doc ? poppler_document_get_n_pages(_doc) : 0; }
|
||||
|
||||
bool open(const std::string& filename)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"open("<<filename<<")"<<std::endl;
|
||||
|
||||
std::string foundFile = osgDB::findDataFile(filename);
|
||||
if (foundFile.empty())
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"could not find filename="<<filename<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<"foundFile = "<<foundFile<<std::endl;
|
||||
foundFile = osgDB::getRealPath(foundFile);
|
||||
osg::notify(osg::NOTICE)<<"foundFile = "<<foundFile<<std::endl;
|
||||
|
||||
static bool gTypeInit = false;
|
||||
|
||||
if(!gTypeInit)
|
||||
{
|
||||
g_type_init();
|
||||
|
||||
gTypeInit = true;
|
||||
}
|
||||
|
||||
std::string uri = std::string("file:") + foundFile;
|
||||
|
||||
PopplerDocument* doc = poppler_document_new_from_file(uri.c_str(), NULL, NULL);
|
||||
if (!doc)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" could not open("<<filename<<"), uri="<<uri<<std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_doc)
|
||||
{
|
||||
g_object_unref(_doc);
|
||||
}
|
||||
|
||||
_doc = doc;
|
||||
_pageNum = 0;
|
||||
|
||||
setFileName(filename);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"getNumOfPages()=="<<getNumOfPages()<<std::endl;
|
||||
|
||||
if (getNumOfPages()==0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
page(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
if (keyDown)
|
||||
{
|
||||
if (key=='n') next();
|
||||
else if (key=='p') previous();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool previous()
|
||||
{
|
||||
return page(_pageNum-1);
|
||||
}
|
||||
|
||||
bool next()
|
||||
{
|
||||
return page(_pageNum+1);
|
||||
}
|
||||
|
||||
bool page(int pageNum)
|
||||
{
|
||||
if (!_doc) return false;
|
||||
|
||||
if (pageNum<0 || pageNum>=getNumOfPages()) return false;
|
||||
|
||||
PopplerPage* page = poppler_document_get_page(_doc, pageNum);
|
||||
|
||||
if(!page) return false;
|
||||
|
||||
_pageNum = pageNum;
|
||||
|
||||
double w = 0.0f;
|
||||
double h = 0.0f;
|
||||
|
||||
poppler_page_get_size(page, &w, &h);
|
||||
|
||||
create((unsigned int)(w*2.0),(unsigned int)(h*2.0));
|
||||
|
||||
double r = 1.0;
|
||||
double g = 1.0;
|
||||
double b = 1.0;
|
||||
double a = 1.0;
|
||||
|
||||
cairo_save(_context);
|
||||
|
||||
cairo_set_source_rgba(_context, r, g, b, a);
|
||||
cairo_rectangle(_context, 0.0, 0.0, double(s()), double(t()));
|
||||
cairo_fill(_context);
|
||||
|
||||
cairo_scale(_context, double(s())/w, double(t())/h);
|
||||
|
||||
poppler_page_render(page, getContext());
|
||||
|
||||
|
||||
cairo_restore(_context);
|
||||
|
||||
dirty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis, osg::Vec3& heightAxis,
|
||||
osg::Image* image)
|
||||
{
|
||||
bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
|
||||
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(origin, widthAxis, heightAxis,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(image);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(image));
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(pictureQuad);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
class PageHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
PageHandler() {}
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
|
||||
{
|
||||
if (ea.getHandled()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
{
|
||||
if (ea.getKey()=='n')
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Next page"<<std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (ea.getKey()=='p')
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Previous page"<<std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
#include <osgWidget/PdfReader>
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
|
||||
typedef std::list< osg::ref_ptr<osg::Image> > Images;
|
||||
Images images;
|
||||
osgWidget::GeometryHints hints(osg::Vec3(1.0f,0.0f,0.0f),
|
||||
osg::Vec3(1.0f,0.0f,0.0f),
|
||||
osg::Vec3(0.0f,0.0f,1.0f),
|
||||
osgWidget::GeometryHints::RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO);
|
||||
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
|
||||
for(int i=1; i<arguments.argc(); ++i)
|
||||
{
|
||||
if (!arguments.isOption(i))
|
||||
{
|
||||
osg::ref_ptr<PdfImage> pdfImage= new PdfImage;
|
||||
if (pdfImage->open(arguments[i]))
|
||||
osg::ref_ptr<osgWidget::PdfReader> pdfReader = new osgWidget::PdfReader;
|
||||
if (pdfReader->open(arguments[i], hints))
|
||||
{
|
||||
images.push_back(pdfImage.get());
|
||||
group->addChild(pdfReader.get());
|
||||
|
||||
hints.position.x() += 1.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool xyPlane = false;
|
||||
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
osg::Vec3 origin = osg::Vec3(0.0f,0.0f,0.0f);
|
||||
for(Images::iterator itr = images.begin();
|
||||
itr != images.end();
|
||||
++itr)
|
||||
{
|
||||
osg::Image* image = itr->get();
|
||||
float width = 1.0;
|
||||
float height = float(image->t())/float(image->s());
|
||||
osg::Vec3 widthAxis = osg::Vec3(width,0.0f,0.0f);
|
||||
osg::Vec3 heightAxis = xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height);
|
||||
group->addChild(createInteractiveQuad(origin, widthAxis, heightAxis, image));
|
||||
|
||||
origin += widthAxis*1.1f;
|
||||
}
|
||||
|
||||
viewer.setSceneData(group);
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
//viewer.addEventHandler(new PageHandler);
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
|
||||
|
@ -12,38 +12,6 @@
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
|
||||
osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis, osg::Vec3& heightAxis,
|
||||
osg::Image* image)
|
||||
{
|
||||
bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
|
||||
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(origin, widthAxis, heightAxis,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(image);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
|
||||
|
||||
osg::ref_ptr<osgViewer::InteractiveImageHandler> callback = new osgViewer::InteractiveImageHandler(image);
|
||||
|
||||
pictureQuad->setEventCallback(callback.get());
|
||||
pictureQuad->setCullCallback(callback.get());
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(pictureQuad);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
class EscapeHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
@ -76,45 +44,31 @@ class EscapeHandler : public osgGA::GUIEventHandler
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
osgViewer::Viewer viewer;
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
|
||||
typedef std::list< osg::ref_ptr<osg::Image> > Images;
|
||||
Images images;
|
||||
osgWidget::GeometryHints hints(osg::Vec3(1.0f,0.0f,0.0f),
|
||||
osg::Vec3(1.0f,0.0f,0.0f),
|
||||
osg::Vec3(0.0f,0.0f,1.0f),
|
||||
osgWidget::GeometryHints::RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO);
|
||||
|
||||
std::string hostname;
|
||||
while (arguments.read("--host",hostname))
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
|
||||
for(int i=1; i<arguments.argc(); ++i)
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(hostname+std::string(".vnc"));
|
||||
if (image.valid()) images.push_back(image.get());
|
||||
if (!arguments.isOption(i))
|
||||
{
|
||||
osg::ref_ptr<osgWidget::VncClient> vncClient = new osgWidget::VncClient;
|
||||
if (vncClient->connect(arguments[i], hints))
|
||||
{
|
||||
group->addChild(vncClient.get());
|
||||
|
||||
hints.position.x() += 1.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (images.empty())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool xyPlane = false;
|
||||
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
osg::Vec3 origin = osg::Vec3(0.0f,0.0f,0.0f);
|
||||
for(Images::iterator itr = images.begin();
|
||||
itr != images.end();
|
||||
++itr)
|
||||
{
|
||||
osg::Image* image = itr->get();
|
||||
float width = 1.0;
|
||||
float height = float(image->t())/float(image->s());
|
||||
osg::Vec3 widthAxis = osg::Vec3(width,0.0f,0.0f);
|
||||
osg::Vec3 heightAxis = xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height);
|
||||
group->addChild(createInteractiveQuad(origin, widthAxis, heightAxis, image));
|
||||
|
||||
origin += widthAxis*1.1f;
|
||||
}
|
||||
|
||||
viewer.setSceneData(group);
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#this file is automatically generated
|
||||
|
||||
|
||||
SET(TARGET_SRC osgwidgetscrolled.cpp )
|
||||
|
||||
SET(TARGET_ADDED_LIBRARIES osgWidget )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgwidgetscrolled)
|
||||
|
@ -324,11 +324,11 @@ class OSG_EXPORT Image : public Object
|
||||
virtual void update(NodeVisitor* nv) {}
|
||||
|
||||
|
||||
/** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/
|
||||
virtual void sendPointerEvent(int x, int y, int buttonMask) {}
|
||||
/** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window. Return true if handled. */
|
||||
virtual bool sendPointerEvent(int x, int y, int buttonMask) { return false; }
|
||||
|
||||
/** method for sending key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/
|
||||
virtual void sendKeyEvent(int key, bool keyDown) {}
|
||||
/** method for sending key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window. Return true if handled.*/
|
||||
virtual bool sendKeyEvent(int key, bool keyDown) { return false; }
|
||||
|
||||
/** method for passing frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
|
||||
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp) {}
|
||||
|
@ -389,6 +389,10 @@ protected:
|
||||
bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
|
||||
|
||||
osg::observer_ptr<osg::Image> _image;
|
||||
bool _handleKeyboardEvents;
|
||||
bool _handledOnKeyboardEvents;
|
||||
bool _handleMouseEvents;
|
||||
bool _handledOnMouseEvents;
|
||||
|
||||
};
|
||||
|
||||
|
116
include/osgWidget/PdfReader
Normal file
116
include/osgWidget/PdfReader
Normal file
@ -0,0 +1,116 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGWIDGET_PDFREADER
|
||||
#define OSGWIDGET_PDFREADER
|
||||
|
||||
#include <osg/Image>
|
||||
#include <osg/Geode>
|
||||
|
||||
#include <osgWidget/Export>
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
|
||||
/** Hints structure that can be passed to PdfReader and VncClient classes to help guide them on what geometry to build.*/
|
||||
struct GeometryHints
|
||||
{
|
||||
enum AspectRatioPolicy
|
||||
{
|
||||
RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO,
|
||||
RESIZE_WIDTH_TO_MAINTAINCE_ASPECT_RATIO,
|
||||
IGNORE_DOCUMENT_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
GeometryHints():
|
||||
position(0.0f,0.0f,0.0f),
|
||||
widthVec(1.0f,0.0f,0.0f),
|
||||
heightVec(0.0f,1.0f,0.0f),
|
||||
aspectRatioPolicy(RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO) {}
|
||||
|
||||
GeometryHints(const osg::Vec3& pos,
|
||||
const osg::Vec3& wVec,
|
||||
const osg::Vec3& hVec,
|
||||
AspectRatioPolicy asp=RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO):
|
||||
position(pos),
|
||||
widthVec(wVec),
|
||||
heightVec(hVec),
|
||||
aspectRatioPolicy(asp) {}
|
||||
|
||||
osg::Vec3 position;
|
||||
osg::Vec3 widthVec;
|
||||
osg::Vec3 heightVec;
|
||||
AspectRatioPolicy aspectRatioPolicy;
|
||||
|
||||
};
|
||||
|
||||
/** Pure virtual base class for interfacing with implementation of PDF reader.*/
|
||||
class PdfImage : public osg::Image
|
||||
{
|
||||
public:
|
||||
|
||||
PdfImage():_pageNum(0) {}
|
||||
|
||||
int getPageNum() const { return _pageNum; }
|
||||
|
||||
virtual int getNumOfPages() = 0;
|
||||
|
||||
virtual bool page(int pageNum) = 0;
|
||||
|
||||
bool previous()
|
||||
{
|
||||
return page(_pageNum-1);
|
||||
}
|
||||
|
||||
bool next()
|
||||
{
|
||||
return page(_pageNum+1);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~PdfImage() {}
|
||||
|
||||
int _pageNum;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Convinience class that provides a interactive quad that can be placed directly in the scene.*/
|
||||
class OSGWIDGET_EXPORT PdfReader : public osg::Geode
|
||||
{
|
||||
public:
|
||||
|
||||
PdfReader() {}
|
||||
|
||||
PdfReader(const std::string& filename, GeometryHints hints = GeometryHints());
|
||||
|
||||
bool assign(PdfImage* pdfImage, GeometryHints hints = GeometryHints());
|
||||
|
||||
bool open(const std::string& filename, GeometryHints hints = GeometryHints());
|
||||
|
||||
bool page(int pageNum);
|
||||
|
||||
bool previous();
|
||||
|
||||
bool next();
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<PdfImage> _pdfImage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
63
include/osgWidget/VncClient
Normal file
63
include/osgWidget/VncClient
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGWIDGET_VNCCLIENT
|
||||
#define OSGWIDGET_VNCCLIENT
|
||||
|
||||
#include <osgDB/ReaderWriter>
|
||||
|
||||
#include <osgWidget/PdfReader>
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
/** Pure virtual base class for VncImage that is sublcassed by vnc plugin to provide the actual implementation.*/
|
||||
class VncImage : public osg::Image
|
||||
{
|
||||
public:
|
||||
|
||||
VncImage() {}
|
||||
|
||||
virtual bool connect(const std::string& hostname) = 0;
|
||||
|
||||
virtual void close() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~VncImage() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Convinience Vnc Client class that provides a interactive quad that can be placed directly in the scene.*/
|
||||
class OSGWIDGET_EXPORT VncClient : public osg::Geode
|
||||
{
|
||||
public:
|
||||
|
||||
VncClient() {}
|
||||
|
||||
VncClient(const std::string& hostname, GeometryHints hints = GeometryHints());
|
||||
|
||||
bool assign(VncImage* vncImage, GeometryHints hints = GeometryHints());
|
||||
|
||||
bool connect(const std::string& hostname, GeometryHints hints = GeometryHints());
|
||||
|
||||
void close();
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<VncImage> _vncImage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -196,6 +196,9 @@ IF(RSVG_FOUND AND CAIRO_FOUND)
|
||||
ADD_SUBDIRECTORY(svg)
|
||||
ENDIF(RSVG_FOUND AND CAIRO_FOUND)
|
||||
|
||||
IF (POPPLER_FOUND AND CAIRO_FOUND)
|
||||
ADD_SUBDIRECTORY(pdf)
|
||||
ENDIF(POPPLER_FOUND AND CAIRO_FOUND)
|
||||
|
||||
IF (LIBVNCSERVER_FOUND)
|
||||
ADD_SUBDIRECTORY(vnc)
|
||||
|
@ -478,7 +478,7 @@ struct PointerEventOperation : public osg::Operation
|
||||
int _buttonDelta;
|
||||
};
|
||||
|
||||
void UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask)
|
||||
bool UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask)
|
||||
{
|
||||
int deltaButton = (buttonMask&1) - (_previousButtonMask&1);
|
||||
_previousButtonMask = buttonMask;
|
||||
@ -486,6 +486,8 @@ void UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int b
|
||||
_thread->add(new PointerEventOperation(image, x, y, deltaButton));
|
||||
|
||||
active(image);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -509,15 +511,17 @@ struct KeyEventOperation : public osg::Operation
|
||||
bool _isUnicode;
|
||||
};
|
||||
|
||||
void UBrowserManager::sendKeyEvent(UBrowserImage* image, int key, bool keyDown)
|
||||
bool UBrowserManager::sendKeyEvent(UBrowserImage* image, int key, bool keyDown)
|
||||
{
|
||||
if (!keyDown) return;
|
||||
if (!keyDown) return false;
|
||||
|
||||
KeyMap::const_iterator itr = _keyMap.find(key);
|
||||
if (_keyMap.find(key)==_keyMap.end()) _thread->add(new KeyEventOperation(image, key, true));
|
||||
else _thread->add(new KeyEventOperation(image, itr->second, false));
|
||||
|
||||
active(image);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -582,14 +586,14 @@ UBrowserImage::~UBrowserImage()
|
||||
_manager->unregisterUBrowserImage(this);
|
||||
}
|
||||
|
||||
void UBrowserImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
bool UBrowserImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
_manager->sendPointerEvent(this, x, y, buttonMask);
|
||||
return _manager->sendPointerEvent(this, x, y, buttonMask);
|
||||
}
|
||||
|
||||
void UBrowserImage::sendKeyEvent(int key, bool keyDown)
|
||||
bool UBrowserImage::sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
_manager->sendKeyEvent(this, key, keyDown);
|
||||
return _manager->sendKeyEvent(this, key, keyDown);
|
||||
}
|
||||
|
||||
void UBrowserImage::setFrameLastRendered(const osg::FrameStamp*)
|
||||
|
@ -60,9 +60,9 @@ class UBrowserManager : public osgWidget::BrowserManager
|
||||
if (itr != _ubrowserImageList.end()) _ubrowserImageList.erase(itr);
|
||||
}
|
||||
|
||||
void sendKeyEvent(UBrowserImage* image, int key, bool keyDown);
|
||||
bool sendKeyEvent(UBrowserImage* image, int key, bool keyDown);
|
||||
|
||||
void sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask);
|
||||
bool sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask);
|
||||
|
||||
void navigateTo(UBrowserImage* image, const std::string& page);
|
||||
|
||||
@ -108,9 +108,9 @@ class UBrowserImage : public osgWidget::BrowserImage, public LLEmbeddedBrowserWi
|
||||
|
||||
const std::string& getHomeURL() const { return _homeURL; }
|
||||
|
||||
virtual void sendPointerEvent(int x, int y, int buttonMask);
|
||||
virtual bool sendPointerEvent(int x, int y, int buttonMask);
|
||||
|
||||
virtual void sendKeyEvent(int key, bool keyDown);
|
||||
virtual bool sendKeyEvent(int key, bool keyDown);
|
||||
|
||||
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp);
|
||||
|
||||
|
10
src/osgPlugins/pdf/CMakeLists.txt
Normal file
10
src/osgPlugins/pdf/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
SET(TARGET_SRC ReaderWriterPDF.cpp )
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CAIRO_INCLUDE_DIRS} ${POPPLER_INCLUDE_DIRS} )
|
||||
LINK_DIRECTORIES(${CAIRO_LIBRARY_DIRS} ${POPPLER_LIB_DIRS})
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${CAIRO_LIBRARIES} ${POPPLER_LIBRARIES} )
|
||||
|
||||
SET(TARGET_ADDED_LIBRARIES osgWidget )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_PLUGIN(pdf)
|
292
src/osgPlugins/pdf/ReaderWriterPDF.cpp
Normal file
292
src/osgPlugins/pdf/ReaderWriterPDF.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1999-2008 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software 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
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <osgWidget/PdfReader>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <poppler.h>
|
||||
|
||||
class CairoImage : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
CairoImage(osg::Image* image):
|
||||
_image(image),
|
||||
_surface(0),
|
||||
_context(0) {}
|
||||
|
||||
|
||||
void create(unsigned int width, unsigned int height)
|
||||
{
|
||||
if (_image->data() && width==_image->s() && height==_image->t()) return;
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Create cario surface/context "<<width<<", "<<height<<std::endl;
|
||||
|
||||
// allocate the image data
|
||||
_image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
_image->setPixelFormat(GL_BGRA);
|
||||
_image->setDataVariance(osg::Object::DYNAMIC);
|
||||
_image->setOrigin(osg::Image::TOP_LEFT);
|
||||
|
||||
|
||||
// create a cairo surface for this image data
|
||||
_surface = cairo_image_surface_create_for_data(
|
||||
_image->data(),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width, height,
|
||||
_image->getRowSizeInBytes());
|
||||
|
||||
// create a context for the surface
|
||||
_context = cairo_create(_surface);
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (_surface) cairo_surface_destroy(_surface);
|
||||
if (_context) cairo_destroy(_context);
|
||||
}
|
||||
|
||||
cairo_surface_t* getSurface() { return _surface; }
|
||||
const cairo_surface_t* getSurface() const { return _surface; }
|
||||
|
||||
cairo_t* getContext() { return _context; }
|
||||
const cairo_t* getContext() const { return _context; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~CairoImage()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
osg::observer_ptr<osg::Image> _image;
|
||||
cairo_surface_t* _surface;
|
||||
cairo_t* _context;
|
||||
};
|
||||
|
||||
class PopplerPdfImage : public osgWidget::PdfImage
|
||||
{
|
||||
public:
|
||||
|
||||
PopplerPdfImage():
|
||||
_doc(0)
|
||||
{
|
||||
_cairoImage = new CairoImage(this);
|
||||
}
|
||||
|
||||
virtual ~PopplerPdfImage()
|
||||
{
|
||||
_cairoImage = 0;
|
||||
|
||||
if (_doc)
|
||||
{
|
||||
g_object_unref(_doc);
|
||||
}
|
||||
}
|
||||
|
||||
PopplerDocument* _doc;
|
||||
|
||||
int getNumOfPages() { return _doc ? poppler_document_get_n_pages(_doc) : 0; }
|
||||
|
||||
bool open(const std::string& filename)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"open("<<filename<<")"<<std::endl;
|
||||
|
||||
std::string foundFile = osgDB::findDataFile(filename);
|
||||
if (foundFile.empty())
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"could not find filename="<<filename<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<"foundFile = "<<foundFile<<std::endl;
|
||||
foundFile = osgDB::getRealPath(foundFile);
|
||||
osg::notify(osg::NOTICE)<<"foundFile = "<<foundFile<<std::endl;
|
||||
|
||||
static bool gTypeInit = false;
|
||||
|
||||
if(!gTypeInit)
|
||||
{
|
||||
g_type_init();
|
||||
|
||||
gTypeInit = true;
|
||||
}
|
||||
|
||||
std::string uri = std::string("file:") + foundFile;
|
||||
|
||||
PopplerDocument* doc = poppler_document_new_from_file(uri.c_str(), NULL, NULL);
|
||||
if (!doc)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" could not open("<<filename<<"), uri="<<uri<<std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_doc)
|
||||
{
|
||||
g_object_unref(_doc);
|
||||
}
|
||||
|
||||
_doc = doc;
|
||||
_pageNum = 0;
|
||||
|
||||
setFileName(filename);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"getNumOfPages()=="<<getNumOfPages()<<std::endl;
|
||||
|
||||
if (getNumOfPages()==0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
page(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
if (keyDown)
|
||||
{
|
||||
if (key=='n')
|
||||
{
|
||||
next();
|
||||
return true;
|
||||
}
|
||||
else if (key=='p')
|
||||
{
|
||||
previous();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual bool page(int pageNum)
|
||||
{
|
||||
if (!_doc) return false;
|
||||
|
||||
if (pageNum<0 || pageNum>=getNumOfPages()) return false;
|
||||
|
||||
PopplerPage* page = poppler_document_get_page(_doc, pageNum);
|
||||
|
||||
if(!page) return false;
|
||||
|
||||
_pageNum = pageNum;
|
||||
|
||||
double w = 0.0f;
|
||||
double h = 0.0f;
|
||||
|
||||
poppler_page_get_size(page, &w, &h);
|
||||
|
||||
_cairoImage->create((unsigned int)(w*2.0),(unsigned int)(h*2.0));
|
||||
|
||||
double r = 1.0;
|
||||
double g = 1.0;
|
||||
double b = 1.0;
|
||||
double a = 1.0;
|
||||
|
||||
cairo_save(_cairoImage->getContext());
|
||||
|
||||
cairo_set_source_rgba(_cairoImage->getContext(), r, g, b, a);
|
||||
cairo_rectangle(_cairoImage->getContext(), 0.0, 0.0, double(s()), double(t()));
|
||||
cairo_fill(_cairoImage->getContext());
|
||||
|
||||
cairo_scale(_cairoImage->getContext(), double(s())/w, double(t())/h);
|
||||
|
||||
poppler_page_render(page, _cairoImage->getContext());
|
||||
|
||||
|
||||
cairo_restore(_cairoImage->getContext());
|
||||
|
||||
dirty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<CairoImage> _cairoImage;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ReaderWriterPDF : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
|
||||
ReaderWriterPDF()
|
||||
{
|
||||
supportsExtension("pdf","PDF plugin");
|
||||
}
|
||||
|
||||
virtual const char* className() const { return "PDF plugin"; }
|
||||
|
||||
virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
return readImage(file,options);
|
||||
}
|
||||
|
||||
virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
if (!osgDB::equalCaseInsensitive(osgDB::getFileExtension(fileName),"pdf"))
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
std::string file = osgDB::findDataFile(fileName);
|
||||
if (file.empty())
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
osg::ref_ptr<PopplerPdfImage> image = new PopplerPdfImage;
|
||||
image->setDataVariance(osg::Object::DYNAMIC);
|
||||
|
||||
image->setOrigin(osg::Image::TOP_LEFT);
|
||||
|
||||
if (!image->open(file))
|
||||
{
|
||||
return "Could not open "+file;
|
||||
}
|
||||
|
||||
return image.get();
|
||||
}
|
||||
|
||||
virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
osgDB::ReaderWriter::ReadResult result = readImage(fileName, options);
|
||||
if (!result.validImage()) return result;
|
||||
|
||||
|
||||
osg::ref_ptr<osgWidget::PdfReader> pdfReader = new osgWidget::PdfReader();
|
||||
if (pdfReader->assign(dynamic_cast<osgWidget::PdfImage*>(result.getImage())))
|
||||
{
|
||||
return pdfReader.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterPDF> g_readerWriter_PDF_Proxy;
|
||||
|
@ -4,7 +4,7 @@ INCLUDE_DIRECTORIES(${LIBVNCCLIENT_INCLUDE_DIR})
|
||||
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${LIBVNCCLIENT_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY} )
|
||||
|
||||
SET(TARGET_ADDED_LIBRARIES osgViewer )
|
||||
SET(TARGET_ADDED_LIBRARIES osgWidget )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_PLUGIN(vnc)
|
||||
|
@ -16,32 +16,30 @@
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgWidget/VncClient>
|
||||
|
||||
extern "C" {
|
||||
#include <rfb/rfbclient.h>
|
||||
}
|
||||
|
||||
class VncImage : public osg::Image
|
||||
class LibVncImage : public osgWidget::VncImage
|
||||
{
|
||||
public:
|
||||
|
||||
VncImage();
|
||||
LibVncImage();
|
||||
|
||||
bool connect(int* argc, char** argv);
|
||||
|
||||
bool connect(const std::string& hostname, const osgDB::ReaderWriter::Options* options);
|
||||
bool connect(const std::string& hostname);
|
||||
|
||||
void close();
|
||||
|
||||
virtual void sendPointerEvent(int x, int y, int buttonMask);
|
||||
virtual bool sendPointerEvent(int x, int y, int buttonMask);
|
||||
|
||||
double getTimeOfLastUpdate() const { return _timeOfLastUpdate; }
|
||||
double getTimeOfLastRender() const { return _timeOfLastRender; }
|
||||
|
||||
double time() const { return osg::Timer::instance()->time_s(); }
|
||||
|
||||
virtual void sendKeyEvent(int key, bool keyDown);
|
||||
virtual bool sendKeyEvent(int key, bool keyDown);
|
||||
|
||||
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp);
|
||||
|
||||
@ -59,13 +57,13 @@ class VncImage : public osg::Image
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~VncImage();
|
||||
virtual ~LibVncImage();
|
||||
|
||||
class RfbThread : public osg::Referenced, public OpenThreads::Thread
|
||||
{
|
||||
public:
|
||||
|
||||
RfbThread(rfbClient* client, VncImage* image):
|
||||
RfbThread(rfbClient* client, LibVncImage* image):
|
||||
_client(client),
|
||||
_image(image),
|
||||
_done(false) {}
|
||||
@ -120,7 +118,7 @@ class VncImage : public osg::Image
|
||||
}
|
||||
|
||||
rfbClient* _client;
|
||||
osg::observer_ptr<VncImage> _image;
|
||||
osg::observer_ptr<LibVncImage> _image;
|
||||
bool _done;
|
||||
|
||||
};
|
||||
@ -133,7 +131,7 @@ class VncImage : public osg::Image
|
||||
|
||||
};
|
||||
|
||||
VncImage::VncImage():
|
||||
LibVncImage::LibVncImage():
|
||||
_client(0)
|
||||
{
|
||||
// setPixelBufferObject(new osg::PixelBufferObject(this);
|
||||
@ -142,40 +140,11 @@ VncImage::VncImage():
|
||||
|
||||
}
|
||||
|
||||
VncImage::~VncImage()
|
||||
LibVncImage::~LibVncImage()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool VncImage::connect(int* argc, char** argv)
|
||||
{
|
||||
if (_client) close();
|
||||
|
||||
|
||||
_client = rfbGetClient(8,3,4);
|
||||
_client->canHandleNewFBSize = TRUE;
|
||||
_client->MallocFrameBuffer = resizeImage;
|
||||
_client->GotFrameBufferUpdate = updateImage;
|
||||
_client->HandleKeyboardLedState = 0;
|
||||
_client->HandleTextChat = 0;
|
||||
|
||||
rfbClientSetClientData(_client, 0, this);
|
||||
|
||||
if (rfbInitClient(_client,argc,argv))
|
||||
{
|
||||
_rfbThread = new RfbThread(_client, this);
|
||||
_rfbThread->startThread();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
close();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static rfbBool rfbInitConnection(rfbClient* client)
|
||||
{
|
||||
/* Unless we accepted an incoming connection, make a TCP connection to the
|
||||
@ -229,7 +198,7 @@ static rfbBool rfbInitConnection(rfbClient* client)
|
||||
}
|
||||
|
||||
|
||||
bool VncImage::connect(const std::string& hostname, const osgDB::ReaderWriter::Options* options)
|
||||
bool LibVncImage::connect(const std::string& hostname)
|
||||
{
|
||||
if (hostname.empty()) return false;
|
||||
|
||||
@ -268,7 +237,7 @@ bool VncImage::connect(const std::string& hostname, const osgDB::ReaderWriter::O
|
||||
}
|
||||
|
||||
|
||||
void VncImage::close()
|
||||
void LibVncImage::close()
|
||||
{
|
||||
if (_rfbThread.valid())
|
||||
{
|
||||
@ -287,7 +256,7 @@ void VncImage::close()
|
||||
}
|
||||
|
||||
|
||||
rfbBool VncImage::resizeImage(rfbClient* client)
|
||||
rfbBool LibVncImage::resizeImage(rfbClient* client)
|
||||
{
|
||||
osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0));
|
||||
|
||||
@ -304,30 +273,32 @@ rfbBool VncImage::resizeImage(rfbClient* client)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void VncImage::updateImage(rfbClient* client,int x,int y,int w,int h)
|
||||
void LibVncImage::updateImage(rfbClient* client,int x,int y,int w,int h)
|
||||
{
|
||||
osg::Image* image = (osg::Image*)(rfbClientGetClientData(client, 0));
|
||||
image->dirty();
|
||||
}
|
||||
|
||||
void VncImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
bool LibVncImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
if (_client)
|
||||
{
|
||||
SendPointerEvent(_client ,x, y, buttonMask);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void VncImage::sendKeyEvent(int key, bool keyDown)
|
||||
bool LibVncImage::sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
if (_client)
|
||||
{
|
||||
SendKeyEvent(_client, key, keyDown ? TRUE : FALSE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VncImage::setFrameLastRendered(const osg::FrameStamp*)
|
||||
void LibVncImage::setFrameLastRendered(const osg::FrameStamp*)
|
||||
{
|
||||
_timeOfLastRender = time();
|
||||
|
||||
@ -335,7 +306,7 @@ void VncImage::setFrameLastRendered(const osg::FrameStamp*)
|
||||
_active = true;
|
||||
}
|
||||
|
||||
void VncImage::updated()
|
||||
void LibVncImage::updated()
|
||||
{
|
||||
_timeOfLastUpdate = time();
|
||||
}
|
||||
@ -367,12 +338,12 @@ class ReaderWriterVNC : public osgDB::ReaderWriter
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Hostname = "<<hostname<<std::endl;
|
||||
|
||||
osg::ref_ptr<VncImage> image = new VncImage;
|
||||
osg::ref_ptr<LibVncImage> image = new LibVncImage;
|
||||
image->setDataVariance(osg::Object::DYNAMIC);
|
||||
|
||||
image->setOrigin(osg::Image::TOP_LEFT);
|
||||
|
||||
if (!image->connect(hostname, options))
|
||||
if (!image->connect(hostname))
|
||||
{
|
||||
return "Could not connect to "+hostname;
|
||||
}
|
||||
@ -385,38 +356,16 @@ class ReaderWriterVNC : public osgDB::ReaderWriter
|
||||
osgDB::ReaderWriter::ReadResult result = readImage(fileName, options);
|
||||
if (!result.validImage()) return result;
|
||||
|
||||
osg::Image* image = result.getImage();
|
||||
|
||||
bool xyPlane = false;
|
||||
bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
|
||||
osg::Vec3 origin = osg::Vec3(0.0f,0.0f,0.0f);
|
||||
float width = 1.0;
|
||||
float height = float(image->t())/float(image->s());
|
||||
osg::Vec3 widthAxis = osg::Vec3(width,0.0f,0.0f);
|
||||
osg::Vec3 heightAxis = xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height);
|
||||
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(origin, widthAxis, heightAxis,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(image);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
osg::ref_ptr<osgViewer::InteractiveImageHandler> callback = new osgViewer::InteractiveImageHandler(image);
|
||||
|
||||
pictureQuad->setEventCallback(callback.get());
|
||||
pictureQuad->setCullCallback(callback.get());
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(pictureQuad);
|
||||
|
||||
return geode;
|
||||
osg::ref_ptr<osgWidget::VncClient> vncClient = new osgWidget::VncClient();
|
||||
if (vncClient->assign(dynamic_cast<osgWidget::VncImage*>(result.getImage())))
|
||||
{
|
||||
return vncClient.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -705,8 +705,7 @@ bool InteractiveImageHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUI
|
||||
int x,y;
|
||||
if (mousePosition(view, nv, ea, x, y))
|
||||
{
|
||||
_image->sendPointerEvent(x, y, ea.getButtonMask());
|
||||
return true;
|
||||
return _image->sendPointerEvent(x, y, ea.getButtonMask());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -719,9 +718,7 @@ bool InteractiveImageHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUI
|
||||
|
||||
if (sendKeyEvent)
|
||||
{
|
||||
_image->sendKeyEvent(ea.getKey(), ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN);
|
||||
|
||||
return true;
|
||||
return _image->sendKeyEvent(ea.getKey(), ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/Export
|
||||
${HEADER_PATH}/Box
|
||||
${HEADER_PATH}/Browser
|
||||
${HEADER_PATH}/PdfReader
|
||||
${HEADER_PATH}/VncClient
|
||||
${HEADER_PATH}/Canvas
|
||||
${HEADER_PATH}/EventInterface
|
||||
${HEADER_PATH}/Frame
|
||||
@ -37,6 +39,8 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
${LIB_PUBLIC_HEADERS}
|
||||
Box.cpp
|
||||
Browser.cpp
|
||||
PdfReader.cpp
|
||||
VncClient.cpp
|
||||
Canvas.cpp
|
||||
CMakeLists.txt
|
||||
Frame.cpp
|
||||
|
100
src/osgWidget/PdfReader.cpp
Normal file
100
src/osgWidget/PdfReader.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <osgWidget/PdfReader>
|
||||
|
||||
#include <osg/io_utils>
|
||||
|
||||
using namespace osgWidget;
|
||||
|
||||
PdfReader::PdfReader(const std::string& filename, GeometryHints hints)
|
||||
{
|
||||
open(filename, hints);
|
||||
}
|
||||
|
||||
bool PdfReader::assign(PdfImage* pdfImage, GeometryHints hints)
|
||||
{
|
||||
if (!pdfImage) return false;
|
||||
|
||||
_pdfImage = pdfImage;
|
||||
|
||||
bool flip = _pdfImage->getOrigin()==osg::Image::TOP_LEFT;
|
||||
|
||||
float aspectRatio = (_pdfImage->t()>0 && _pdfImage->s()>0) ? float(_pdfImage->t()) / float(_pdfImage->s()) : 1.0;
|
||||
|
||||
osg::Vec3 widthVec(hints.widthVec);
|
||||
osg::Vec3 heightVec(hints.heightVec);
|
||||
|
||||
switch(hints.aspectRatioPolicy)
|
||||
{
|
||||
case(GeometryHints::RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO):
|
||||
heightVec *= aspectRatio;
|
||||
break;
|
||||
case(GeometryHints::RESIZE_WIDTH_TO_MAINTAINCE_ASPECT_RATIO):
|
||||
widthVec /= aspectRatio;
|
||||
break;
|
||||
default:
|
||||
// no need to adjust aspect ratio
|
||||
break;
|
||||
}
|
||||
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(hints.position, widthVec, heightVec,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(_pdfImage.get());
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(_pdfImage.get()));
|
||||
|
||||
addDrawable(pictureQuad);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PdfReader::open(const std::string& filename, GeometryHints hints)
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(filename);
|
||||
return assign(dynamic_cast<PdfImage*>(image.get()), hints);
|
||||
}
|
||||
|
||||
bool PdfReader::page(int pageNum)
|
||||
{
|
||||
if (!_pdfImage) return false;
|
||||
|
||||
return _pdfImage->page(pageNum);
|
||||
}
|
||||
|
||||
bool PdfReader::previous()
|
||||
{
|
||||
if (!_pdfImage) return false;
|
||||
|
||||
return _pdfImage->previous();
|
||||
}
|
||||
|
||||
bool PdfReader::next()
|
||||
{
|
||||
if (!_pdfImage) return false;
|
||||
|
||||
return _pdfImage->next();
|
||||
}
|
64
src/osgWidget/VncClient.cpp
Normal file
64
src/osgWidget/VncClient.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgWidget/VncClient>
|
||||
|
||||
using namespace osgWidget;
|
||||
|
||||
VncClient::VncClient(const std::string& hostname, GeometryHints hints)
|
||||
{
|
||||
connect(hostname, hints);
|
||||
}
|
||||
|
||||
bool VncClient::assign(VncImage* vncImage, GeometryHints hints)
|
||||
{
|
||||
if (!vncImage) return false;
|
||||
|
||||
_vncImage = vncImage;
|
||||
|
||||
bool flip = _vncImage->getOrigin()==osg::Image::TOP_LEFT;
|
||||
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(hints.position, hints.widthVec, hints.heightVec,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(_vncImage.get());
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(_vncImage.get()));
|
||||
|
||||
addDrawable(pictureQuad);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VncClient::connect(const std::string& hostname, GeometryHints hints)
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(hostname+".vnc");
|
||||
return assign(dynamic_cast<VncImage*>(image.get()));
|
||||
}
|
||||
|
||||
void VncClient::close()
|
||||
{
|
||||
if (!_vncImage) return;
|
||||
|
||||
_vncImage->close();
|
||||
}
|
Loading…
Reference in New Issue
Block a user