mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 18:32:53 +00:00
thumbnailers: reimplement gs thumbnailer
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
6bf65cde3d
commit
086e12a2a9
7 changed files with 59 additions and 5280 deletions
|
@ -1,17 +1,23 @@
|
||||||
########### next target ###############
|
########### next target ###############
|
||||||
|
|
||||||
set(gsthumbnail_PART_SRCS gscreator.cpp dscparse.cpp dscparse_adapter.cpp)
|
set(gsthumbnail_PART_SRCS gscreator.cpp)
|
||||||
|
|
||||||
|
|
||||||
kde4_add_plugin(gsthumbnail ${gsthumbnail_PART_SRCS})
|
kde4_add_plugin(gsthumbnail ${gsthumbnail_PART_SRCS})
|
||||||
|
|
||||||
|
target_link_libraries(gsthumbnail
|
||||||
|
${KDE4_KDECORE_LIBS}
|
||||||
|
${KDE4_KIO_LIBS}
|
||||||
|
${QT_QTGUI_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(gsthumbnail ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${QT_QTGUI_LIBRARY} )
|
install(
|
||||||
|
TARGETS gsthumbnail
|
||||||
install(TARGETS gsthumbnail DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} )
|
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
########### install files ###############
|
########### install files ###############
|
||||||
|
|
||||||
install( FILES gsthumbnail.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR} )
|
install(
|
||||||
|
FILES gsthumbnail.desktop
|
||||||
|
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,477 +0,0 @@
|
||||||
/* 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 License 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 License. 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 */
|
|
||||||
/* 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
|
|
|
@ -1,420 +0,0 @@
|
||||||
/**
|
|
||||||
* 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 Street, 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 QByteArray& 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray 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] ),
|
|
||||||
QByteArray( 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
|
|
|
@ -1,336 +0,0 @@
|
||||||
/**
|
|
||||||
* 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 Street, 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"
|
|
||||||
|
|
||||||
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 QByteArray& line,
|
|
||||||
unsigned int lineNumber );
|
|
||||||
|
|
||||||
Type type() const;
|
|
||||||
Severity severity() const;
|
|
||||||
QByteArray line() const;
|
|
||||||
unsigned int lineNumber() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type _type;
|
|
||||||
Severity _severity;
|
|
||||||
QByteArray _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;
|
|
||||||
|
|
||||||
std::auto_ptr<KDSCBBOX> bbox() const;
|
|
||||||
std::auto_ptr<KDSCBBOX> page_bbox() const;
|
|
||||||
|
|
||||||
// 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
|
|
|
@ -1,12 +1,9 @@
|
||||||
/* This file is part of the KDE libraries
|
/* This file is part of the KDE project
|
||||||
Copyright (C) 2001 Malte Starostik <malte@kde.org>
|
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||||
|
|
||||||
Handling of EPS previews Copyright (C) 2003 Philipp Hullmann <phull@gmx.de>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License version 2, as published by the Free Software Foundation.
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
@ -17,613 +14,61 @@
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
Boston, MA 02110-1301, USA.
|
Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This function gets a path of a DVI, EPS, PS or PDF file and
|
|
||||||
produces a PNG-Thumbnail which is stored as a QImage
|
|
||||||
|
|
||||||
The program works as follows
|
|
||||||
|
|
||||||
1. Test if file is a DVI file
|
|
||||||
|
|
||||||
2. Create a child process (1), in which the
|
|
||||||
file is to be changed into a PNG
|
|
||||||
|
|
||||||
3. Child-process (1) :
|
|
||||||
|
|
||||||
4. If file is DVI continue with 6
|
|
||||||
|
|
||||||
5. If file is no DVI continue with 9
|
|
||||||
|
|
||||||
6. Create another child process (2), in which the DVI is
|
|
||||||
turned into PS using dvips
|
|
||||||
|
|
||||||
7. Parent process (2) :
|
|
||||||
Turn the recently created PS file into a PNG file using gs
|
|
||||||
|
|
||||||
8. continue with 10
|
|
||||||
|
|
||||||
9. Turn the PS,PDF or EPS file into a PNG file using gs
|
|
||||||
|
|
||||||
10. Parent process (1)
|
|
||||||
store data in a QImage
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <kdemacros.h>
|
|
||||||
|
|
||||||
#include <qcolor.h>
|
|
||||||
#include <qfile.h>
|
|
||||||
#include <qimage.h>
|
|
||||||
#include <qregexp.h>
|
|
||||||
#include <QVector>
|
|
||||||
|
|
||||||
|
|
||||||
#include "gscreator.h"
|
#include "gscreator.h"
|
||||||
#include "dscparse_adapter.h"
|
|
||||||
#include "dscparse.h"
|
#include <QImage>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <kstandarddirs.h>
|
||||||
|
#include <ktemporaryfile.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <kdemacros.h>
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
KDE_EXPORT ThumbCreator *new_creator()
|
KDE_EXPORT ThumbCreator *new_creator()
|
||||||
{
|
{
|
||||||
return new GSCreator;
|
return new GSCreator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This PS snippet will be prepended to the actual file so that only
|
bool GSCreator::create(const QString &path, int, int, QImage &img)
|
||||||
// the first page is output.
|
|
||||||
static const char *psprolog =
|
|
||||||
"%!PS-Adobe-3.0\n"
|
|
||||||
"/.showpage.orig /showpage load def\n"
|
|
||||||
"/.showpage.firstonly {\n"
|
|
||||||
" .showpage.orig\n"
|
|
||||||
" quit\n"
|
|
||||||
"} def\n"
|
|
||||||
"/showpage { .showpage.firstonly } def\n";
|
|
||||||
|
|
||||||
// This is the code recommended by Adobe tech note 5002 for including
|
|
||||||
// EPS files.
|
|
||||||
static const char *epsprolog =
|
|
||||||
"%!PS-Adobe-3.0\n"
|
|
||||||
"userdict begin /pagelevel save def /showpage { } def\n"
|
|
||||||
"0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit\n"
|
|
||||||
"[ ] 0 setdash newpath false setoverprint false setstrokeadjust\n";
|
|
||||||
|
|
||||||
static const char * gsargs_ps[] = {
|
|
||||||
"gs",
|
|
||||||
"-sDEVICE=png16m",
|
|
||||||
"-sOutputFile=-",
|
|
||||||
"-dSAFER",
|
|
||||||
"-dPARANOIDSAFER",
|
|
||||||
"-dNOPAUSE",
|
|
||||||
"-dFirstPage=1",
|
|
||||||
"-dLastPage=1",
|
|
||||||
"-q",
|
|
||||||
"-",
|
|
||||||
0, // file name
|
|
||||||
"-c",
|
|
||||||
"showpage",
|
|
||||||
"-c",
|
|
||||||
"quit",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char * gsargs_eps[] = {
|
|
||||||
"gs",
|
|
||||||
"-sDEVICE=png16m",
|
|
||||||
"-sOutputFile=-",
|
|
||||||
"-dSAFER",
|
|
||||||
"-dPARANOIDSAFER",
|
|
||||||
"-dNOPAUSE",
|
|
||||||
0, // page size
|
|
||||||
0, // resolution
|
|
||||||
"-q",
|
|
||||||
"-",
|
|
||||||
0, // file name
|
|
||||||
"-c",
|
|
||||||
"pagelevel",
|
|
||||||
"-c",
|
|
||||||
"restore",
|
|
||||||
"-c",
|
|
||||||
"end",
|
|
||||||
"-c",
|
|
||||||
"showpage",
|
|
||||||
"-c",
|
|
||||||
"quit",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *dvipsargs[] = {
|
|
||||||
"dvips",
|
|
||||||
"-n",
|
|
||||||
"1",
|
|
||||||
"-q",
|
|
||||||
"-o",
|
|
||||||
"-",
|
|
||||||
0, // file name
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool correctDVI(const QString& filename);
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool got_sig_term = false;
|
|
||||||
void handle_sigterm( int ) {
|
|
||||||
got_sig_term = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool GSCreator::create(const QString &path, int width, int height, QImage &img)
|
|
||||||
{
|
{
|
||||||
// The code in the loop (when testing whether got_sig_term got set)
|
const QString gsexe = KStandardDirs::findExe("gs");
|
||||||
// should read some variation of:
|
if (gsexe.isEmpty()) {
|
||||||
// parentJob()->wasKilled()
|
kWarning() << "Ghostscript is not available";
|
||||||
//
|
return false;
|
||||||
// Unfortunatelly, that's currently impossible without breaking BIC.
|
|
||||||
// So we need to catch the signal ourselves.
|
|
||||||
// Otherwise, on certain funny PS files (for example
|
|
||||||
// http://www.tjhsst.edu/~Eedanaher/pslife/life.ps )
|
|
||||||
// gs would run forever after we were dead.
|
|
||||||
// #### Reconsider for KDE 4 ###
|
|
||||||
// (24/12/03 - luis_pedro)
|
|
||||||
//
|
|
||||||
typedef void ( *sighandler_t )( int );
|
|
||||||
// according to linux's "man signal" the above typedef is a gnu extension
|
|
||||||
sighandler_t oldhandler = signal( SIGTERM, handle_sigterm );
|
|
||||||
|
|
||||||
int input[2];
|
|
||||||
int output[2];
|
|
||||||
int dvipipe[2];
|
|
||||||
|
|
||||||
QByteArray data(1024, '\0');
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
// Test if file is DVI
|
|
||||||
bool no_dvi =!correctDVI(path);
|
|
||||||
|
|
||||||
if (pipe(input) == -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (pipe(output) == -1) {
|
|
||||||
close(input[0]);
|
|
||||||
close(input[1]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
KDSC dsc;
|
|
||||||
endComments = false;
|
|
||||||
dsc.setCommentHandler(this);
|
|
||||||
|
|
||||||
if (no_dvi)
|
|
||||||
{
|
|
||||||
FILE* fp = fopen(QFile::encodeName(path), "r");
|
|
||||||
if (fp == 0) return false;
|
|
||||||
|
|
||||||
char buf[4096];
|
|
||||||
int count;
|
|
||||||
while ((count = fread(buf, sizeof(char), 4096, fp)) != 0
|
|
||||||
&& !endComments) {
|
|
||||||
dsc.scanData(buf, count);
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
if (dsc.pjl() || dsc.ctrld()) {
|
|
||||||
// this file is a mess.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool is_encapsulated = no_dvi &&
|
|
||||||
(path.indexOf(QRegExp("\\.epsi?$", Qt::CaseInsensitive)) > 0) &&
|
|
||||||
(dsc.bbox()->width() > 0) && (dsc.bbox()->height() > 0) &&
|
|
||||||
(dsc.page_count() <= 1);
|
|
||||||
|
|
||||||
char translation[64] = "";
|
|
||||||
char pagesize[32] = "";
|
|
||||||
char resopt[32] = "";
|
|
||||||
std::auto_ptr<KDSCBBOX> bbox = dsc.bbox();
|
|
||||||
if (is_encapsulated) {
|
|
||||||
// GhostScript's rendering at the extremely low resolutions
|
|
||||||
// required for thumbnails leaves something to be desired. To
|
|
||||||
// get nicer images, we render to four times the required
|
|
||||||
// resolution and let QImage scale the result.
|
|
||||||
const int hres = (width * 72) / bbox->width();
|
|
||||||
const int vres = (height * 72) / bbox->height();
|
|
||||||
const int resolution = (hres > vres ? vres : hres) * 4;
|
|
||||||
const int gswidth = ((bbox->urx() - bbox->llx()) * resolution) / 72;
|
|
||||||
const int gsheight = ((bbox->ury() - bbox->lly()) * resolution) / 72;
|
|
||||||
|
|
||||||
snprintf(pagesize, 31, "-g%ix%i", gswidth, gsheight);
|
|
||||||
snprintf(resopt, 31, "-r%i", resolution);
|
|
||||||
snprintf(translation, 63,
|
|
||||||
" 0 %i sub 0 %i sub translate\n", bbox->llx(),
|
|
||||||
bbox->lly());
|
|
||||||
}
|
|
||||||
|
|
||||||
const CDSC_PREVIEW_TYPE previewType =
|
|
||||||
static_cast<CDSC_PREVIEW_TYPE>(dsc.preview());
|
|
||||||
|
|
||||||
switch (previewType) {
|
|
||||||
case CDSC_TIFF:
|
|
||||||
case CDSC_WMF:
|
|
||||||
case CDSC_PICT:
|
|
||||||
// FIXME: these should take precedence, since they can hold
|
|
||||||
// color previews, which EPSI can't (or can it?).
|
|
||||||
break;
|
|
||||||
case CDSC_EPSI:
|
|
||||||
{
|
|
||||||
const int xscale = bbox->width() / width;
|
|
||||||
const int yscale = bbox->height() / height;
|
|
||||||
const int scale = xscale < yscale ? xscale : yscale;
|
|
||||||
if (getEPSIPreview(path,
|
|
||||||
dsc.beginpreview(),
|
|
||||||
dsc.endpreview(),
|
|
||||||
img,
|
|
||||||
bbox->width() / scale,
|
|
||||||
bbox->height() / scale))
|
|
||||||
return true;
|
|
||||||
// If the preview extraction routine fails, gs is used to
|
|
||||||
// create a thumbnail.
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CDSC_NOPREVIEW:
|
|
||||||
default:
|
|
||||||
// need to run ghostscript in these cases
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
// Child process (1)
|
|
||||||
|
|
||||||
// close(STDERR_FILENO);
|
|
||||||
|
|
||||||
// find first zero entry in gsargs and put the filename
|
|
||||||
// or - (stdin) there, if DVI
|
|
||||||
const char **gsargs = gsargs_ps;
|
|
||||||
const char **arg = gsargs;
|
|
||||||
|
|
||||||
if (no_dvi && is_encapsulated) {
|
|
||||||
gsargs = gsargs_eps;
|
|
||||||
arg = gsargs;
|
|
||||||
|
|
||||||
// find first zero entry and put page size there
|
|
||||||
while (*arg) ++arg;
|
|
||||||
*arg = pagesize;
|
|
||||||
|
|
||||||
// find second zero entry and put resolution there
|
|
||||||
while (*arg) ++arg;
|
|
||||||
*arg = resopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// find next zero entry and put the filename there
|
const QStringList gsargs = QStringList()
|
||||||
QByteArray fname = QFile::encodeName( path );
|
<< QLatin1String("-q")
|
||||||
while (*arg)
|
<< QLatin1String("-dNOPAUSE")
|
||||||
++arg;
|
<< QLatin1String("-dSAFER")
|
||||||
if( no_dvi )
|
<< QLatin1String("-dBATCH")
|
||||||
*arg = fname.data();
|
<< QLatin1String("-dFirstPage=1")
|
||||||
else
|
<< QLatin1String("-dLastPage=1")
|
||||||
*arg = "-";
|
<< QLatin1String("-sDEVICE=png16m")
|
||||||
|
<< QLatin1String("-sOutputFile=-")
|
||||||
// find first zero entry in dvipsargs and put the filename there
|
<< path;
|
||||||
arg = dvipsargs;
|
QProcess gsprocess;
|
||||||
while (*arg)
|
gsprocess.start(gsexe, gsargs);
|
||||||
++arg;
|
if (gsprocess.waitForFinished() == false || gsprocess.exitCode() != 0) {
|
||||||
*arg = fname.data();
|
kWarning() << gsprocess.readAllStandardError();
|
||||||
|
return false;
|
||||||
if( !no_dvi ){
|
|
||||||
pipe(dvipipe);
|
|
||||||
pid_t pid_two = fork();
|
|
||||||
if( pid_two == 0 ){
|
|
||||||
// Child process (2), reopen stdout on the pipe "dvipipe" and exec dvips
|
|
||||||
|
|
||||||
close(input[0]);
|
|
||||||
close(input[1]);
|
|
||||||
close(output[0]);
|
|
||||||
close(output[1]);
|
|
||||||
close(dvipipe[0]);
|
|
||||||
|
|
||||||
dup2( dvipipe[1], STDOUT_FILENO);
|
|
||||||
|
|
||||||
execvp(dvipsargs[0], const_cast<char *const *>(dvipsargs));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else if(pid_two != -1){
|
|
||||||
close(input[1]);
|
|
||||||
close(output[0]);
|
|
||||||
close(dvipipe[1]);
|
|
||||||
|
|
||||||
dup2( dvipipe[0], STDIN_FILENO);
|
|
||||||
dup2( output[1], STDOUT_FILENO);
|
|
||||||
|
|
||||||
execvp(gsargs[0], const_cast<char *const *>(gsargs));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// fork() (2) failed, close these
|
|
||||||
close(dvipipe[0]);
|
|
||||||
close(dvipipe[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( no_dvi ){
|
const QByteArray gsimage = gsprocess.readAllStandardOutput();
|
||||||
// Reopen stdin/stdout on the pipes and exec gs
|
|
||||||
close(input[1]);
|
|
||||||
close(output[0]);
|
|
||||||
|
|
||||||
dup2(input[0], STDIN_FILENO);
|
if (img.loadFromData(gsimage, "PNG") == false) {
|
||||||
dup2(output[1], STDOUT_FILENO);
|
kWarning() << "Could not load ghostscript image";
|
||||||
|
return false;
|
||||||
execvp(gsargs[0], const_cast<char *const *>(gsargs));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pid != -1) {
|
|
||||||
// Parent process, write first-page-only-hack (the hack is not
|
|
||||||
// used if DVI) and read the png output
|
|
||||||
close(input[0]);
|
|
||||||
close(output[1]);
|
|
||||||
const char *prolog;
|
|
||||||
if (is_encapsulated)
|
|
||||||
prolog = epsprolog;
|
|
||||||
else
|
|
||||||
prolog = psprolog;
|
|
||||||
int count = write(input[1], prolog, strlen(prolog));
|
|
||||||
if (is_encapsulated)
|
|
||||||
write(input[1], translation, strlen(translation));
|
|
||||||
|
|
||||||
close(input[1]);
|
|
||||||
if (count == static_cast<int>(strlen(prolog))) {
|
|
||||||
int offset = 0;
|
|
||||||
while (!ok) {
|
|
||||||
fd_set fds;
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(output[0], &fds);
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 20;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
got_sig_term = false;
|
|
||||||
if (select(output[0] + 1, &fds, 0, 0, &tv) <= 0) {
|
|
||||||
if ( ( errno == EINTR || errno == EAGAIN ) && !got_sig_term ) continue;
|
|
||||||
break; // error, timeout or master wants us to quit (SIGTERM)
|
|
||||||
}
|
|
||||||
if (FD_ISSET(output[0], &fds)) {
|
|
||||||
count = read(output[0], data.data() + offset, 1024);
|
|
||||||
if (count == -1)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
if (count) // prepare for next block
|
|
||||||
{
|
|
||||||
offset += count;
|
|
||||||
data.resize(offset + 1024);
|
|
||||||
}
|
|
||||||
else // got all data
|
|
||||||
{
|
|
||||||
data.resize(offset);
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ok) // error or timeout, gs probably didn't exit yet
|
|
||||||
{
|
|
||||||
kill(pid, SIGTERM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = 0;
|
return true;
|
||||||
int ret;
|
|
||||||
do {
|
|
||||||
ret = waitpid(pid, &status, 0);
|
|
||||||
} while (ret == -1 && errno == EINTR);
|
|
||||||
if (ret != pid || (status != 0 && status != 256) )
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// fork() (1) failed, close these
|
|
||||||
close(input[0]);
|
|
||||||
close(input[1]);
|
|
||||||
close(output[1]);
|
|
||||||
}
|
|
||||||
close(output[0]);
|
|
||||||
|
|
||||||
int l = img.loadFromData( data );
|
|
||||||
|
|
||||||
if ( got_sig_term &&
|
|
||||||
oldhandler != SIG_ERR &&
|
|
||||||
oldhandler != SIG_DFL &&
|
|
||||||
oldhandler != SIG_IGN ) {
|
|
||||||
oldhandler( SIGTERM ); // propagate the signal. Other things might rely on it
|
|
||||||
}
|
|
||||||
if ( oldhandler != SIG_ERR ) signal( SIGTERM, oldhandler );
|
|
||||||
|
|
||||||
return ok && l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThumbCreator::Flags GSCreator::flags() const
|
ThumbCreator::Flags GSCreator::flags() const
|
||||||
{
|
{
|
||||||
return static_cast<Flags>(DrawFrame);
|
return ThumbCreator::None;
|
||||||
}
|
|
||||||
|
|
||||||
void GSCreator::comment(Name name)
|
|
||||||
{
|
|
||||||
switch (name) {
|
|
||||||
case EndPreview:
|
|
||||||
case BeginProlog:
|
|
||||||
case Page:
|
|
||||||
endComments = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick function to check if the filename corresponds to a valid DVI
|
|
||||||
// file. Returns true if <filename> is a DVI file, false otherwise.
|
|
||||||
|
|
||||||
static bool correctDVI(const QString& filename)
|
|
||||||
{
|
|
||||||
QFile f(filename);
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char test[4];
|
|
||||||
if ( f.read( (char *)test,2)<2 || test[0] != 247 || test[1] != 2 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int n = f.size();
|
|
||||||
if ( n < 134 ) // Too short for a dvi file
|
|
||||||
return false;
|
|
||||||
f.seek( n-4 );
|
|
||||||
|
|
||||||
unsigned char trailer[4] = { 0xdf,0xdf,0xdf,0xdf };
|
|
||||||
|
|
||||||
if ( f.read( (char *)test, 4 )<4 || strncmp( (char *)test, (char*) trailer, 4 ) )
|
|
||||||
return false;
|
|
||||||
// We suppose now that the dvi file is complete and OK
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSCreator::getEPSIPreview(const QString &path, long start, long
|
|
||||||
end, QImage &outimg, int imgwidth, int imgheight)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
fp = fopen(QFile::encodeName(path), "r");
|
|
||||||
if (fp == 0) return false;
|
|
||||||
|
|
||||||
const long previewsize = end - start + 1;
|
|
||||||
|
|
||||||
char *buf = (char *) malloc(previewsize);
|
|
||||||
fseek(fp, start, SEEK_SET);
|
|
||||||
int count = fread(buf, sizeof(char), previewsize - 1, fp);
|
|
||||||
fclose(fp);
|
|
||||||
buf[previewsize - 1] = 0;
|
|
||||||
if (count != previewsize - 1)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString previewstr = QString::fromLatin1(buf);
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
while ((offset < previewsize) && !(previewstr[offset].isDigit())) offset++;
|
|
||||||
int digits = 0;
|
|
||||||
while ((offset + digits < previewsize) && previewstr[offset + digits].isDigit()) digits++;
|
|
||||||
int width = previewstr.mid(offset, digits).toInt();
|
|
||||||
offset += digits + 1;
|
|
||||||
while ((offset < previewsize) && !(previewstr[offset].isDigit())) offset++;
|
|
||||||
digits = 0;
|
|
||||||
while ((offset + digits < previewsize) && previewstr[offset + digits].isDigit()) digits++;
|
|
||||||
int height = previewstr.mid(offset, digits).toInt();
|
|
||||||
offset += digits + 1;
|
|
||||||
while ((offset < previewsize) && !(previewstr[offset].isDigit())) offset++;
|
|
||||||
digits = 0;
|
|
||||||
while ((offset + digits < previewsize) && previewstr[offset + digits].isDigit()) digits++;
|
|
||||||
int depth = previewstr.mid(offset, digits).toInt();
|
|
||||||
|
|
||||||
// skip over the rest of the BeginPreview comment
|
|
||||||
while ((offset < previewsize) &&
|
|
||||||
previewstr[offset] != '\n' &&
|
|
||||||
previewstr[offset] != '\r') offset++;
|
|
||||||
while ((offset < previewsize) && previewstr[offset] != '%') offset++;
|
|
||||||
|
|
||||||
#if QT_VERSION < 0x041200
|
|
||||||
unsigned int imagedepth;
|
|
||||||
switch (depth) {
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 8:
|
|
||||||
imagedepth = 8;
|
|
||||||
break;
|
|
||||||
case 12: // valid, but not (yet) supported
|
|
||||||
default: // illegal value
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int colors = (1U << depth);
|
|
||||||
QImage img(width, height, QImage::Format_Indexed8);
|
|
||||||
img.setColorCount(colors);
|
|
||||||
|
|
||||||
if (imagedepth <= 8) {
|
|
||||||
for (unsigned int gray = 0; gray < colors; gray++) {
|
|
||||||
unsigned int grayvalue = (255U * (colors - 1 - gray)) / (colors - 1);
|
|
||||||
img.setColor(gray, qRgb(grayvalue, grayvalue, grayvalue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
QImage img(width, height, QImage::Format_RGB32);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const unsigned int bits_per_scan_line = width * depth;
|
|
||||||
unsigned int bytes_per_scan_line = bits_per_scan_line / 8;
|
|
||||||
if (bits_per_scan_line % 8) bytes_per_scan_line++;
|
|
||||||
const unsigned int bindatabytes = height * bytes_per_scan_line;
|
|
||||||
QVector<unsigned char> bindata(bindatabytes);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < bindatabytes; i++) {
|
|
||||||
if (offset >= previewsize)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (!isxdigit(previewstr[offset].toLatin1()) && offset < previewsize)
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
bindata[i] = static_cast<unsigned char>(previewstr.mid(offset, 2).toUInt(&ok, 16));
|
|
||||||
if (!ok)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
offset += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int scanline = 0; scanline < height; scanline++) {
|
|
||||||
unsigned char *scanlineptr = img.scanLine(scanline);
|
|
||||||
|
|
||||||
for (int pixelindex = 0; pixelindex < width; pixelindex++) {
|
|
||||||
unsigned char pixelvalue = 0;
|
|
||||||
const unsigned int bitoffset =
|
|
||||||
scanline * bytes_per_scan_line * 8U + pixelindex * depth;
|
|
||||||
for (int depthindex = 0; depthindex < depth;
|
|
||||||
depthindex++) {
|
|
||||||
const unsigned int byteindex = (bitoffset + depthindex) / 8U;
|
|
||||||
const unsigned int bitindex =
|
|
||||||
7 - ((bitoffset + depthindex) % 8U);
|
|
||||||
const unsigned char bitvalue =
|
|
||||||
(bindata[byteindex] & static_cast<unsigned char>(1U << bitindex)) >> bitindex;
|
|
||||||
pixelvalue |= (bitvalue << depthindex);
|
|
||||||
}
|
|
||||||
scanlineptr[pixelindex] = pixelvalue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if QT_VERSION < 0x041200
|
|
||||||
outimg = img.convertToFormat(QImage::Format_RGB32).scaled(imgwidth, imgheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
#else
|
|
||||||
outimg = img.scaled(imgwidth, imgheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/* This file is part of the KDE libraries
|
/* This file is part of the KDE project
|
||||||
Copyright (C) 2000 Malte Starostik <malte@kde.org>
|
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License version 2, as published by the Free Software Foundation.
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
@ -15,28 +14,19 @@
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
Boston, MA 02110-1301, USA.
|
Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GSCREATOR_H_
|
#ifndef _GSCREATOR_H_
|
||||||
#define _GSCREATOR_H_
|
#define _GSCREATOR_H_
|
||||||
|
|
||||||
#include <kio/thumbcreator.h>
|
#include <kio/thumbcreator.h>
|
||||||
#include "dscparse_adapter.h"
|
|
||||||
|
|
||||||
class GSCreator : public ThumbCreator, public KDSCCommentHandler
|
class GSCreator : public ThumbCreator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GSCreator() {}
|
GSCreator() {}
|
||||||
virtual bool create(const QString &path, int, int, QImage &img);
|
virtual bool create(const QString &path, int, int, QImage &img);
|
||||||
virtual Flags flags() const;
|
virtual ThumbCreator::Flags flags() const;
|
||||||
void comment(Name name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool getEPSIPreview(const QString &path,
|
|
||||||
long start, long end,
|
|
||||||
QImage &outimg,
|
|
||||||
int imgwidth, int imgheight);
|
|
||||||
bool endComments;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue