- code for use of command line GS interpreter, reused from kghostview, a little remodeled, still fails to work,

GS says it cant open the initial device, does it mean the pximap or the widget? does the widget need to be shown
  before it can receive communication from X11?
  Asking Luis, he might know. I wanted to use the library version of the interpreter but it 
  somehow fails to create instance... Will investigate it later.
CCMAIL: luis@luispedro.org

svn path=/trunk/playground/graphics/oKular/kpdf/; revision=439247
This commit is contained in:
Piotr Szymanski 2005-07-27 13:52:37 +00:00
parent bb8e583945
commit 0be10d88e5
8 changed files with 5504 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,477 @@
/* Copyright (C) 2000-2001, Ghostgum Software Pty Ltd. All rights reserved.
This file is part of GSview.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the GNU General Public Licence for full details.
Everyone is granted permission to copy, modify and redistribute this
file, but only under the conditions described in the GNU General
Public Licence. A copy of this license is supposed to have been given
to you along with this file so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies.
*/
/* $Id: dscparse.h 420737 2005-06-01 09:09:35Z wgreven $ */
/* dscparse.h */
/* Interface for the DSC parser. */
#ifndef _DSCPARSE_H_
#define _DSCPARSE_H_
/* Some local types that may need modification */
typedef bool GSBOOL;
typedef unsigned long GSDWORD; /* must be at least 32 bits */
typedef unsigned int GSWORD; /* must be at least 16 bits */
#ifndef FALSE
# define FALSE ((GSBOOL)0)
# define TRUE ((GSBOOL)(!FALSE))
#endif
#ifndef dsc_private
# ifdef private
# define dsc_private private
# else
# define dsc_private static
# endif
#endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/* macros to allow conversion of function declarations to K&R */
#ifndef P0
#define P0() void
#define P1(t1) t1
#define P2(t1,t2) t1,t2
#define P3(t1,t2,t3) t1,t2,t3
#define P4(t1,t2,t3,t4) t1,t2,t3,t4
#define P5(t1,t2,t3,t4,t5) t1,t2,t3,t4,t5
#define P6(t1,t2,t3,t4,t5,t6) t1,t2,t3,t4,t5,t6
#endif
/* maximum legal length of lines in a DSC compliant file */
#define DSC_LINE_LENGTH 255
/* memory for strings is allocated in chunks of this length */
#define CDSC_STRING_CHUNK 4096
/* page array is allocated in chunks of this many pages */
#define CDSC_PAGE_CHUNK 128
/* buffer length for storing lines passed to dsc_scan_data() */
/* must be at least 2 * DSC_LINE_LENGTH */
/* We choose 8192 as twice the length passed to us by GSview */
#define CDSC_DATA_LENGTH 8192
/* Return codes from dsc_scan_data()
* < 0 = error
* >=0 = OK
*
* -1 = error, usually insufficient memory.
* 0-9 = normal
* 10-99 = internal codes, should not be seen.
* 100-999 = identifier of last DSC comment processed.
*/
typedef enum {
CDSC_ERROR = -1, /* Fatal error, usually insufficient memory */
CDSC_OK = 0, /* OK, no DSC comment found */
CDSC_NOTDSC = 1, /* Not DSC, or DSC is being ignored */
/* Any section */
CDSC_UNKNOWNDSC = 100, /* DSC comment not recognised */
/* Header section */
CDSC_PSADOBE = 200, /* %!PS-Adobe- */
CDSC_BEGINCOMMENTS = 201, /* %%BeginComments */
CDSC_ENDCOMMENTS = 202, /* %%EndComments */
CDSC_PAGES = 203, /* %%Pages: */
CDSC_CREATOR = 204, /* %%Creator: */
CDSC_CREATIONDATE = 205, /* %%CreationDate: */
CDSC_TITLE = 206, /* %%Title: */
CDSC_FOR = 207, /* %%For: */
CDSC_LANGUAGELEVEL = 208, /* %%LanguageLevel: */
CDSC_BOUNDINGBOX = 209, /* %%BoundingBox: */
CDSC_ORIENTATION = 210, /* %%Orientation: */
CDSC_PAGEORDER = 211, /* %%PageOrder: */
CDSC_DOCUMENTMEDIA = 212, /* %%DocumentMedia: */
CDSC_DOCUMENTPAPERSIZES = 213, /* %%DocumentPaperSizes: */
CDSC_DOCUMENTPAPERFORMS = 214, /* %%DocumentPaperForms: */
CDSC_DOCUMENTPAPERCOLORS = 215, /* %%DocumentPaperColors: */
CDSC_DOCUMENTPAPERWEIGHTS = 216, /* %%DocumentPaperWeights: */
CDSC_DOCUMENTDATA = 217, /* %%DocumentData: */
CDSC_REQUIREMENTS = 218, /* IGNORED %%Requirements: */
CDSC_DOCUMENTNEEDEDFONTS = 219, /* IGNORED %%DocumentNeededFonts: */
CDSC_DOCUMENTSUPPLIEDFONTS = 220, /* IGNORED %%DocumentSuppliedFonts: */
CDSC_HIRESBOUNDINGBOX = 221, /* %%HiResBoundingBox: */
CDSC_CROPBOX = 222, /* %%CropBox: */
/* Preview section */
CDSC_BEGINPREVIEW = 301, /* %%BeginPreview */
CDSC_ENDPREVIEW = 302, /* %%EndPreview */
/* Defaults section */
CDSC_BEGINDEFAULTS = 401, /* %%BeginDefaults */
CDSC_ENDDEFAULTS = 402, /* %%EndDefaults */
/* also %%PageMedia, %%PageOrientation, %%PageBoundingBox */
/* Prolog section */
CDSC_BEGINPROLOG = 501, /* %%BeginProlog */
CDSC_ENDPROLOG = 502, /* %%EndProlog */
CDSC_BEGINFONT = 503, /* IGNORED %%BeginFont */
CDSC_ENDFONT = 504, /* IGNORED %%EndFont */
CDSC_BEGINFEATURE = 505, /* IGNORED %%BeginFeature */
CDSC_ENDFEATURE = 506, /* IGNORED %%EndFeature */
CDSC_BEGINRESOURCE = 507, /* IGNORED %%BeginResource */
CDSC_ENDRESOURCE = 508, /* IGNORED %%EndResource */
CDSC_BEGINPROCSET = 509, /* IGNORED %%BeginProcSet */
CDSC_ENDPROCSET = 510, /* IGNORED %%EndProcSet */
/* Setup section */
CDSC_BEGINSETUP = 601, /* %%BeginSetup */
CDSC_ENDSETUP = 602, /* %%EndSetup */
CDSC_FEATURE = 603, /* IGNORED %%Feature: */
CDSC_PAPERCOLOR = 604, /* IGNORED %%PaperColor: */
CDSC_PAPERFORM = 605, /* IGNORED %%PaperForm: */
CDSC_PAPERWEIGHT = 606, /* IGNORED %%PaperWeight: */
CDSC_PAPERSIZE = 607, /* %%PaperSize: */
/* also %%Begin/EndFeature, %%Begin/EndResource */
/* Page section */
CDSC_PAGE = 700, /* %%Page: */
CDSC_PAGETRAILER = 701, /* IGNORED %%PageTrailer */
CDSC_BEGINPAGESETUP = 702, /* IGNORED %%BeginPageSetup */
CDSC_ENDPAGESETUP = 703, /* IGNORED %%EndPageSetup */
CDSC_PAGEMEDIA = 704, /* %%PageMedia: */
/* also %%PaperColor, %%PaperForm, %%PaperWeight, %%PaperSize */
CDSC_PAGEORIENTATION = 705, /* %%PageOrientation: */
CDSC_PAGEBOUNDINGBOX = 706, /* %%PageBoundingBox: */
/* also %%Begin/EndFont, %%Begin/EndFeature */
/* also %%Begin/EndResource, %%Begin/EndProcSet */
CDSC_INCLUDEFONT = 707, /* IGNORED %%IncludeFont: */
CDSC_VIEWINGORIENTATION = 708, /* %%ViewingOrientation: */
/* Trailer section */
CDSC_TRAILER = 800, /* %%Trailer */
/* also %%Pages, %%BoundingBox, %%Orientation, %%PageOrder, %%DocumentMedia */
/* %%Page is recognised as an error */
/* also %%DocumentNeededFonts, %%DocumentSuppliedFonts */
/* End of File */
CDSC_EOF = 900 /* %%EOF */
} CDSC_RETURN_CODE;
/* stored in dsc->preview */
typedef enum {
CDSC_NOPREVIEW = 0,
CDSC_EPSI = 1,
CDSC_TIFF = 2,
CDSC_WMF = 3,
CDSC_PICT = 4
} CDSC_PREVIEW_TYPE;
/* stored in dsc->page_order */
typedef enum {
CDSC_ORDER_UNKNOWN = 0,
CDSC_ASCEND = 1,
CDSC_DESCEND = 2,
CDSC_SPECIAL = 3
} CDSC_PAGE_ORDER;
/* stored in dsc->page_orientation and dsc->page[pagenum-1].orientation */
typedef enum {
CDSC_ORIENT_UNKNOWN = 0,
CDSC_PORTRAIT = 1,
CDSC_LANDSCAPE = 2,
CDSC_UPSIDEDOWN = 3,
CDSC_SEASCAPE = 4
} CDSC_ORIENTATION_ENUM;
/* stored in dsc->document_data */
typedef enum {
CDSC_DATA_UNKNOWN = 0,
CDSC_CLEAN7BIT = 1,
CDSC_CLEAN8BIT = 2,
CDSC_BINARY = 3
} CDSC_DOCUMENT_DATA ;
typedef struct CDSCBBOX_S {
int llx;
int lly;
int urx;
int ury;
} CDSCBBOX;
typedef struct CDSCFBBOX_S {
float fllx;
float flly;
float furx;
float fury;
} CDSCFBBOX;
typedef struct CDSCMEDIA_S {
const char *name;
float width; /* PostScript points */
float height;
float weight; /* GSM */
const char *colour;
const char *type;
CDSCBBOX *mediabox; /* Used by GSview for PDF MediaBox */
} CDSCMEDIA;
#define CDSC_KNOWN_MEDIA 46
extern const CDSCMEDIA dsc_known_media[CDSC_KNOWN_MEDIA];
typedef struct CDSCCTM_S { /* used for %%ViewingOrientation */
float xx;
float xy;
float yx;
float yy;
/* float ty; */
/* float ty; */
} CDSCCTM;
typedef struct CDSCPAGE_S {
int ordinal;
const char *label;
unsigned long begin;
unsigned long end;
unsigned int orientation;
const CDSCMEDIA *media;
CDSCBBOX *bbox; /* PageBoundingBox, also used by GSview for PDF CropBox */
CDSCCTM *viewing_orientation;
} CDSCPAGE;
/* binary DOS EPS header */
typedef struct CDSCDOSEPS_S {
GSDWORD ps_begin;
GSDWORD ps_length;
GSDWORD wmf_begin;
GSDWORD wmf_length;
GSDWORD tiff_begin;
GSDWORD tiff_length;
GSWORD checksum;
} CDSCDOSEPS;
/* rather than allocated every string with malloc, we allocate
* chunks of 4k and place the (usually) short strings in these
* chunks.
*/
typedef struct CDSCSTRING_S CDSCSTRING;
struct CDSCSTRING_S {
unsigned int index;
unsigned int length;
char *data;
CDSCSTRING *next;
};
/* DSC error reporting */
typedef enum {
CDSC_MESSAGE_BBOX = 0,
CDSC_MESSAGE_EARLY_TRAILER = 1,
CDSC_MESSAGE_EARLY_EOF = 2,
CDSC_MESSAGE_PAGE_IN_TRAILER = 3,
CDSC_MESSAGE_PAGE_ORDINAL = 4,
CDSC_MESSAGE_PAGES_WRONG = 5,
CDSC_MESSAGE_EPS_NO_BBOX = 6,
CDSC_MESSAGE_EPS_PAGES = 7,
CDSC_MESSAGE_NO_MEDIA = 8,
CDSC_MESSAGE_ATEND = 9,
CDSC_MESSAGE_DUP_COMMENT = 10,
CDSC_MESSAGE_DUP_TRAILER = 11,
CDSC_MESSAGE_BEGIN_END = 12,
CDSC_MESSAGE_BAD_SECTION = 13,
CDSC_MESSAGE_LONG_LINE = 14,
CDSC_MESSAGE_INCORRECT_USAGE = 15
} CDSC_MESSAGE_ERROR;
/* severity */
typedef enum {
CDSC_ERROR_INFORM = 0, /* Not an error */
CDSC_ERROR_WARN = 1, /* Not a DSC error itself, */
CDSC_ERROR_ERROR = 2 /* DSC error */
} CDSC_MESSAGE_SEVERITY;
/* response */
typedef enum {
CDSC_RESPONSE_OK = 0,
CDSC_RESPONSE_CANCEL = 1,
CDSC_RESPONSE_IGNORE_ALL = 2
} CDSC_RESPONSE;
extern const char * const dsc_message[];
typedef struct CDSC_S CDSC;
struct CDSC_S {
/* public data */
GSBOOL dsc; /* TRUE if DSC comments found */
GSBOOL ctrld; /* TRUE if has CTRLD at start of stream */
GSBOOL pjl; /* TRUE if has HP PJL at start of stream */
GSBOOL epsf; /* TRUE if EPSF */
GSBOOL pdf; /* TRUE if Portable Document Format */
unsigned int preview; /* enum CDSC_PREVIEW_TYPE */
char *dsc_version; /* first line of file */
unsigned int language_level;
unsigned int document_data; /* Clean7Bit, Clean8Bit, Binary */
/* enum CDSC_DOCUMENT_DATA */
/* DSC sections */
unsigned long begincomments;
unsigned long endcomments;
unsigned long beginpreview;
unsigned long endpreview;
unsigned long begindefaults;
unsigned long enddefaults;
unsigned long beginprolog;
unsigned long endprolog;
unsigned long beginsetup;
unsigned long endsetup;
unsigned long begintrailer;
unsigned long endtrailer;
CDSCPAGE *page;
unsigned int page_count; /* number of %%Page: pages in document */
unsigned int page_pages; /* number of pages in document from %%Pages: */
unsigned int page_order; /* enum CDSC_PAGE_ORDER */
unsigned int page_orientation; /* the default page orientation */
/* enum CDSC_ORIENTATION */
CDSCCTM *viewing_orientation;
unsigned int media_count; /* number of media items */
CDSCMEDIA **media; /* the array of media */
const CDSCMEDIA *page_media;/* the default page media */
CDSCBBOX *bbox; /* the document bounding box */
CDSCBBOX *page_bbox; /* the default page bounding box */
CDSCDOSEPS *doseps; /* DOS binary header */
char *dsc_title;
char *dsc_creator;
char *dsc_date;
char *dsc_for;
unsigned int max_error; /* highest error number that will be reported */
const int *severity; /* array of severity values, one per error */
/* private data */
void *caller_data; /* pointer to be provided when calling */
/* error and debug callbacks */
int id; /* last DSC comment found */
int scan_section; /* section currently being scanned */
/* enum CDSC_SECTION */
unsigned long doseps_end; /* ps_begin+ps_length, otherwise 0 */
unsigned int page_chunk_length; /* number of pages allocated */
unsigned long file_length; /* length of document */
/* If provided we try to recognise %%Trailer and %%EOF */
/* incorrectly embedded inside document. */
/* Can be left set to default value of 0 */
int skip_document; /* recursion level of %%BeginDocument: */
int skip_bytes; /* #bytes to ignore from BeginData: */
/* or DOSEPS preview section */
int skip_lines; /* #lines to ignore from BeginData: */
GSBOOL skip_pjl; /* TRUE if skip PJL until first PS comment */
int begin_font_count; /* recursion level of %%BeginFont */
int begin_feature_count; /* recursion level of %%BeginFeature */
int begin_resource_count; /* recursion level of %%BeginResource */
int begin_procset_count; /* recursion level of %%BeginProcSet */
/* buffer for input */
char data[CDSC_DATA_LENGTH];/* start of buffer */
unsigned int data_length; /* length of data in buffer */
unsigned int data_index; /* offset to next char in buffer */
unsigned long data_offset; /* offset from start of document */
/* to byte in data[0] */
GSBOOL eof; /* TRUE if there is no more data */
/* information about DSC line */
char *line; /* pointer to last read DSC line */
/* not null terminated */
unsigned int line_length; /* number of characters in line */
GSBOOL eol; /* TRUE if dsc_line contains EOL */
GSBOOL last_cr; /* TRUE if last line ended in \r */
/* check next time for \n */
unsigned int line_count; /* line number */
GSBOOL long_line; /* TRUE if found a line longer than 255 characters */
char last_line[256]; /* previous DSC line, used for %%+ */
/* more efficient string storage (for short strings) than malloc */
CDSCSTRING *string_head; /* linked list head */
CDSCSTRING *string; /* current list item */
/* memory allocation routines */
void *(*memalloc)(P2(size_t size, void *closure_data));
void (*memfree)(P2(void *ptr, void *closure_data));
void *mem_closure_data;
/* function for printing debug messages */
void (*debug_print_fn)(P2(void *caller_data, const char *str));
/* function for reporting errors in DSC comments */
int (*dsc_error_fn)(P5(void *caller_data, CDSC *dsc,
unsigned int explanation, const char *line, unsigned int line_len));
/* public data */
/* Added 2001-10-01 */
CDSCFBBOX *hires_bbox; /* the hires document bounding box */
CDSCFBBOX *crop_box; /* the size of the trimmed page */
};
/* Public functions */
/* Create and initialise DSC parser */
CDSC *dsc_init(P1(void *caller_data));
CDSC *dsc_init_with_alloc(P4(
void *caller_data,
void *(*memalloc)(size_t size, void *closure_data),
void (*memfree)(void *ptr, void *closure_data),
void *closure_data));
/* Free the DSC parser */
void dsc_free(P1(CDSC *dsc));
/* Tell DSC parser how long document will be, to allow ignoring
* of early %%Trailer and %%EOF. This is optional.
*/
void dsc_set_length(P2(CDSC *dsc, unsigned long len));
/* Process a buffer containing DSC comments and PostScript */
int dsc_scan_data(P3(CDSC *dsc, const char *data, int len));
/* All data has been processed, fixup any DSC errors */
int dsc_fixup(P1(CDSC *dsc));
/* Install error query function */
void dsc_set_error_function(P2(CDSC *dsc,
int (*dsc_error_fn)(P5(void *caller_data, CDSC *dsc,
unsigned int explanation, const char *line, unsigned int line_len))));
/* Install print function for debug messages */
void dsc_set_debug_function(P2(CDSC *dsc,
void (*debug_fn)(P2(void *caller_data, const char *str))));
/* Print a message to debug output, if provided */
void dsc_debug_print(P2(CDSC *dsc, const char *str));
/* should be internal only functions, but made available to
* GSview for handling PDF
*/
int dsc_add_page(P3(CDSC *dsc, int ordinal, char *label));
int dsc_add_media(P2(CDSC *dsc, CDSCMEDIA *media));
int dsc_set_page_bbox(P6(CDSC *dsc, unsigned int page_number,
int llx, int lly, int urx, int ury));
#endif
// vim:sw=4:sts=4:ts=8:noet

