You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

356 lines
8.0 KiB

#include <time.h>
#include "qwt3d_plot.h"
#include "qwt3d_io_gl2ps.h"
#include "qwt3d_io_reader.h"
#if QT_VERSION < 0x040000
#else
#include <QImageWriter>
#endif
using namespace Qwt3D;
IO::Entry::Entry() : iofunc(0)
{
}
IO::Entry::~Entry()
{
delete iofunc;
}
IO::Entry::Entry(IO::Entry const& e)
{
if (this==&e)
return;
fmt = e.fmt;
iofunc = e.iofunc->clone();
}
void IO::Entry::operator=(IO::Entry const& e)
{
if (this==&e)
return;
delete iofunc;
fmt = e.fmt;
iofunc = e.iofunc->clone();
}
IO::Entry::Entry(QString const& s, Functor const& f)
: fmt(s)
{
iofunc = f.clone();
}
IO::Entry::Entry(QString const& s, Function f)
: fmt(s)
{
Wrapper w(f);
iofunc = w.clone();
}
IO::FormatCompare::FormatCompare(IO::Entry const& e)
{
e_ = e;
}
bool IO::FormatCompare::operator() (IO::Entry const& e)
{
return ( e.fmt == e_.fmt);
}
IO::FormatCompare2::FormatCompare2(QString s)
{
s_ = s;
}
bool IO::FormatCompare2::operator() (IO::Entry const& e)
{
return( e.fmt == s_);
}
bool IO::add_unique(Container& l, Entry const& e)
{
FormatCompare comp(e);
l.erase(std::remove_if(l.begin(), l.end(), comp), l.end());
l.push_back(e);
return true;
}
IO::IT IO::find(Container& l, QString const& fmt)
{
FormatCompare2 comp(fmt);
return std::find_if(l.begin(), l.end(), comp);
}
IO::Container& IO::rlist()
{
static Container rl = Container();
static bool rfirst = true;
bool f = false;
f = rfirst;
if (rfirst)
{
rfirst = false;
setupHandler();
}
return rl;
}
IO::Container& IO::wlist()
{
static Container wl = Container();
static bool wfirst = true;
bool f = false;
f = wfirst;
if (wfirst)
{
wfirst = false;
setupHandler();
}
return wl;
}
/*!
Registers a new IO::Function for data input.\n
Every call overwrites a formerly registered handler for the same format string
(case sensitive).
*/
bool IO::defineInputHandler(QString const& format, IO::Function func)
{
return add_unique(rlist(), Entry(format, func));
}
/*!
Registers a new Functor for data input.\n
Every call overwrites a formerly registered handler for the same format string
(case sensitive).
*/
bool IO::defineInputHandler(QString const& format, IO::Functor const& func)
{
return add_unique(rlist(), Entry(format, func));
}
/*!
Registers a new IO::Function for data output.
Every call overwrites a formerly registered handler for the same format string
(case sensitive).
*/
bool IO::defineOutputHandler(QString const& format, IO::Function func)
{
return add_unique(wlist(), Entry(format, func));
}
/*!
Registers a new Functor for data output.\n
Every call overwrites a formerly registered handler for the same format string
(case sensitive).
*/
bool IO::defineOutputHandler(QString const& format, IO::Functor const& func)
{
return add_unique(wlist(), Entry(format, func));
}
/*!
Applies a reading IO::Function or IO::Functor.
\param plot Plot with the content that should be loaded
\param fname File name
\param format Input format
\return The return value from the called Function/Functor.
The function returns false, if no registered handler could be found.
*/
bool IO::load(Plot3D* plot, QString const& fname, QString const& format)
{
IT it = IO::find(rlist(), format);
if (it == rlist().end())
return false;
return (*it->iofunc)(plot, fname);
}
/*!
Applies a writing IO::Function or IO::Functor.
\param plot Plot with the content that should be saved
\param fname File name
\param format Output format
\return The return value from the called Function/Functor.
The function returns false, if no registered handler could be found.
*/
bool IO::save(Plot3D* plot, QString const& fname, QString const& format)
{
IT it = IO::find(wlist(), format);
if (it == wlist().end())
return false;
return (*it->iofunc)(plot, fname);
}
/*!
Returns a list of currently registered input formats.
*/
QStringList IO::inputFormatList()
{
QStringList list;
for ( IT it = rlist().begin(); it!=rlist().end(); ++it )
list.append(it->fmt);
return list;
}
/*!
Returns a list of currently registered output formats.
*/
QStringList IO::outputFormatList()
{
QStringList list;
for ( IT it = wlist().begin(); it!=wlist().end(); ++it )
list.append(it->fmt);
return list;
}
/*!
Returns the input functor in charge for format and 0 if non-existent.
*/
IO::Functor* IO::inputHandler(QString const& format)
{
IO::IT it = IO::find(rlist(), format);
if (it==rlist().end())
return 0;
return it->iofunc;
}
/*!
Returns the output functor in charge for format and 0 if non-existent.
*/
IO::Functor* IO::outputHandler(QString const& format)
{
IO::IT it = IO::find(wlist(), format);
if (it==wlist().end())
return 0;
return it->iofunc;
}
bool PixmapWriter::operator()(Plot3D* plot, QString const& fname)
{
QImage im = plot->grabFrameBuffer(true);
#if QT_VERSION < 0x040000
QImageIO iio;
iio.setImage(im);
#else
QImageWriter iio;
#endif
iio.setFormat(QWT3DLOCAL8BIT(fmt_));
iio.setQuality(quality_);
iio.setFileName(fname);
#if QT_VERSION < 0x040000
return iio.write();
#else
return iio.write(im);
#endif
}
//! Calls Qt's QImageIO::setQuality() function.
void PixmapWriter::setQuality(int val)
{
quality_ = val;
}
void IO::setupHandler()
{
#if QT_VERSION < 0x040000
QStringList list = QImage::outputFormatList();
QStringList::Iterator it = list.begin();
#else
QList<QByteArray> list = QImageWriter::supportedImageFormats();
QList<QByteArray>::Iterator it = list.begin();
#endif
PixmapWriter qtw;
while( it != list.end() )
{
qtw.fmt_ = *it;
defineOutputHandler(*it, qtw);
++it;
}
VectorWriter vecfunc;
vecfunc.setCompressed(false);
vecfunc.setFormat("EPS");
defineOutputHandler("EPS", vecfunc);
vecfunc.setFormat("PS");
defineOutputHandler("PS", vecfunc);
#ifdef GL2PS_HAVE_ZLIB
vecfunc.setCompressed(true);
vecfunc.setFormat("EPS_GZ");
defineOutputHandler("EPS_GZ", vecfunc);
vecfunc.setFormat("PS_GZ");
defineOutputHandler("PS_GZ", vecfunc);
#endif
vecfunc.setFormat("PDF");
defineOutputHandler("PDF", vecfunc);
defineInputHandler("mes", NativeReader());
defineInputHandler("MES", NativeReader());
}
/*!
\deprecated Use Plot3D::save or IO::save instead.
Writes vector data supported by gl2ps. The corresponding format types are "EPS","PS"or "PDF".
If zlib has been configured this will be extended by "EPS_GZ" and "PS_GZ".
\b Beware: BSPSORT turns out to behave very slowly and memory consuming, especially in cases where
many polygons appear. It is still more exact than SIMPLESORT.
*/
bool Plot3D::saveVector(QString const& fileName, QString const& format, VectorWriter::TEXTMODE text, VectorWriter::SORTMODE sortmode)
{
if (format == "EPS" || format == "EPS_GZ" || format == "PS"
|| format == "PS_GZ" || format == "PDF")
{
VectorWriter* gl2ps = (VectorWriter*)IO::outputHandler(format);
if (gl2ps)
{
gl2ps->setSortMode(sortmode);
gl2ps->setTextMode(text);
}
return IO::save(this, fileName, format);
}
return false;
}
/*!
\deprecated Use Plot3D::save or IO::save instead.
Saves the framebuffer to the file fileName using one of the image file formats supported by Qt.
*/
bool Plot3D::savePixmap(QString const& fileName, QString const& format)
{
if (format == "EPS" || format == "EPS_GZ" || format == "PS"
|| format == "PS_GZ" || format == "PDF")
return false;
return IO::save(this, fileName, format);
}
/*!
Saves content in one of the registered output formats. To modify the
behaviour for more complex output handling use IO::outputHandler.
*/
bool Plot3D::save(QString const& fileName, QString const& format)
{
return IO::save(this, fileName, format);
}