10 #include <QtGui/QImage>
11 #include <QtCore/QFile>
12 #include <QtGui/QPainter>
13 #include <QtGui/QPrinter>
14 #include <QtCore/QTextStream>
15 #include <QtCore/QTemporaryFile>
16 #include <kapplication.h>
21 #define BBOX "%%BoundingBox:"
22 #define BBOX_LEN strlen(BBOX)
24 static bool seekToCodeStart( QIODevice * io, quint32 & ps_offset, quint32 & ps_size )
30 if ( io->read(buf, 2)!=2 )
32 kError(399) <<
"kimgio EPS: EPS file has less than 2 bytes." << endl;
36 if ( buf[0]==
'%' && buf[1]==
'!' )
38 kDebug(399) <<
"kimgio EPS: normal EPS file";
40 else if ( buf[0]==
char(0xc5) && buf[1]==
char(0xd0) )
42 if ( io->read(buf+2, 2)!=2 )
44 kError(399) <<
"kimgio EPS: potential MS-DOS EPS file has less than 4 bytes." << endl;
47 if ( buf[2]==
char(0xd3) && buf[3]==
char(0xc6) )
49 if (io->read(buf, 4)!=4)
51 kError(399) <<
"kimgio EPS: cannot read offset of MS-DOS EPS file" << endl;
55 = ((
unsigned char) buf[0])
56 + ((
unsigned char) buf[1] << 8)
57 + ((
unsigned char) buf[2] << 16)
58 + ((
unsigned char) buf[3] << 24);
59 if (io->read(buf, 4)!=4)
61 kError(399) <<
"kimgio EPS: cannot read size of MS-DOS EPS file" << endl;
65 = ((
unsigned char) buf[0])
66 + ((
unsigned char) buf[1] << 8)
67 + ((
unsigned char) buf[2] << 16)
68 + ((
unsigned char) buf[3] << 24);
69 kDebug(399) <<
"kimgio EPS: Offset: " << ps_offset <<
" Size: " << ps_size;
70 if ( !io->seek(ps_offset) )
72 kError(399) <<
"kimgio EPS: cannot seek in MS-DOS EPS file" << endl;
75 if ( io->read(buf, 2)!=2 )
77 kError(399) <<
"kimgio EPS: PostScript code has less than 2 bytes." << endl;
80 if ( buf[0]==
'%' && buf[1]==
'!' )
82 kDebug(399) <<
"kimgio EPS: MS-DOS EPS file";
86 kError(399) <<
"kimgio EPS: supposed Postscript code of a MS-DOS EPS file doe not start with %!." << endl;
92 kError(399) <<
"kimgio EPS: wrong magic for potential MS-DOS EPS file!" << endl;
98 kError(399) <<
"kimgio EPS: not an EPS file!" << endl;
104 static bool bbox ( QIODevice *io,
int *x1,
int *y1,
int *x2,
int *y2)
110 while (io->readLine(buf,
BUFLEN) > 0)
116 float _x1, _y1, _x2, _y2;
117 if ( sscanf (buf,
"%*s %f %f %f %f",
118 &_x1, &_y1, &_x2, &_y2) == 4) {
119 kDebug(399) <<
"kimgio EPS BBOX: " << _x1 <<
" " << _y1 <<
" " << _x2 <<
" " << _y2;
120 *x1=(int)_x1; *y1=(int)_y1; *x2=(int)_x2; *y2=(int)_y2;
145 kDebug(399) <<
"kimgio EPS: starting...";
155 QIODevice* io = device();
156 quint32 ps_offset, ps_size;
163 if ( !
bbox (io, &x1, &y1, &x2, &y2)) {
164 kError(399) <<
"kimgio EPS: no bounding box found!" << endl;
168 QTemporaryFile tmpFile;
169 if( !tmpFile.open() ) {
170 kError(399) <<
"kimgio EPS: no temp file!" << endl;
182 int wantedWidth = x2;
183 int wantedHeight = y2;
187 cmdBuf =
"gs -sOutputFile=";
188 cmdBuf += tmpFile.fileName();
190 tmp.setNum( wantedWidth );
192 tmp.setNum( wantedHeight );
195 cmdBuf +=
" -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
200 "1 1 254 255 div setrgbcolor fill "
201 "0 0 0 setrgbcolor - -c showpage quit";
205 ghostfd = popen (QFile::encodeName(cmdBuf),
"w");
207 if ( ghostfd == 0 ) {
208 kError(399) <<
"kimgio EPS: no GhostScript?" << endl;
212 fprintf (ghostfd,
"\n%d %d translate\n", -qRound(x1*xScale), -qRound(y1*yScale));
219 QByteArray buffer ( io->readAll() );
222 if (ps_size<=0 || ps_size>(
unsigned int)buffer.size())
223 ps_size=buffer.size();
225 fwrite(buffer.data(),
sizeof(char), ps_size, ghostfd);
231 if( image->load (tmpFile.fileName()) ) {
232 kDebug(399) <<
"kimgio EPS: success!";
237 kError(399) <<
"kimgio EPS: no image!" << endl;
245 QPrinter psOut(QPrinter::PrinterResolution);
249 psOut.setCreator(
"KDE " KDE_VERSION_STRING );
250 if ( psOut.outputFileName().isEmpty() )
251 psOut.setOutputFileName(
"untitled_printer_document" );
254 QTemporaryFile tmpFile(
"XXXXXXXX.eps");
255 if ( !tmpFile.open() )
258 psOut.setOutputFileName(tmpFile.fileName());
259 psOut.setOutputFormat(QPrinter::PostScriptFormat);
260 psOut.setFullPage(
true);
261 psOut.setPaperSize(image.size(), QPrinter::DevicePixel);
265 p.drawImage( QPoint( 0, 0 ), image );
269 QFile inFile(tmpFile.fileName());
270 if ( !inFile.open( QIODevice::ReadOnly ) )
273 QTextStream in( &inFile );
274 in.setCodec(
"ISO-8859-1" );
275 QTextStream out( device() );
276 out.setCodec(
"ISO-8859-1" );
278 QString szInLine = in.readLine();
279 out << szInLine <<
'\n';
281 while( !in.atEnd() ){
282 szInLine = in.readLine();
283 out << szInLine <<
'\n';
299 qWarning(
"EPSHandler::canRead() called with no device");
303 qint64 oldPos = device->pos();
305 QByteArray head = device->readLine(64);
306 int readBytes = head.size();
307 if (device->isSequential()) {
308 while (readBytes > 0)
309 device->ungetChar(head[readBytes-- - 1]);
311 device->seek(oldPos);
314 return head.contains(
"%!PS-Adobe");
317 class EPSPlugin :
public QImageIOPlugin
320 QStringList keys()
const;
321 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
322 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
325 QStringList EPSPlugin::keys()
const
327 return QStringList() <<
"eps" <<
"EPS" <<
"epsi" <<
"EPSI" <<
"epsf" <<
"EPSF";
330 QImageIOPlugin::Capabilities EPSPlugin::capabilities(QIODevice *device,
const QByteArray &format)
const
332 if (format ==
"eps" || format ==
"epsi" || format ==
"EPS" || format ==
"EPSI" ||
333 format ==
"epsf" || format ==
"EPSF")
334 return Capabilities(CanRead | CanWrite);
335 if (!format.isEmpty())
337 if (!device->isOpen())
343 if (device->isWritable())
348 QImageIOHandler *EPSPlugin::create(QIODevice *device,
const QByteArray &format)
const
351 handler->setDevice(device);
352 handler->setFormat(format);
356 Q_EXPORT_STATIC_PLUGIN(EPSPlugin)
357 Q_EXPORT_PLUGIN2(eps, EPSPlugin)
static bool seekToCodeStart(QIODevice *io, quint32 &ps_offset, quint32 &ps_size)
static bool bbox(QIODevice *io, int *x1, int *y1, int *x2, int *y2)
bool write(const QImage &image)
#define BUFLEN
QImageIO Routines to read/write EPS images.
QImageIO Routines to read/write EPS images.