View file

@ -0,0 +1,420 @@
/**
* Copyright (C) 2001 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 Steet, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dscparse_adapter.h"
using namespace std;
/*-- KDSCBBOX implementation -----------------------------------------------*/
KDSCBBOX::KDSCBBOX() :
_llx( 0 ), _lly( 0 ),
_urx( 0 ), _ury( 0 )
{}
KDSCBBOX::KDSCBBOX( const KDSCBBOX& b ) :
_llx( b._llx ), _lly( b._lly ),
_urx( b._urx ), _ury( b._ury )
{}
KDSCBBOX::KDSCBBOX( int llx, int lly, int urx, int ury ) :
_llx( llx ), _lly( lly ),
_urx( urx ), _ury( ury )
{}
KDSCBBOX::KDSCBBOX( const CDSCBBOX& bbox ) :
_llx( bbox.llx ), _lly( bbox.lly ),
_urx( bbox.urx ), _ury( bbox.ury )
{}
KDSCBBOX& KDSCBBOX::operator = ( const KDSCBBOX& b )
{
_llx = b._llx; _lly = b._lly; _urx = b._urx; _ury = b._ury;
return *this;
}
bool KDSCBBOX::operator == ( const KDSCBBOX& b )
{
return ( _llx == b._llx && _lly == b._lly
&& _urx == b._urx && _ury == b._ury );
}
bool KDSCBBOX::operator != ( const KDSCBBOX& b )
{
return !( *this == b );
}
int KDSCBBOX::llx() const { return _llx; }
int KDSCBBOX::lly() const { return _lly; }
int KDSCBBOX::urx() const { return _urx; }
int KDSCBBOX::ury() const { return _ury; }
int KDSCBBOX::width() const { return _urx - _llx; }
int KDSCBBOX::height() const { return _ury - _lly; }
QSize KDSCBBOX::size() const { return QSize( width(), height() ); }
ostream& operator << ( ostream& os, const KDSCBBOX& source )
{
os << "{ llx: "<< source.llx() << ", lly: " << source.lly()
<< " urx: "<< source.urx() << ", ury: " << source.ury() << " }";
return os;
}
/*-- KDSCError implementation ----------------------------------------------*/
KDSCError::KDSCError( Type type, Severity severity, const QCString& line,
unsigned int lineNumber ) :
_type( type ),
_severity( severity ),
_line( line ),
_lineNumber( lineNumber )
{}
KDSCError::Type KDSCError::type() const
{
return _type;
}
KDSCError::Severity KDSCError::severity() const
{
return _severity;
}
QCString KDSCError::line() const
{
return _line;
}
unsigned int KDSCError::lineNumber() const
{
return _lineNumber;
}
/*-- KDSCOkErrorHandler implementation -------------------------------------*/
KDSCErrorHandler::Response KDSCOkErrorHandler::error( const KDSCError& err )
{
cout << "KDSC: error in line " << err.lineNumber() << endl;
cout << err.line() << endl;
return Ok;
}
/*-- KDSC implementation ---------------------------------------------------*/
KDSC::KDSC() :
_errorHandler( 0 ),
_commentHandler( 0 )
{
_cdsc = dsc_init( this );
Q_ASSERT( _cdsc != 0 );
_scanHandler = new KDSCScanHandler( _cdsc );
}
KDSC::~KDSC()
{
dsc_free( _cdsc );
delete _scanHandler;
}
QString KDSC::dsc_version() const
{
return QString( _cdsc->dsc_version );
}
bool KDSC::dsc() const
{
return ( _cdsc->dsc == TRUE );
}
bool KDSC::ctrld() const
{
return ( _cdsc->ctrld == TRUE );
}
bool KDSC::pjl() const
{
return ( _cdsc->pjl == TRUE );
}
bool KDSC::epsf() const
{
return ( _cdsc->epsf == TRUE );
}
bool KDSC::pdf() const
{
return ( _cdsc->pdf == TRUE );
}
unsigned int KDSC::preview() const
{
return _cdsc->preview;
}
unsigned int KDSC::language_level() const
{
return _cdsc->language_level;
}
unsigned int KDSC::document_data() const
{
return _cdsc->document_data;
}
unsigned long KDSC::begincomments() const
{
return _cdsc->begincomments;
}
unsigned long KDSC::endcomments() const
{
return _cdsc->endcomments;
}
unsigned long KDSC::beginpreview() const
{
return _cdsc->beginpreview;
}
unsigned long KDSC::endpreview() const
{
return _cdsc->endpreview;
}
unsigned long KDSC::begindefaults() const
{
return _cdsc->begindefaults;
}
unsigned long KDSC::enddefaults() const
{
return _cdsc->enddefaults;
}
unsigned long KDSC::beginprolog() const
{
return _cdsc->beginprolog;
}
unsigned long KDSC::endprolog() const
{
return _cdsc->endprolog;
}
unsigned long KDSC::beginsetup() const
{
return _cdsc->beginsetup;
}
unsigned long KDSC::endsetup() const
{
return _cdsc->endsetup;
}
unsigned long KDSC::begintrailer() const
{
return _cdsc->begintrailer;
}
unsigned long KDSC::endtrailer() const
{
return _cdsc->endtrailer;
}
CDSCPAGE* KDSC::page() const
{
return _cdsc->page;
}
unsigned int KDSC::page_count() const
{
return _cdsc->page_count;
}
unsigned int KDSC::page_pages() const
{
return _cdsc->page_pages;
}
unsigned int KDSC::page_order() const
{
return _cdsc->page_order;
}
unsigned int KDSC::page_orientation() const
{
return _cdsc->page_orientation;
}
CDSCCTM* KDSC::viewing_orientation() const
{
return _cdsc->viewing_orientation;
}
unsigned int KDSC::media_count() const
{
return _cdsc->media_count;
}
CDSCMEDIA** KDSC::media() const
{
return _cdsc->media;
}
const CDSCMEDIA* KDSC::page_media() const
{
return _cdsc->page_media;
}
auto_ptr<KDSCBBOX> KDSC::bbox() const
{
if( _cdsc->bbox == 0 )
return auto_ptr<KDSCBBOX>( 0 );
else
return auto_ptr<KDSCBBOX>( new KDSCBBOX( *_cdsc->bbox ) );
}
auto_ptr<KDSCBBOX> KDSC::page_bbox() const
{
if( _cdsc->page_bbox == 0 )
return auto_ptr<KDSCBBOX>( 0 );
else
return auto_ptr<KDSCBBOX>( new KDSCBBOX( *_cdsc->page_bbox ) );
}
QString KDSC::dsc_title() const
{
return QString( _cdsc->dsc_title );
}
QString KDSC::dsc_creator() const
{
return QString( _cdsc->dsc_creator );
}
QString KDSC::dsc_date() const
{
return QString( _cdsc->dsc_date );
}
QString KDSC::dsc_for() const
{
return QString( _cdsc->dsc_for );
}
bool KDSC::scanData( char* buffer, unsigned int count )
{
return _scanHandler->scanData( buffer, count );
}
int KDSC::fixup()
{
return dsc_fixup( _cdsc );
}
KDSCErrorHandler* KDSC::errorHandler() const
{
return _errorHandler;
}
void KDSC::setErrorHandler( KDSCErrorHandler* errorHandler )
{
_errorHandler = errorHandler;
if( errorHandler == 0 )
dsc_set_error_function( _cdsc, 0 );
else
dsc_set_error_function( _cdsc, &errorFunction );
}
KDSCCommentHandler* KDSC::commentHandler() const
{
return _commentHandler;
}
void KDSC::setCommentHandler( KDSCCommentHandler* commentHandler )
{
if( _commentHandler != 0 && commentHandler == 0 )
{
delete _scanHandler;
_scanHandler = new KDSCScanHandler( _cdsc );
}
else if( _commentHandler == 0 && commentHandler != 0 )
{
delete _scanHandler;
_scanHandler = new KDSCScanHandlerByLine( _cdsc, commentHandler );
}
_commentHandler = commentHandler;
}
bool KDSC::isStructured() const
{
return epsf() ? ( page_count() > 1 ) : ( page_count() > 0 );
}
CDSC* KDSC::cdsc() const
{
return _cdsc;
}
int KDSC::errorFunction( void* caller_data, CDSC* dsc,
unsigned int explanation, const char* line, unsigned int line_len )
{
KDSCError error(
static_cast< KDSCError::Type >( explanation ),
static_cast< KDSCError::Severity >( dsc->severity[explanation] ),
QCString( line, line_len + 1 ),
dsc->line_count
);
KDSC* kdsc = static_cast< KDSC* >( caller_data );
Q_ASSERT( kdsc );
return kdsc->errorHandler()->error( error );
}
bool KDSCScanHandlerByLine::scanData( char* buf, unsigned int count )
{
char* lineStart = buf;
char* it = buf;
while( it < buf + count )
{
if( *it++ == '\n' )
{
int retval = dsc_scan_data( _cdsc, lineStart, it - lineStart );
if( retval < 0 )
return false;
else if( retval > 0 )
{
_commentHandler->comment(
static_cast<KDSCCommentHandler::Name>( retval ) );
}
lineStart = it;
}
}
if( it != lineStart )
{
// Scan the remaining part of the string.
return ( dsc_scan_data( _cdsc, lineStart, it - lineStart ) < 0 );
}
else
return true;
}
// vim:sw=4:sts=4:ts=8:noet

