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:
Robert Osfield
2008-12-07 17:02:30 +00:00
parent 0114ac4734
commit 6f356aeb97
20 changed files with 752 additions and 476 deletions

View File

@@ -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)
ADD_SUBDIRECTORY(osgpdf)
IF (BUILD_OSG_WRAPPERS)
ADD_SUBDIRECTORY(osgintrospection)

View File

@@ -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)

View File

@@ -10,314 +10,37 @@
#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();
}

View File

@@ -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,48 +44,34 @@ class EscapeHandler : public osgGA::GUIEventHandler
int main(int argc,char** argv)
{
osg::ArgumentParser arguments(&argc, argv);
osgViewer::Viewer viewer;
typedef std::list< osg::ref_ptr<osg::Image> > Images;
Images images;
osgViewer::Viewer viewer(arguments);
std::string hostname;
while (arguments.read("--host",hostname))
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)
{
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(hostname+std::string(".vnc"));
if (image.valid()) images.push_back(image.get());
}
if (images.empty())
{
return 1;
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;
}
}
}
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);
// add a custom escape handler, but disable the standard viewer one to enable the vnc images to handle
// the escape without it getting caught by the viewer.
viewer.addEventHandler(new EscapeHandler);

View File

@@ -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)