|
|
|
/**
|
|
|
|
* Copyright (C) 2000-2003 the KGhostView authors. See file AUTHORS.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __KPSWIDGET_H__
|
|
|
|
#define __KPSWIDGET_H__
|
|
|
|
|
|
|
|
#include <queue>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqwidget.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
|
|
|
|
#include "dscparse_adapter.h"
|
|
|
|
#include "configuration.h"
|
|
|
|
|
|
|
|
#include <X11/X.h>
|
|
|
|
|
|
|
|
class KProcess;
|
|
|
|
|
|
|
|
class KGVConfigDialog;
|
|
|
|
class MessagesDialog;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class KPSWidget
|
|
|
|
*
|
|
|
|
* @brief KPSWidget is a widget on which Ghostscript can render.
|
|
|
|
*
|
|
|
|
* @ref ghostscript_interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
class KPSWidget : public TQWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
KPSWidget( TQWidget* parent = 0, const char* name = 0 );
|
|
|
|
~KPSWidget();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start up the Ghostscript interpreter. Returns true if Ghostscript
|
|
|
|
* could be started; otherwise false.
|
|
|
|
*/
|
|
|
|
bool startInterpreter();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the interpreter process.
|
|
|
|
*/
|
|
|
|
void stopInterpreter();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the interpreter is ready for new input.
|
|
|
|
*/
|
|
|
|
bool isInterpreterReady() const;
|
|
|
|
|
|
|
|
bool isInterpreterBusy() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the interpreter is running; otherwise returns false.
|
|
|
|
*/
|
|
|
|
bool isInterpreterRunning() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tell ghostscript to start the next page.
|
|
|
|
* Returns false if ghostscript is not running, or not ready to start
|
|
|
|
* another page. If another page is started, sets the _interpreterReady
|
|
|
|
* flag and cursor.
|
|
|
|
*/
|
|
|
|
bool nextPage();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Queue a portion of a PostScript file for output to ghostscript and
|
|
|
|
* start processing the queue.
|
|
|
|
*
|
|
|
|
* fp: FILE* of the file in question. Should be seek()able.
|
|
|
|
* begin: position in file to start.
|
|
|
|
* len: number of bytes to write.
|
|
|
|
*
|
|
|
|
* If an interpreter is not running, nothing is queued and false is
|
|
|
|
* returned.
|
|
|
|
*/
|
|
|
|
bool sendPS( FILE*, unsigned int begin, unsigned int end );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the filename of the ghostscript input.
|
|
|
|
* @p usePipe indicates whether we use a pipe for
|
|
|
|
* communication or let ghoscript read the file itself.
|
|
|
|
*/
|
|
|
|
void setFileName( const TQString&, bool usePipe );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the bounding box of the drawable. See my comment in the source
|
|
|
|
* file.
|
|
|
|
*/
|
|
|
|
void setBoundingBox( const KDSCBBOX& );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the orientation of the page.
|
|
|
|
*/
|
|
|
|
void setOrientation( CDSC_ORIENTATION_ENUM );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the resolution according to the physical resolution of the screen
|
|
|
|
* and the magnification value.
|
|
|
|
*/
|
|
|
|
void setMagnification( double magnification );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the boundingbox of the drawable.
|
|
|
|
*/
|
|
|
|
const KDSCBBOX& boundingBox() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the current orientation.
|
|
|
|
*/
|
|
|
|
CDSC_ORIENTATION_ENUM orientation() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Double buffering means that all the drawing is done outside the
|
|
|
|
* screen and the finished picture is then flashed to the screen.
|
|
|
|
* This reduces flicker ( to almost none ) at the price of speed.
|
|
|
|
*
|
|
|
|
* By default, KPSWidget is *not* double buffered.
|
|
|
|
*/
|
|
|
|
bool isDoubleBuffered() const { return _doubleBuffer; }
|
|
|
|
void setDoubleBuffering( bool n );
|
|
|
|
|
|
|
|
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
/**
|
|
|
|
* Call this when the settings have changed.
|
|
|
|
*/
|
|
|
|
void readSettings();
|
|
|
|
signals:
|
|
|
|
/**
|
|
|
|
* This signal gets emited whenever a page is finished, but contains a reference to the pixmap
|
|
|
|
* used to hold the image.
|
|
|
|
*
|
|
|
|
* Don't change the pixmap or bad things will happen. This is the backing pixmap of the display.
|
|
|
|
*/
|
|
|
|
void newPageImage( TQPixmap image );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This signal is emitted whenever the ghostscript process has
|
|
|
|
* written data to stdout or stderr.
|
|
|
|
*/
|
|
|
|
void output( char* data, int len );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This means that gs exited uncleanly
|
|
|
|
*
|
|
|
|
* @param msg a <strong>translated</strong> error message to display the user which may be null if we cannot tell anything important
|
|
|
|
*/
|
|
|
|
void ghostscriptError( const TQString& mgs );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
struct Record
|
|
|
|
{
|
|
|
|
Record( FILE* fp_, long begin_, unsigned len_ )
|
|
|
|
:fp( fp_ ), begin( begin_ ), len( len_ ) { }
|
|
|
|
|
|
|
|
FILE* fp;
|
|
|
|
long begin;
|
|
|
|
unsigned int len;
|
|
|
|
};
|
|
|
|
|
|
|
|
// void resizeEvent( TQResizeEvent* );
|
|
|
|
bool x11Event( XEvent* );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup the widget according to the current settings for the
|
|
|
|
* boundingBox, the resolution and the orientation. This involves
|
|
|
|
* the following things:
|
|
|
|
* - Resize the widget
|
|
|
|
* - Resize and clear the background pixmap.
|
|
|
|
* - Setup the GHOSTVIEW and GHOSTVIEW_COLORS properties.
|
|
|
|
*
|
|
|
|
* Make sure ghostscript isn't running when calling this method.
|
|
|
|
*/
|
|
|
|
void setupWidget();
|
|
|
|
|
|
|
|
void setGhostscriptPath( const TQString& );
|
|
|
|
void setGhostscriptArguments( const TQStringList& );
|
|
|
|
void setPalette( Configuration::EnumPalette::type );
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void gs_input( KProcess* );
|
|
|
|
void gs_output( KProcess*, char* buffer, int len );
|
|
|
|
void interpreterFailed();
|
|
|
|
void slotProcessExited( KProcess* );
|
|
|
|
|
|
|
|
private:
|
|
|
|
Window _gsWindow; // Destination of ghostscript messages.
|
|
|
|
|
|
|
|
enum AtomName { GHOSTVIEW = 0, GHOSTVIEW_COLORS, NEXT, PAGE, DONE };
|
|
|
|
Atom _atoms[5];
|
|
|
|
|
|
|
|
TQPixmap _backgroundPixmap;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The following properties determine how Ghostscript is started.
|
|
|
|
* If any of these is changed, Ghostscript needs to be restarted.
|
|
|
|
*/
|
|
|
|
TQString _ghostscriptPath;
|
|
|
|
TQStringList _ghostscriptArguments;
|
|
|
|
TQString _fileName;
|
|
|
|
bool _usePipe;
|
|
|
|
bool _doubleBuffer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag set when one of the properties _ghostscriptPath,
|
|
|
|
* _ghostscriptArguments or _fileName has been changed.
|
|
|
|
*/
|
|
|
|
bool _ghostscriptDirty;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The following properties determine how Ghostscript renders its
|
|
|
|
* pages. If any of these is changed, the widget needs to be setup,
|
|
|
|
* and Ghostscript needs to be restarted.
|
|
|
|
*/
|
|
|
|
CDSC_ORIENTATION_ENUM _orientation;
|
|
|
|
KDSCBBOX _boundingBox;
|
|
|
|
float _magnification;
|
|
|
|
Configuration::EnumPalette::type _palette;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag set when one of the properties _orientation, _boundingBox,
|
|
|
|
* _dpi[X|Y] or _palette has been changed.
|
|
|
|
*/
|
|
|
|
bool _widgetDirty;
|
|
|
|
|
|
|
|
KProcess* _process;
|
|
|
|
char* _buffer;
|
|
|
|
|
|
|
|
std::queue<Record> _inputQueue;
|
|
|
|
|
|
|
|
bool _stdinReady;
|
|
|
|
bool _interpreterBusy;
|
|
|
|
bool _interpreterReady;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline const KDSCBBOX& KPSWidget::boundingBox() const
|
|
|
|
{
|
|
|
|
return _boundingBox;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline CDSC_ORIENTATION_ENUM KPSWidget::orientation() const
|
|
|
|
{
|
|
|
|
return _orientation;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @page ghostview_interface Ghostview interface to Ghostscript
|
|
|
|
*
|
|
|
|
* When the GHOSTVIEW environment variable is set, Ghostscript draws on
|
|
|
|
* an existing drawable rather than creating its own window. Ghostscript
|
|
|
|
* can be directed to draw on either a window or a pixmap.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @section window Drawing on a Window
|
|
|
|
*
|
|
|
|
* The GHOSTVIEW environment variable contains the window id of the target
|
|
|
|
* window. The window id is an integer. Ghostscript will use the attributes
|
|
|
|
* of the window to obtain the width, height, colormap, screen, and visual of
|
|
|
|
* the window. The remainder of the information is gotten from the GHOSTVIEW
|
|
|
|
* property on that window.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @section pixmap Drawing on a Pixmap
|
|
|
|
*
|
|
|
|
* The GHOSTVIEW environment variable contains a window id and a pixmap id.
|
|
|
|
* They are integers separated by white space. Ghostscript will use the
|
|
|
|
* attributes of the window to obtain the colormap, screen, and visual to use.
|
|
|
|
* The width and height will be obtained from the pixmap. The remainder of the
|
|
|
|
* information, is gotten from the GHOSTVIEW property on the window. In this
|
|
|
|
* case, the property is deleted when read.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @section gv_variable The GHOSTVIEW environment variable
|
|
|
|
*
|
|
|
|
* @par parameters:
|
|
|
|
* <tt> window-id [pixmap-id] </tt>
|
|
|
|
*
|
|
|
|
* @par scanf format:
|
|
|
|
* @code "%d %d" @endcode
|
|
|
|
*
|
|
|
|
* @par Explanation of the parameters
|
|
|
|
* @li @e window-id:
|
|
|
|
* tells Ghostscript where to:
|
|
|
|
* - read the GHOSTVIEW property
|
|
|
|
* - send events
|
|
|
|
* If pixmap-id is not present, Ghostscript will draw on this window.
|
|
|
|
*
|
|
|
|
* @li @e pixmap-id:
|
|
|
|
* If present, tells Ghostscript that a pixmap will be used as the
|
|
|
|
* final destination for drawing. The window will not be touched for
|
|
|
|
* drawing purposes.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @section gv_property The GHOSTVIEW property
|
|
|
|
*
|
|
|
|
* @par type:
|
|
|
|
* STRING
|
|
|
|
*
|
|
|
|
* @par parameters:
|
|
|
|
* <tt> bpixmap orient llx lly urx ury xdpi ydpi [left bottom top right]
|
|
|
|
* </tt>
|
|
|
|
*
|
|
|
|
* @par scanf format:
|
|
|
|
* @code "%d %d %d %d %d %d %f %f %d %d %d %d" @endcode
|
|
|
|
*
|
|
|
|
* @par Explanation of the parameters
|
|
|
|
* @li @e bpixmap:
|
|
|
|
* pixmap id of the backing pixmap for the window. If no pixmap is to
|
|
|
|
* be used, this parameter should be zero. This parameter must be zero
|
|
|
|
* when drawing on a pixmap.
|
|
|
|
*
|
|
|
|
* @li <em>orient:</em>
|
|
|
|
* orientation of the page. The number represents clockwise rotation
|
|
|
|
* of the paper in degrees. Permitted values are 0, 90, 180, 270.
|
|
|
|
*
|
|
|
|
* @li <em>llx, lly, urx, ury:</em>
|
|
|
|
* Bounding box of the drawable. The bounding box is specified in
|
|
|
|
* PostScript points in default user coordinates. (Note the word
|
|
|
|
* @e drawable. This means that this bounding box is generally not
|
|
|
|
* the same as the BoundingBox specified in the DSC. In case
|
|
|
|
* DocumentMedia is specified, it is equal to the Media's bounding
|
|
|
|
* box.)
|
|
|
|
*
|
|
|
|
* @li <em>xdpi, ydpi:</em>
|
|
|
|
* Resolution of window. (This can be derived from the other
|
|
|
|
* parameters, but not without roundoff error. These values are
|
|
|
|
* included to avoid this error.)
|
|
|
|
*
|
|
|
|
* @li <em>left, bottom, top, right (optional):</em>
|
|
|
|
* Margins around the window. The margins extend the imageable area
|
|
|
|
* beyond the boundaries of the window. This is primarily used for
|
|
|
|
* popup zoom windows. I have encountered several instances of
|
|
|
|
* PostScript programs that position themselves with respect to the
|
|
|
|
* imageable area. The margins are specified in PostScript points.
|
|
|
|
* If omitted, the margins are assumed to be 0.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @section events Events from Ghostscript
|
|
|
|
*
|
|
|
|
* If the final destination is a pixmap, the client will get a property
|
|
|
|
* notify event when Ghostscript reads the GHOSTVIEW property causing it to
|
|
|
|
* be deleted.
|
|
|
|
*
|
|
|
|
* Ghostscript sends events to the window where it read the GHOSTVIEW
|
|
|
|
* property. These events are of type ClientMessage. The message_type is set
|
|
|
|
* to either PAGE or DONE. The first long data value gives the window to be
|
|
|
|
* used to send replies to Ghostscript. The second long data value gives the
|
|
|
|
* primary drawable. If rendering to a pixmap, it is the primary drawable.
|
|
|
|
* If rendering to a window, the backing pixmap is the primary drawable. If
|
|
|
|
* no backing pixmap is employed, then the window is the primary drawable.
|
|
|
|
* This field is necessary to distinguish multiple Ghostscripts rendering to
|
|
|
|
* separate pixmaps where the GHOSTVIEW property was placed on the same
|
|
|
|
* window.
|
|
|
|
*
|
|
|
|
* The PAGE message indicates that a "page" has completed. Ghostscript will
|
|
|
|
* wait until it receives a ClientMessage whose message_type is NEXT before
|
|
|
|
* continuing.
|
|
|
|
*
|
|
|
|
* The DONE message indicates that Ghostscript has finished processing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#endif // __KPSWIDGET_H__
|
|
|
|
|
|
|
|
|
|
|
|
// vim:sw=4:sts=4:ts=8:noet
|