View file

@ -0,0 +1,388 @@
/**
* Copyright (C) 2001 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 Steet, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef DSCPARSE_ADAPTER_H
#define DSCPARSE_ADAPTER_H
#include <iostream>
#include <map>
#include <memory>
#include <qsize.h>
#include <qstring.h>
#include "dscparse.h"
#undef min
#undef max
#if defined(__GNUC__)
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 93)
/*
* We add a quick 'n' dirty inline implementation of auto_ptr for older
* releases of GCC, which don't include an auto_ptr implementation in
* <memory>.
*/
template <class T> class auto_ptr {
private:
T* _ptr;
public:
typedef T element_type;
explicit auto_ptr(T* p = 0) : _ptr(p) {}
auto_ptr(auto_ptr& a) : _ptr(a.release()) {}
template <class T1> auto_ptr(auto_ptr<T1>& a) : _ptr(a.release()) {}
auto_ptr& operator=(auto_ptr& a) {
if (&a != this) {
delete _ptr;
_ptr = a.release();
}
return *this;
}
template <class T1>
auto_ptr& operator=(auto_ptr<T1>& a) {
if (a.get() != this->get()) {
delete _ptr;
_ptr = a.release();
}
return *this;
}
~auto_ptr() { delete _ptr; }
T& operator*() const { return *_ptr; }
T* operator->() const { return _ptr; }
T* get() const { return _ptr; }
T* release() { T* tmp = _ptr; _ptr = 0; return tmp; }
void reset(T* p = 0) { delete _ptr; _ptr = p; }
};
#endif
#endif
class KDSCBBOX
{
public:
KDSCBBOX();
KDSCBBOX( const KDSCBBOX& b );
KDSCBBOX( int llx, int lly, int urx, int ury );
KDSCBBOX( const CDSCBBOX& bbox );
KDSCBBOX& operator = ( const KDSCBBOX& b );
bool operator == ( const KDSCBBOX& b );
bool operator != ( const KDSCBBOX& b );
int llx() const;
int lly() const;
int urx() const;
int ury() const;
int width() const;
int height() const;
QSize size() const;
private:
int _llx, _lly, _urx, _ury;
};
std::ostream& operator << ( std::ostream&, const KDSCBBOX& );
class KDSCError
{
public:
enum Type
{
BBox = CDSC_MESSAGE_BBOX,
EarlyTrailer = CDSC_MESSAGE_EARLY_TRAILER,
EarlyEOF = CDSC_MESSAGE_EARLY_EOF,
PageInTrailer = CDSC_MESSAGE_PAGE_IN_TRAILER,
PageOrdinal = CDSC_MESSAGE_PAGE_ORDINAL,
PagesWrong = CDSC_MESSAGE_PAGES_WRONG,
EPSNoBBox = CDSC_MESSAGE_EPS_NO_BBOX,
EPSPages = CDSC_MESSAGE_EPS_PAGES,
NoMedia = CDSC_MESSAGE_NO_MEDIA,
AtEnd = CDSC_MESSAGE_ATEND,
DuplicateComment = CDSC_MESSAGE_DUP_COMMENT,
DuplicateTrailer = CDSC_MESSAGE_DUP_TRAILER,
BeginEnd = CDSC_MESSAGE_BEGIN_END,
BadSection = CDSC_MESSAGE_BAD_SECTION,
LongLine = CDSC_MESSAGE_LONG_LINE,
IncorrectUsage = CDSC_MESSAGE_INCORRECT_USAGE
};
enum Severity
{
Information = CDSC_ERROR_INFORM,
Warning = CDSC_ERROR_WARN,
Error = CDSC_ERROR_ERROR
};
KDSCError( Type, Severity, const QCString& line,
unsigned int lineNumber );
Type type() const;
Severity severity() const;
QCString line() const;
unsigned int lineNumber() const;
private:
Type _type;
Severity _severity;
QCString _line;
unsigned int _lineNumber;
};
class KDSCErrorHandler
{
public:
virtual ~KDSCErrorHandler() {}
enum Response
{
Ok = CDSC_RESPONSE_OK,
Cancel = CDSC_RESPONSE_CANCEL,
IgnoreAll = CDSC_RESPONSE_IGNORE_ALL
};
virtual Response error( const KDSCError& ) = 0;
};
class KDSCOkErrorHandler : public KDSCErrorHandler
{
Response error( const KDSCError& );
};
class KDSCCommentHandler
{
public:
virtual ~KDSCCommentHandler() {}
enum Name
{
// Header section
PSAdobe = CDSC_PSADOBE,
BeginComments = CDSC_BEGINCOMMENTS,
EndComments = CDSC_ENDCOMMENTS,
Pages = CDSC_PAGES,
Creator = CDSC_CREATOR,
CreationDate = CDSC_CREATIONDATE,
Title = CDSC_TITLE,
For = CDSC_FOR,
LanguageLevel = CDSC_LANGUAGELEVEL,
BoundingBox = CDSC_BOUNDINGBOX,
Orientation = CDSC_ORIENTATION,
PageOrder = CDSC_PAGEORDER,
DocumentMedia = CDSC_DOCUMENTMEDIA,
DocumentPaperSizes = CDSC_DOCUMENTPAPERSIZES,
DocumentPaperForms = CDSC_DOCUMENTPAPERFORMS,
DocumentPaperColors = CDSC_DOCUMENTPAPERCOLORS,
DocumentPaperWeights = CDSC_DOCUMENTPAPERWEIGHTS,
DocumentData = CDSC_DOCUMENTDATA,
Requirements = CDSC_REQUIREMENTS,
DocumentNeededFonts = CDSC_DOCUMENTNEEDEDFONTS,
DocumentSuppliedFonts = CDSC_DOCUMENTSUPPLIEDFONTS,
HiResBoundingBox = CDSC_HIRESBOUNDINGBOX,
CropBox = CDSC_CROPBOX,
// Preview section
BeginPreview = CDSC_BEGINPREVIEW,
EndPreview = CDSC_ENDPREVIEW,
// Defaults section
BeginDefaults = CDSC_BEGINDEFAULTS,
EndDefaults = CDSC_ENDDEFAULTS,
// also %%PageMedia, %%PageOrientation, %%PageBoundingBox
// Prolog section
BeginProlog = CDSC_BEGINPROLOG,
EndProlog = CDSC_ENDPROLOG,
BeginFont = CDSC_BEGINFONT,
EndFont = CDSC_ENDFONT,
BeginFeature = CDSC_BEGINFEATURE,
EndFeature = CDSC_ENDFEATURE,
BeginResource = CDSC_BEGINRESOURCE,
EndResource = CDSC_ENDRESOURCE,
BeginProcset = CDSC_BEGINPROCSET,
EndProcset = CDSC_ENDPROCSET,
// Setup section
BeginSetup = CDSC_BEGINSETUP,
EndSetup = CDSC_ENDSETUP,
Feature = CDSC_FEATURE,
PaperColor = CDSC_PAPERCOLOR,
PaperForm = CDSC_PAPERFORM,
PaperWeight = CDSC_PAPERWEIGHT,
PaperSize = CDSC_PAPERSIZE,
// also %%Begin/EndFeature, %%Begin/EndResource
// Page section
Page = CDSC_PAGE,
PageTrailer = CDSC_PAGETRAILER,
BeginPageSetup = CDSC_BEGINPAGESETUP,
EndPageSetup = CDSC_ENDPAGESETUP,
PageMedia = CDSC_PAGEMEDIA,
// also %%PaperColor, %%PaperForm, %%PaperWeight, %%PaperSize
PageOrientation = CDSC_PAGEORIENTATION,
PageBoundingBox = CDSC_PAGEBOUNDINGBOX,
// also %%Begin/EndFont, %%Begin/EndFeature
// also %%Begin/EndResource, %%Begin/EndProcSet
IncludeFont = CDSC_INCLUDEFONT,
ViewingOrientation = CDSC_VIEWINGORIENTATION,
// Trailer section
Trailer = CDSC_TRAILER,
// also %%Pages, %%BoundingBox, %%Orientation, %%PageOrder,
// %%DocumentMedia
// %%Page is recognised as an error
// also %%DocumentNeededFonts, %%DocumentSuppliedFonts
// End of File */
Eof = CDSC_EOF
};
virtual void comment( Name name ) { std::cout << name << std::endl; }
};
class KDSCScanHandler;
class KDSC
{
public:
KDSC();
~KDSC();
/*--- Adapter for CDSC ------------------------------------------------*/
QString dsc_version() const;
bool dsc() const;
bool ctrld() const;
bool pjl() const;
bool epsf() const;
bool pdf() const;
unsigned int preview() const;
unsigned int language_level() const;
unsigned int document_data() const;
unsigned long begincomments() const;
unsigned long endcomments() const;
unsigned long beginpreview() const;
unsigned long endpreview() const;
unsigned long begindefaults() const;
unsigned long enddefaults() const;
unsigned long beginprolog() const;
unsigned long endprolog() const;
unsigned long beginsetup() const;
unsigned long endsetup() const;
unsigned long begintrailer() const;
unsigned long endtrailer() const;
CDSCPAGE* page() const;
unsigned int page_count() const;
unsigned int page_pages() const;
unsigned int page_order() const;
unsigned int page_orientation() const;
CDSCCTM* viewing_orientation() const;
unsigned int media_count() const;
CDSCMEDIA** media() const;
const CDSCMEDIA* page_media() const;
#if defined(__GNUC__) && (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 93))
auto_ptr<KDSCBBOX> bbox() const;
auto_ptr<KDSCBBOX> page_bbox() const;
#else
std::auto_ptr<KDSCBBOX> bbox() const;
std::auto_ptr<KDSCBBOX> page_bbox() const;
#endif
// CDSCDOSEPS *doseps;
QString dsc_title() const;
QString dsc_creator() const;
QString dsc_date() const;
QString dsc_for() const;
// unsigned int max_error
bool scanData( char*, unsigned int );
/**
* Tidy up from incorrect DSC comments.
*/
int fixup();
KDSCErrorHandler* errorHandler() const;
void setErrorHandler( KDSCErrorHandler* );
KDSCCommentHandler* commentHandler() const;
void setCommentHandler( KDSCCommentHandler* );
/*--- Extra methods for convenience -----------------------------------*/
bool isStructured() const;
/*--- Temporary -------------------------------------------------------*/
CDSC* cdsc() const;
protected:
static int errorFunction( void* caller_data, CDSC* dsc,
unsigned int explanation,
const char* line, unsigned int line_len );
private:
CDSC* _cdsc;
KDSCErrorHandler* _errorHandler;
KDSCCommentHandler* _commentHandler;
KDSCScanHandler* _scanHandler;
};
class KDSCScanHandler
{
public:
virtual ~KDSCScanHandler() {}
KDSCScanHandler( CDSC* cdsc ) : _cdsc( cdsc ) {}
virtual bool scanData( char* buf, unsigned int count )
{
return ( dsc_scan_data( _cdsc, buf, count ) >= 0 );
}
protected:
CDSC* _cdsc;
};
class KDSCScanHandlerByLine : public KDSCScanHandler
{
public:
KDSCScanHandlerByLine( CDSC* cdsc, KDSCCommentHandler* commentHandler ) :
KDSCScanHandler( cdsc ),
_commentHandler( commentHandler )
{}
virtual bool scanData( char* buf, unsigned int count );
protected:
KDSCCommentHandler* _commentHandler;
};
#endif
// vim:sw=4:sts=4:ts=8:noet

