okular/psgs.cpp
Waldo Bastian 675e01cc9b add -dSAFER -dPARANOIDSAFER when dealing with ghostscript (#56808)
svn path=/trunk/kdegraphics/kdvi/; revision=219376
2003-04-09 21:02:56 +00:00

199 lines
5.8 KiB
C++

#include <stdio.h>
#include <kdebug.h>
#include <klocale.h>
#include <kprocess.h>
#include "psgs.h"
extern const char psheader[];
pageInfo::pageInfo(QString _PostScriptString) {
PostScriptString = new QString(_PostScriptString);
Gfx = NULL;
}
pageInfo::~pageInfo() {
if (PostScriptString != 0L)
delete PostScriptString;
}
// ======================================================
ghostscript_interface::ghostscript_interface(double dpi, int pxlw, int pxlh) {
pageList.setAutoDelete(TRUE);
MemoryCache.setAutoDelete(TRUE);
DiskCache.setAutoDelete(TRUE);
PostScriptHeaderString = new QString();
resolution = dpi;
pixel_page_w = pxlw;
pixel_page_h = pxlh;
}
ghostscript_interface::~ghostscript_interface() {
if (PostScriptHeaderString != 0L)
delete PostScriptHeaderString;
}
void ghostscript_interface::setSize(double dpi, int pxlw, int pxlh) {
resolution = dpi;
pixel_page_w = pxlw;
pixel_page_h = pxlh;
MemoryCache.clear();
DiskCache.clear();
}
void ghostscript_interface::setPostScript(int page, QString PostScript) {
if (pageList.find(page) == 0) {
pageInfo *info = new pageInfo(PostScript);
// Check if dict is big enough
if (pageList.count() > pageList.size() -2)
pageList.resize(pageList.size()*2);
pageList.insert(page, info);
} else
*(pageList.find(page)->PostScriptString) = PostScript;
}
void ghostscript_interface::setIncludePath(const QString &_includePath) {
if (_includePath.isEmpty())
includePath = "*"; // Allow all files
else
includePath = _includePath+"/*";
}
void ghostscript_interface::setColor(int page, QColor background_color) {
if (pageList.find(page) == 0) {
pageInfo *info = new pageInfo(QString::null);
info->background = background_color;
// Check if dict is big enough
if (pageList.count() > pageList.size() -2)
pageList.resize(pageList.size()*2);
pageList.insert(page, info);
} else
pageList.find(page)->background = background_color;
}
// Returns the background color for a certain page. This color is
// always guaranteed to be valid
QColor ghostscript_interface::getBackgroundColor(int page) {
if (pageList.find(page) == 0)
return Qt::white;
else
return pageList.find(page)->background;
}
void ghostscript_interface::clear(void) {
PostScriptHeaderString->truncate(0);
MemoryCache.clear();
DiskCache.clear();
// Deletes all items, removes temporary files, etc.
pageList.clear();
}
void ghostscript_interface::gs_generate_graphics_file(int page, QString filename) {
emit(setStatusBarText(i18n("Generating PostScript graphics...")));
pageInfo *info = pageList.find(page);
// Generate a PNG-file
// Step 1: Write the PostScriptString to a File
KTempFile PSfile(QString::null,".ps");
FILE *f = PSfile.fstream();
fputs("%!PS-Adobe-2.0\n",f);
fputs("%%Creator: kdvi\n",f);
fputs("%%Title: KDVI temporary PostScript\n",f);
fputs("%%Pages: 1\n",f);
fputs("%%PageOrder: Ascend\n",f);
fprintf(f,"%%BoundingBox: 0 0 %ld %ld\n",
(long)(72*(pixel_page_w/resolution)),
(long)(72*(pixel_page_h/resolution))); // HSize and VSize in 1/72 inch
fputs("%%EndComments\n",f);
fputs("%!\n",f);
fputs(psheader,f);
fputs("TeXDict begin",f);
fprintf(f," %ld", (long)(72*65781*(pixel_page_w/resolution)) ); // HSize in (1/(65781.76*72))inch @@@
fprintf(f," %ld", (long)(72*65781*(pixel_page_h/resolution)) ); // VSize in (1/(65781.76*72))inch
fputs(" 1000",f); // Magnification
fputs(" 300 300",f); // dpi and vdpi
fputs(" (test.dvi)",f); // Name
fputs(" @start end\n",f);
fputs("TeXDict begin\n",f);
fputs("1 0 bop 0 0 a \n",f); // Start page
if (PostScriptHeaderString->latin1() != NULL)
fputs(PostScriptHeaderString->latin1(),f);
if (info->PostScriptString->latin1() != NULL)
fputs(info->PostScriptString->latin1(),f);
fputs("end\n",f);
fputs("showpage \n",f);
PSfile.close();
// Step 2: Call GS with the File
KProcess proc;
proc << "gs";
proc << "-dSAFER" << "-dPARANOIDSAFER" << "-dDELAYSAFER" << "-dNOPAUSE" << "-dBATCH" << "-sDEVICE=png256";
proc << QString("-sOutputFile=%1").arg(filename);
proc << QString("-sExtraIncludePath=%1").arg(includePath);
proc << QString("-g%1x%2").arg(pixel_page_w).arg(pixel_page_h); // page size in pixels
proc << QString("-r%1").arg(resolution); // resolution in dpi
proc << "-c" << "<< /PermitFileReading [ ExtraIncludePath ] /PermitFileWriting [] /PermitFileControl [] >> setuserparams .locksafe";
proc << "-f" << PSfile.name();
proc.start(KProcess::Block);
PSfile.unlink();
emit(setStatusBarText(QString::null));
}
QPixmap *ghostscript_interface::graphics(int page) {
pageInfo *info = pageList.find(page);
// No PostScript? Then return immediately.
if ((info == 0) || (info->PostScriptString->isEmpty()))
return 0;
// Gfx exists in the MemoryCache?
QPixmap *CachedCopy = MemoryCache.find(page);
if (CachedCopy != NULL)
return new QPixmap(*CachedCopy);
// Gfx exists in the DiskCache?
KTempFile *CachedCopyFile = DiskCache.find(page);
if (CachedCopyFile != NULL) {
QPixmap *MemoryCopy = new QPixmap(CachedCopyFile->name());
QPixmap *ReturnCopy = new QPixmap(*MemoryCopy);
MemoryCache.insert(page, MemoryCopy);
return ReturnCopy;
}
// Gfx exists neither in Disk- nor in Memorycache. We have to build
// it ourselfes.
KTempFile *GfxFile = new KTempFile(QString::null,".png");
GfxFile->setAutoDelete(1);
GfxFile->close(); // we are want the filename, not the file
gs_generate_graphics_file(page, GfxFile->name());
QPixmap *MemoryCopy = new QPixmap(GfxFile->name());
QPixmap *ReturnCopy = new QPixmap(*MemoryCopy);
MemoryCache.insert(page, MemoryCopy);
DiskCache.insert(page, GfxFile);
return ReturnCopy;
}
#include "psgs.moc"