View file

@ -0,0 +1,78 @@
/***************************************************************************
* Copyright (C) 1997-2005 the KGhostView authors. See file GV_AUTHORS. *
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
* *
* Many portions of this file are based on kghostview's kpswidget code *
* *
* 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. *
***************************************************************************/
#include <qtextedit.h>
#include <qlabel.h>
#include <qvbox.h>
#include <kglobalsettings.h>
#include <kurllabel.h>
#include <klocale.h>
#include "gvlogwindow.h"
GVLogWindow::GVLogWindow( const QString& caption,
QWidget* parent, const char* name) :
KDialogBase( parent, name, false, caption, User1|Close, Close, false,
KStdGuiItem::clear() )
{
QVBox * display = makeVBoxMainWidget();
m_errorIndication = new QLabel( "", display, "logview-label" );
m_errorIndication->hide();
m_configureGS = new KURLLabel( i18n( "Configure Ghostscript" ), QString::null, display );
m_configureGS->hide();
m_logView = new QTextEdit( display, "logview" );
m_logView->setTextFormat( Qt::PlainText );
m_logView->setReadOnly( true );
m_logView->setWordWrap( QTextEdit::NoWrap );
m_logView->setFont( KGlobalSettings::fixedFont() );
m_logView->setMinimumWidth( 80 * fontMetrics().width( " " ) );
connect( this, SIGNAL( user1Clicked() ), SLOT( clear() ) );
connect( m_configureGS, SIGNAL( leftClickedURL() ), SLOT( emitConfigureGS() ) );
}
void GVLogWindow::emitConfigureGS() {
emit configureGS();
}
void GVLogWindow::append( const QString& message )
{
m_logView->append( message );
this->show();
}
void GVLogWindow::append( char* buf, int num )
{
m_logView->append( QString::fromLocal8Bit( buf, num ) );
// if( _showLogWindow )
this->show();
}
void GVLogWindow::clear()
{
m_logView->clear();
m_errorIndication->clear();
}
void GVLogWindow::setLabel( const QString& text, bool showConfigureGS )
{
m_errorIndication->setText( text );
m_errorIndication->show();
if ( showConfigureGS ) m_configureGS->show();
else m_configureGS->hide();
}
#include "gvlogwindow.moc"

View file

@ -0,0 +1,49 @@
/***************************************************************************
* Copyright (C) 1997-2005 the KGhostView authors. See file GV_AUTHORS. *
* *
* Many portions of this file are based on kghostview's kpswidget code *
* *
* 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. *
***************************************************************************/
#ifndef LOGWINDOW_H
#define LOGWINDOW_H
#include <kdialogbase.h>
class QLabel;
class QTextEdit;
class KURLLabel;
class GVLogWindow : public KDialogBase
{
Q_OBJECT
public:
GVLogWindow( const QString& caption,
QWidget* parent = 0, const char* name = 0 );
public slots:
void append( const QString& message );
void append( char* buf, int num );
void clear();
void setLabel( const QString&, bool showConfigureGSLink );
private slots:
void emitConfigureGS();
signals:
void configureGS();
private:
QLabel* m_errorIndication;
QTextEdit* m_logView;
KURLLabel* m_configureGS;
};
#endif
// vim:sw=4:sts=4:ts=8:sta:tw=78:noet

View file

@ -0,0 +1,426 @@
/***************************************************************************
* Copyright (C) 1997-2005 the KGhostView authors. See file GV_AUTHORS. *
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
* *
* Many portions of this file are based on kghostview's kpswidget code *
* *
* 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. *
***************************************************************************/
#include <kdebug.h>
#include <math.h>
#include <kmessagebox.h>
#include <kapplication.h>
#include <klocale.h>
#include "interpreter_cmd.h"
#include "conf/settings.h"
int handler( Display* d, XErrorEvent* e )
{
char msg[80], req[80], number[80];
XGetErrorText( d, e->error_code, msg, sizeof( msg ) );
sprintf( number, "%d", e->request_code );
XGetErrorDatabaseText( d, "XRequest", number, "<unknown>",
req, sizeof( req ) );
return 0;
}
int orientation2angle( CDSC_ORIENTATION_ENUM orientation )
{
Q_ASSERT( orientation != CDSC_ORIENT_UNKNOWN );
int angle = 0;
switch( orientation )
{
case CDSC_ORIENT_UNKNOWN: break; // Catched by Q_ASSERT
case CDSC_PORTRAIT: angle = 0; break;
case CDSC_LANDSCAPE: angle = 90; break;
case CDSC_UPSIDEDOWN: angle = 180; break;
case CDSC_SEASCAPE: angle = 270; break;
}
return angle;
}
QCString getPaletteString()
{
QCString str;
switch( Settings::renderMode() )
{
case (int) Settings::EnumRenderMode::BlackWhite:
if (Settings::bWThreshold() == 2)
str = "Monochrome";
else
str = "Grayscale";
break;
default:
str = "Color";
break;
}
return str;
}
GVInterpreterCMD::GVInterpreterCMD( QWidget* parent, const char* name, const QString & fileName ) :
QWidget ( parent, name ),
comm_window ( None ),
m_needUpdate ( false ),
m_stdinReady ( false ),
m_busy ( false ),
m_usePipe ( false ),
m_buffer ( 0 ),
m_process ( 0 ),
m_magnify ( 1 ),
m_work (),
m_orientation ( CDSC_PORTRAIT ),
m_name (fileName)
{
XSetErrorHandler( handler );
kdDebug(4500) << "Constructing interpreter!" << endl;
// Create the Atoms used to communicate with Ghostscript.
const char* const atomNames[] = { "GHOSTVIEW", "GHOSTVIEW_COLORS",
"NEXT", "PAGE", "DONE" };
XInternAtoms( x11Display(), const_cast<char**>( atomNames ),
5, false, m_atoms );
m_pixmap=0;
}
GVInterpreterCMD::~GVInterpreterCMD()
{
if (!m_pixmap)
delete m_pixmap;
}
void GVInterpreterCMD::stopInterpreter()
{
kdDebug(4500) << "GVInterpreterCMD::stopInterpreter()" << endl;
// if( !_interpreterBusy ) return;
if( running() )
m_process->kill( SIGHUP );
m_tmpFile=0;
m_process = 0;
m_work.unlock();
}
void GVInterpreterCMD::gs_output( KProcess*, char* buffer, int len )
{
kdDebug(4500) << "Output sent!" << endl;
emit output( buffer, len );
}
bool GVInterpreterCMD::startInterpreter()
{
setupWidget();
if (!m_pixmap)
m_pixmap = new QPixmap;
this->show();
m_process = new KProcess;
m_process -> setEnvironment( "GHOSTVIEW", QString( "%1 %2" ).arg( winId() ).arg( m_pixmap->handle() ) );
*m_process << m_path.local8Bit();
*m_process << m_args;
*m_process <<
// The following two lines are their to
// ensure that we are allowed to read m_fileName
"-dDELAYSAFER"
<< "-sInputFile=" + m_name
<< "-c '/PermitFileReading [ InputFile ] /PermitFileWriting [] /PermitFileControl []'"
<< "-";
/* }
else
*m_process << m_name << "-c" << "quit";*/
connect( m_process, SIGNAL( processExited( KProcess* ) ),
this, SLOT( slotProcessExited( KProcess* ) ) );
connect( m_process, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
this, SLOT( gs_output( KProcess*, char*, int ) ) );
connect( m_process, SIGNAL( receivedStderr( KProcess*, char*, int ) ),
this, SLOT( gs_output( KProcess*, char*, int ) ) );
connect( m_process, SIGNAL( wroteStdin( KProcess*) ),
this, SLOT( gs_input( KProcess* ) ) );
// really necessary?
KApplication::kApplication () -> flushX();
// Finally fire up the interpreter.
kdDebug(4500) << "KPSWidget: starting interpreter" << endl;
if( m_process->start( KProcess::NotifyOnExit,
/*m_usePipe ?*/ KProcess::All /*: KProcess::AllOutput*/ ) )
{
m_busy = true;
m_work.lock();
m_stdinReady = true;
m_needUpdate = false;
return true;
}
else
{
KMessageBox::error( this,
i18n( "Could not start Ghostscript. This is most likely "
"caused by an incorrectly specified interpreter." ) );
return false;
}
}
bool GVInterpreterCMD::busy()
{
return (running() && m_busy && m_work.locked() && !m_stdinReady) || (! running()) ;
}
void GVInterpreterCMD::setGhostscriptPath( const QString& path )
{
kdDebug() << "KPSWidget::setGhostscriptPath( " << path << " )" << endl;
if( m_path != path )
{
m_path = path;
stopInterpreter();
m_needUpdate = true;
}
}
void GVInterpreterCMD::setGhostscriptArguments( const QStringList& arguments )
{
if( m_args != arguments )
{
m_args= arguments;
stopInterpreter();
m_needUpdate = true;
}
}
void GVInterpreterCMD::setOrientation( CDSC_ORIENTATION_ENUM orientation )
{
if( m_orientation != orientation )
{
m_orientation = orientation;
stopInterpreter();
m_needUpdate = true;
}
}
void GVInterpreterCMD::setBoundingBox( const KDSCBBOX& boundingBox )
{
if( m_boundingBox != boundingBox )
{
m_boundingBox = boundingBox;
stopInterpreter();
m_needUpdate = true;
}
}
void GVInterpreterCMD::setMagnification( double magnification )
{
if( abs( static_cast <int>(magnification - m_magnify )) > 0.0001 )
{
m_magnify = magnification;
stopInterpreter();
m_needUpdate = true;
}
}
bool GVInterpreterCMD::sendPS( FILE* fp, const PagePosition *pos, PixmapRequest * req )
{
kdDebug(4500) << "KPSWidget::sendPS" << endl;
if( !running() )
return false;
if (!m_pixmap)
m_pixmap = new QPixmap;
m_tmpFile = fp;
m_req=req;
m_begin=pos->first;
m_len=static_cast <unsigned int> (pos->first - pos->second);
// Start processing the queue.
if( m_stdinReady )
{
gs_input( m_process );
}
return true;
}
void GVInterpreterCMD::gs_input( KProcess* process )
{
kdDebug(4500) << "Sending input ::gs_input" << endl;
if (process != m_process)
{
kdDebug(4500) << "BROKEN::gs_input(): process != _process" << endl;
return;
}
m_stdinReady = true;
if ( fseek( m_tmpFile, m_begin , SEEK_SET ) )
{
kdDebug(4500) << "KPSWidget::gs_input(): seek failed!" << endl;
stopInterpreter();
return;
}
if (m_len == 0)
{
m_busy = false;
m_work.unlock();
}
Q_ASSERT( m_len > 0 );
const unsigned buffer_size = 4096;
if ( !m_buffer )
m_buffer = static_cast<char*>( operator new( buffer_size ) );
const int bytesRead = fread( m_buffer, sizeof (char),
QMIN( buffer_size, m_len ),
m_tmpFile );
if( bytesRead > 0 )
{
m_begin += bytesRead;
m_len -= bytesRead;
if( process && process->writeStdin( m_buffer, bytesRead ) )
m_stdinReady = false;
else
{
stopInterpreter();
}
}
else
stopInterpreter();
}
bool GVInterpreterCMD::x11Event( XEvent* e )
{
if( e->type == ClientMessage )
{
comm_window = e->xclient.data.l[0];
if( e->xclient.message_type == m_atoms[PAGE] )
{
kdDebug() << "received PAGE" << endl;
m_busy = false;
if (m_work.locked())
m_work.unlock();
m_tmpFile=0;
emit newPageImage( m_req );
setErasePixmap( *m_pixmap );
return true;
}
else if( e->xclient.message_type == m_atoms[DONE] )
{
kdDebug() << "received DONE" << endl;
stopInterpreter();
return true;
}
}
return QWidget::x11Event( e );
}
void GVInterpreterCMD::setupWidget()
{
if( !m_needUpdate )
return;
if (!m_pixmap)
m_pixmap = new QPixmap;
Q_ASSERT( m_orientation != CDSC_ORIENT_UNKNOWN );
const float dpiX = m_magnify * x11AppDpiX();
const float dpiY = m_magnify * x11AppDpiY();
int newWidth = 0, newHeight = 0;
if( m_orientation == CDSC_PORTRAIT || m_orientation == CDSC_UPSIDEDOWN )
{
newWidth = (int) ceil( m_boundingBox.width() * dpiX / 72.0 );
newHeight = (int) ceil( m_boundingBox.height() * dpiY / 72.0 );
}
else
{
newWidth = (int) ceil( m_boundingBox.height() * dpiX / 72.0 );
newHeight = (int) ceil( m_boundingBox.width() * dpiY / 72.0 );
}
if( newWidth != width() || newHeight != height() )
{
setEraseColor( white );
setFixedSize( newWidth, newHeight );
//kapp->processEvents();
m_pixmap->resize( size() );
m_pixmap->fill( white );
// The line below is needed to work around certain "features" of styles such as liquid
// see bug:61711 for more info (LPC, 20 Aug '03)
setBackgroundOrigin( QWidget::WidgetOrigin );
setErasePixmap( *m_pixmap );
}
char data[512];
sprintf( data, "%ld %d %d %d %d %d %g %g",
m_pixmap->handle() ,
orientation2angle( m_orientation ),
m_boundingBox.llx(), m_boundingBox.lly(),
m_boundingBox.urx(), m_boundingBox.ury(),
dpiX, dpiY );
XChangeProperty( x11Display(), winId(),
m_atoms[GHOSTVIEW],
XA_STRING, 8, PropModeReplace,
(unsigned char*) data, strlen( data ) );
sprintf( data, "%s %d %d",
getPaletteString().data(),
(int)BlackPixel( x11Display(), DefaultScreen( x11Display() ) ),
(int)WhitePixel( x11Display(), DefaultScreen( x11Display() ) ) );
XChangeProperty( x11Display(), winId(),
m_atoms[GHOSTVIEW_COLORS],
XA_STRING, 8, PropModeReplace,
(unsigned char*) data, strlen( data ) );
// Make sure the properties are updated immediately.
XSync( x11Display(), false );
repaint();
m_needUpdate = false;
}
void GVInterpreterCMD::slotProcessExited( KProcess* process )
{
kdDebug() << "KPSWidget: process exited" << endl;
if ( process == m_process )
{
kdDebug( 4500 ) << "KPSWidget::slotProcessExited(): looks like it was not a clean exit." << endl;
if ( process->normalExit() ) {
emit ghostscriptError( QString( i18n( "Exited with error code %1." ).arg( process->exitStatus() ) ) );
} else {
emit ghostscriptError( QString( i18n( "Process killed or crashed." ) ) );
}
m_process = 0;
stopInterpreter();
}
}
#include "interpreter_cmd.moc"

View file

@ -0,0 +1,237 @@
/***************************************************************************
* Copyright (C) 1997-2005 the KGhostView authors. See file GV_AUTHORS. *
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
* *
* Many portions of this file are based on kghostview's kpswidget code *
* *
* 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. *
***************************************************************************/
#ifndef _KPDF_GVINTERPETERCMD_H_
#define _KPDF_GVINTERPETERCMD_H_
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <fixx11h.h>
#include <kprocess.h>
#include <qwidget.h>
#include <qmutex.h>
#include "internaldocument.h"
#include "core/generator.h"
#include "dscparse_adapter.h"
class QString;
class QStringList;
/**
* @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.
*/
class GVInterpreterCMD : public QWidget
{
Q_OBJECT
public:
GVInterpreterCMD( QWidget* parent, const char* name , const QString & fileName);
~GVInterpreterCMD();
QPixmap* takePixmap() { return m_pixmap; m_pixmap=0; };
bool startInterpreter();
void setGhostscriptPath( const QString& path );
void setGhostscriptArguments( const QStringList& arguments );
void setOrientation( CDSC_ORIENTATION_ENUM orientation );
void setBoundingBox( const KDSCBBOX& boundingBox );
void setMagnification( double magnification );
bool sendPS( FILE* fp, const PagePosition *pos, PixmapRequest * req );
bool x11Event( XEvent* e );
bool busy();
bool running() { return m_process && m_process->isRunning(); };
QMutex m_work;
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( PixmapRequest *req );
/**
* 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 QString& mgs );
private slots:
void slotProcessExited( KProcess* process );
void gs_output( KProcess*, char* buffer, int len );
void gs_input( KProcess* process );
private:
// functions
void stopInterpreter();
void setupWidget();
// x11 communication stuff
enum AtomName { GHOSTVIEW = 0, GHOSTVIEW_COLORS, NEXT, PAGE, DONE };
Atom m_atoms[5];
Window comm_window;
// state bools
bool m_useWindow;
bool m_needUpdate;
bool m_stdinReady;
bool m_busy;
bool m_usePipe;
char *m_buffer;
KDSCBBOX m_boundingBox;
// result
QPixmap* m_pixmap;
// settings stuff
QString m_path;
QStringList m_args;
// process stuff
KProcess *m_process;
// FILE INFORMATION:
// hold pointer to a file never delete it, it should
// change everytime new request is done
double m_magnify;
CDSC_ORIENTATION_ENUM m_orientation;
QString m_name;
FILE * m_tmpFile;
unsigned long m_begin;
unsigned int m_len;
PixmapRequest* m_req;
};
#endif