diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/display.cpp psi-0.10/libpsi/libTeXFormula/display.cpp --- psi-0.10-orig/libpsi/libTeXFormula/display.cpp 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/display.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,66 @@ +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// +#include "display.h" +#include "stdio.h" +#include "stdlib.h" +#include "memory.h" + +int g_width, g_height,g_raster; +unsigned char *g_pimage; +unsigned char *g_result_pixmap; +int g_result_width, g_result_height; + + +/* Device is about to be closed. */ +/* Device will not be closed until this function returns. */ +int display_open(void *, void *) +{ + return 1; +} + +int display_preclose(void *, void *) +{ + return 0; +} + +int display_close(void *, void *) +{ + return 0; +} + +int display_presize(void *, void *, int , int , int , unsigned int ) +{ + return 0; +} +int display_size(void *, void *, int width, int height, int raster, unsigned int , unsigned char *pimage) +{ + g_height = height; + g_width = width; + g_raster = raster; + g_pimage = pimage; + return 0; +} +int display_sync(void *, void *) +{ + return 0; +} +int display_page(void *, void *, int , int ) +{ + g_result_pixmap = (unsigned char*) malloc(g_raster*g_height); + memcpy(g_result_pixmap,g_pimage, g_raster*g_height); + + // clear border + for (int y = 0; y < g_height;y++) + for (int x = g_width; x < g_raster; x++) + g_result_pixmap[y * g_raster + x] = 0xFF; + + g_result_width = g_raster; + g_result_height = g_height; + return 0; +} +int display_update(void *, void *, int , int, int , int ) +{ + return 0; +} diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/display.h psi-0.10/libpsi/libTeXFormula/display.h --- psi-0.10-orig/libpsi/libTeXFormula/display.h 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/display.h 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,18 @@ +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// +#ifndef DISPLAY_H +#define DISPLAY_H + +int display_open(void *handle, void *device); +int display_preclose(void *handle, void *device); +int display_close(void *handle, void *device); +int display_presize(void *handle, void *device, int width, int height, int raster, unsigned int format); +int display_size(void *handle, void *device, int width, int height, int raster, unsigned int format, unsigned char *pimage); +int display_sync(void *handle, void *device); +int display_page(void *handle, void *device, int copies, int flush); +int display_update(void *handle, void *device, int x, int y, int w, int h); + +#endif //DISPLAY_H + diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/gdevdsp.h psi-0.10/libpsi/libTeXFormula/gdevdsp.h --- psi-0.10-orig/libpsi/libTeXFormula/gdevdsp.h 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/gdevdsp.h 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,202 @@ +/* Copyright (C) 2001, Ghostgum Software Pty Ltd. All rights reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + For more information about licensing, please refer to + http://www.ghostscript.com/licensing/. For information on + commercial licensing, go to http://www.artifex.com/licensing/ or + contact Artifex Software, Inc., 101 Lucas Valley Road #110, + San Rafael, CA 94903, U.S.A., +1(415)492-9861. + */ + +/* $Id: gdevdsp.h,v 1.7 2002/11/20 17:46:26 giles Exp $ */ +/* gdevdsp.h - callback structure for DLL based display device */ + +#ifndef gdevdsp_INCLUDED +# define gdevdsp_INCLUDED + +/* + * The callback structure must be provided by calling the + * Ghostscript APIs in the following order: + * gsapi_new_instance(&minst); + * gsapi_set_display_callback(minst, callback); + * gsapi_init_with_args(minst, argc, argv); + * + * Supported parameters and default values are: + * -dDisplayHandle=0 long + * Caller supplied handle. + * Included as first parameter of all callback functions. + * + * -dDisplayFormat=0 long + * Color format specified using bitfields below. + * Included as argument of display_size() and display_presize() + * These can only be changed when the device is closed. + * + * The second parameter of all callback functions "void *device" + * is the address of the Ghostscript display device instance. + * The arguments "void *handle" and "void *device" together + * uniquely identify an instance of the display device. + * + * A typical sequence of callbacks would be + * open, presize, memalloc, size, sync, page + * presize, memfree, memalloc, size, sync, page + * preclose, memfree, close + * The caller should not access the image buffer: + * - before the first sync + * - between presize and size + * - after preclose + * If opening the device fails, you might see the following: + * open, presize, memalloc, memfree, close + * + */ + +#define DISPLAY_VERSION_MAJOR 1 +#define DISPLAY_VERSION_MINOR 0 + +/* The display format is set by a combination of the following bitfields */ + +/* Define the color space alternatives */ +typedef enum { + DISPLAY_COLORS_NATIVE = (1<<0), + DISPLAY_COLORS_GRAY = (1<<1), + DISPLAY_COLORS_RGB = (1<<2), + DISPLAY_COLORS_CMYK = (1<<3) +} DISPLAY_FORMAT_COLOR; +#define DISPLAY_COLORS_MASK 0x000fL + +/* Define whether alpha information, or an extra unused bytes is included */ +/* DISPLAY_ALPHA_FIRST and DISPLAY_ALPHA_LAST are not implemented */ +typedef enum { + DISPLAY_ALPHA_NONE = (0<<4), + DISPLAY_ALPHA_FIRST = (1<<4), + DISPLAY_ALPHA_LAST = (1<<5), + DISPLAY_UNUSED_FIRST = (1<<6), /* e.g. Mac xRGB */ + DISPLAY_UNUSED_LAST = (1<<7) /* e.g. Windows BGRx */ +} DISPLAY_FORMAT_ALPHA; +#define DISPLAY_ALPHA_MASK 0x00f0L + +/* Define the depth per component for DISPLAY_COLORS_GRAY, + * DISPLAY_COLORS_RGB and DISPLAY_COLORS_CMYK, + * or the depth per pixel for DISPLAY_COLORS_NATIVE + * DISPLAY_DEPTH_2 and DISPLAY_DEPTH_12 have not been tested. + */ +typedef enum { + DISPLAY_DEPTH_1 = (1<<8), + DISPLAY_DEPTH_2 = (1<<9), + DISPLAY_DEPTH_4 = (1<<10), + DISPLAY_DEPTH_8 = (1<<11), + DISPLAY_DEPTH_12 = (1<<12), + DISPLAY_DEPTH_16 = (1<<13) + /* unused (1<<14) */ + /* unused (1<<15) */ +} DISPLAY_FORMAT_DEPTH; +#define DISPLAY_DEPTH_MASK 0xff00L + + +/* Define whether Red/Cyan should come first, + * or whether Blue/Black should come first + */ +typedef enum { + DISPLAY_BIGENDIAN = (0<<16), /* Red/Cyan first */ + DISPLAY_LITTLEENDIAN = (1<<16) /* Blue/Black first */ +} DISPLAY_FORMAT_ENDIAN; +#define DISPLAY_ENDIAN_MASK 0x00010000L + +/* Define whether the raster starts at the top or bottom of the bitmap */ +typedef enum { + DISPLAY_TOPFIRST = (0<<17), /* Unix, Mac */ + DISPLAY_BOTTOMFIRST = (1<<17) /* Windows */ +} DISPLAY_FORMAT_FIRSTROW; +#define DISPLAY_FIRSTROW_MASK 0x00020000L + + +/* Define whether packing RGB in 16-bits should use 555 + * or 565 (extra bit for green) + */ +typedef enum { + DISPLAY_NATIVE_555 = (0<<18), + DISPLAY_NATIVE_565 = (1<<18) +} DISPLAY_FORMAT_555; +#define DISPLAY_555_MASK 0x00040000L + +#ifndef display_callback_DEFINED +#define display_callback_DEFINED +typedef struct display_callback_s display_callback; +#endif + +struct display_callback_s { + /* Size of this structure */ + /* Used for checking if we have been handed a valid structure */ + int size; + + /* Major version of this structure */ + /* The major version number will change if this structure changes. */ + int version_major; + + /* Minor version of this structure */ + /* The minor version number will change if new features are added + * without changes to this structure. For example, a new color + * format. + */ + int version_minor; + + /* New device has been opened */ + /* This is the first event from this device. */ + int (*display_open)(void *handle, void *device); + + /* Device is about to be closed. */ + /* Device will not be closed until this function returns. */ + int (*display_preclose)(void *handle, void *device); + + /* Device has been closed. */ + /* This is the last event from this device. */ + int (*display_close)(void *handle, void *device); + + /* Device is about to be resized. */ + /* Resize will only occur if this function returns 0. */ + /* raster is byte count of a row. */ + int (*display_presize)(void *handle, void *device, + int width, int height, int raster, unsigned int format); + + /* Device has been resized. */ + /* New pointer to raster returned in pimage */ + int (*display_size)(void *handle, void *device, int width, int height, + int raster, unsigned int format, unsigned char *pimage); + + /* flushpage */ + int (*display_sync)(void *handle, void *device); + + /* showpage */ + /* If you want to pause on showpage, then don't return immediately */ + int (*display_page)(void *handle, void *device, int copies, int flush); + + /* Notify the caller whenever a portion of the raster is updated. */ + /* This can be used for cooperative multitasking or for + * progressive update of the display. + * This function pointer may be set to NULL if not required. + */ + int (*display_update)(void *handle, void *device, int x, int y, + int w, int h); + + /* Allocate memory for bitmap */ + /* This is provided in case you need to create memory in a special + * way, e.g. shared. If this is NULL, the Ghostscript memory device + * allocates the bitmap. This will only called to allocate the + * image buffer. The first row will be placed at the address + * returned by display_memalloc. + */ + void *(*display_memalloc)(void *handle, void *device, unsigned long size); + + /* Free memory for bitmap */ + /* If this is NULL, the Ghostscript memory device will free the bitmap */ + int (*display_memfree)(void *handle, void *device, void *mem); + +}; + + +#endif /* gdevdsp_INCLUDED */ diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/iapi.h psi-0.10/libpsi/libTeXFormula/iapi.h --- psi-0.10-orig/libpsi/libTeXFormula/iapi.h 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/iapi.h 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,307 @@ +/* Copyright (C) 1996-2001 Ghostgum Software Pty Ltd. All rights reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + For more information about licensing, please refer to + http://www.ghostscript.com/licensing/. For information on + commercial licensing, go to http://www.artifex.com/licensing/ or + contact Artifex Software, Inc., 101 Lucas Valley Road #110, + San Rafael, CA 94903, U.S.A., +1(415)492-9861. +*/ + +/* $Id: iapi.h,v 1.8.2.1 2003/12/12 22:08:04 giles Exp $ */ + +/* + * Public API for Ghostscript interpreter + * for use both as DLL and for static linking. + * + * Should work for Windows, OS/2, Linux, Mac. + * + * DLL exported functions should be as similar as possible to imain.c + * You will need to include "ierrors.h". + * + * Current problems: + * 1. Ghostscript does not support multiple instances. + * 2. Global variables in gs_main_instance_default() + * and gsapi_instance_counter + */ + +/* Exported functions may need different prefix + * GSDLLEXPORT marks functions as exported + * GSDLLAPI is the calling convention used on functions exported + * by Ghostscript + * GSDLLCALL is used on callback functions called by Ghostscript + * When you include this header file in the caller, you may + * need to change the definitions by defining these + * before including this header file. + * Make sure you get the calling convention correct, otherwise your + * program will crash either during callbacks or soon after returning + * due to stack corruption. + */ + +#ifndef iapi_INCLUDED +# define iapi_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WINDOWS_) || defined(__WINDOWS__) +# ifndef _Windows +# define _Windows +# endif +#endif + +#ifdef _Windows +# ifndef GSDLLEXPORT +# define GSDLLEXPORT __declspec(dllexport) +# endif +# ifndef GSDLLAPI +# define GSDLLAPI __stdcall +# endif +# ifndef GSDLLCALL +# define GSDLLCALL __stdcall +# endif +#endif /* _Windows */ + +#if defined(OS2) && defined(__IBMC__) +# ifndef GSDLLAPI +# define GSDLLAPI _System +# endif +# ifndef GSDLLCALL +# define GSDLLCALL _System +# endif +#endif /* OS2 && __IBMC */ + +#ifdef __MACOS__ +# pragma export on +#endif + +#ifndef GSDLLEXPORT +# define GSDLLEXPORT +#endif +#ifndef GSDLLAPI +# define GSDLLAPI +#endif +#ifndef GSDLLCALL +# define GSDLLCALL +#endif + +#if defined(__IBMC__) +# define GSDLLAPIPTR * GSDLLAPI +# define GSDLLCALLPTR * GSDLLCALL +#else +# define GSDLLAPIPTR GSDLLAPI * +# define GSDLLCALLPTR GSDLLCALL * +#endif + +#ifndef gs_main_instance_DEFINED +# define gs_main_instance_DEFINED +typedef struct gs_main_instance_s gs_main_instance; +#endif +#ifndef display_callback_DEFINED +# define display_callback_DEFINED +typedef struct display_callback_s display_callback; +#endif + +typedef struct gsapi_revision_s { + const char *product; + const char *copyright; + long revision; + long revisiondate; +} gsapi_revision_t; + + +/* Get version numbers and strings. + * This is safe to call at any time. + * You should call this first to make sure that the correct version + * of the Ghostscript is being used. + * pr is a pointer to a revision structure. + * len is the size of this structure in bytes. + * Returns 0 if OK, or if len too small (additional parameters + * have been added to the structure) it will return the required + * size of the structure. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_revision(gsapi_revision_t *pr, int len); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * If you try to create two instances, the second attempt + * will return < 0 and set pinstance to NULL. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Create a new instance of Ghostscript. + * This instance is passed to most other API functions. + * The caller_handle will be provided to callback functions. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_new_instance(gs_main_instance **pinstance, void *caller_handle); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Destroy an instance of Ghostscript + * Before you call this, Ghostscript must have finished. + * If Ghostscript has been initialised, you must call gsapi_exit() + * before gsapi_delete_instance. + */ +GSDLLEXPORT void GSDLLAPI +gsapi_delete_instance(gs_main_instance *instance); + +/* Set the callback functions for stdio + * The stdin callback function should return the number of + * characters read, 0 for EOF, or -1 for error. + * The stdout and stderr callback functions should return + * the number of characters written. + * If a callback address is NULL, the real stdio will be used. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_set_stdio(gs_main_instance *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); + +/* Set the callback function for polling. + * This is used for handling window events or cooperative + * multitasking. This function will only be called if + * Ghostscript was compiled with CHECK_INTERRUPTS + * as described in gpcheck.h. + * The polling function should return 0 if all is well, + * and negative if it wants ghostscript to abort. + * The polling function must be fast. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_poll(gs_main_instance *instance, + int (GSDLLCALLPTR poll_fn)(void *caller_handle)); + +/* Set the display device callback structure. + * If the display device is used, this must be called + * after gsapi_new_instance() and before gsapi_init_with_args(). + * See gdevdisp.h for more details. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_display_callback( + gs_main_instance *instance, display_callback *callback); + + +/* Initialise the interpreter. + * This calls gs_main_init_with_args() in imainarg.c + * 1. If quit or EOF occur during gsapi_init_with_args(), + * the return value will be e_Quit. This is not an error. + * You must call gsapi_exit() and must not call any other + * gsapi_XXX functions. + * 2. If usage info should be displayed, the return value will be e_Info + * which is not an error. Do not call gsapi_exit(). + * 3. Under normal conditions this returns 0. You would then + * call one or more gsapi_run_*() functions and then finish + * with gsapi_exit(). + */ +GSDLLEXPORT int GSDLLAPI gsapi_init_with_args(gs_main_instance *instance, + int argc, char **argv); + +/* + * The gsapi_run_* functions are like gs_main_run_* except + * that the error_object is omitted. + * If these functions return <= -100, either quit or a fatal + * error has occured. You then call gsapi_exit() next. + * The only exception is gsapi_run_string_continue() + * which will return e_NeedInput if all is well. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_begin(gs_main_instance *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_continue(gs_main_instance *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_end(gs_main_instance *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_with_length(gs_main_instance *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string(gs_main_instance *instance, + const char *str, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_file(gs_main_instance *instance, + const char *file_name, int user_errors, int *pexit_code); + + +/* Exit the interpreter. + * This must be called on shutdown if gsapi_init_with_args() + * has been called, and just before gsapi_delete_instance(). + */ +GSDLLEXPORT int GSDLLAPI +gsapi_exit(gs_main_instance *instance); + +/* Visual Tracer */ +/* This function is only for debug purpose clients */ +struct vd_trace_interface_s; +GSDLLEXPORT void GSDLLAPI +gsapi_set_visual_tracer(struct vd_trace_interface_s *I); + + +/* function prototypes */ +typedef int (GSDLLAPIPTR PFN_gsapi_revision)( + gsapi_revision_t *pr, int len); +typedef int (GSDLLAPIPTR PFN_gsapi_new_instance)( + gs_main_instance **pinstance, void *caller_handle); +typedef void (GSDLLAPIPTR PFN_gsapi_delete_instance)( + gs_main_instance *instance); +typedef int (GSDLLAPIPTR PFN_gsapi_set_stdio)(gs_main_instance *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_poll)(gs_main_instance *instance, + int(GSDLLCALLPTR poll_fn)(void *caller_handle)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_display_callback)( + gs_main_instance *instance, display_callback *callback); +typedef int (GSDLLAPIPTR PFN_gsapi_init_with_args)( + gs_main_instance *instance, int argc, char **argv); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_begin)( + gs_main_instance *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_continue)( + gs_main_instance *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_end)( + gs_main_instance *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_with_length)( + gs_main_instance *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string)( + gs_main_instance *instance, const char *str, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_file)(gs_main_instance *instance, + const char *file_name, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_exit)(gs_main_instance *instance); +typedef void (GSDLLAPIPTR PFN_gsapi_set_visual_tracer) + (struct vd_trace_interface_s *I); + + +#ifdef __MACOS__ +#pragma export off +#endif + +#ifdef __cplusplus +} /* extern 'C' protection */ +#endif + +#endif /* iapi_INCLUDED */ diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.cpp psi-0.10/libpsi/libTeXFormula/libTeXFormula.cpp --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.cpp 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormula.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,373 @@ +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// +#include +#include +#include "math.h" +#include "string.h" + +#include +#include +#include +#include + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN 1 + #include + #include + #define DIR_SEPERATOR "\\" +#else + #include + #include + #define max std::max + #define min std::min + #define DIR_SEPERATOR "/" +#endif + +#include "libTeXFormula.h" +#include "libTeXFormulaInternal.h" +#include "display.h" +#include + +extern int g_result_width, g_result_height; +extern unsigned char *g_result_pixmap; + +static int g_resolution = 160; +static std::string tempDir; +static gs_main_instance *g_minst = NULL; +static bool g_gsLibAvailable = false; +static std::string g_gsCmdName; +static int g_AntialiasFactor = 4; + +static display_callback display = + { + sizeof(display_callback), + DISPLAY_VERSION_MAJOR, + DISPLAY_VERSION_MINOR, + display_open, + display_preclose, + display_close, + display_presize, + display_size, + display_sync, + display_page, + display_update, + NULL, /* memalloc */ + NULL /* memfree */ + }; + +// initializes the libTex Library +int DLLEXPORT initLibTeXFormula() +{ + + // check if LaTeX is available + int result = startProcess("pdflatex -version"); + + if (result < 0) + return LIBTEXF_ERROR_SYSTEM; + if (result > 0) + return LIBTEXF_ERROR_LATEXINIT; + + // create Temporary Directory + tempDir = CreateTempDir(); + if (tempDir == "") + return LIBTEXF_ERROR_NOTEMPDIR; + + + // loads GhostScript Library + if (LoadGSLibrary()) + { + g_gsLibAvailable = true; + + // create ghostscript instance + if (gsapi_new_instance_runtime(&g_minst, NULL) < 0 || + gsapi_set_display_callback_runtime(g_minst, &display) < 0) + { + freeLibTeXFormula(); + return LIBTEXF_ERROR_GSINIT; + } + } + + if (startProcess("gswin32c -v") == 0) + g_gsCmdName = "gswin32c"; + else if (startProcess("gswin32 -v") == 0) + g_gsCmdName = "gswin32"; + else if (startProcess("gs -v") == 0) + g_gsCmdName = "gs"; + else if (!g_gsLibAvailable) + return LIBTEXF_ERROR_GSINIT; + + return 1; +}; + +// Frees allocated resources +void DLLEXPORT freeLibTeXFormula() +{ + // free Temp Dir + rmdir(tempDir.c_str()); + + // release ghostscript instance + if (g_minst) + gsapi_delete_instance_runtime(g_minst); + + // free Ghostscript Libraray + FreeGSLibrary(); +}; + +// deletes temporary stuff +void cleanUp() +{ + unlink((tempDir + DIR_SEPERATOR "formula.pdf").c_str()); + unlink((tempDir + DIR_SEPERATOR "formula.aux").c_str()); + unlink((tempDir + DIR_SEPERATOR "formula.log").c_str()); + unlink((tempDir + DIR_SEPERATOR "formula.tex").c_str()); + unlink((tempDir + DIR_SEPERATOR "formula.pix").c_str()); +}; + +// set resolution of output image +void DLLEXPORT setResolutionTeXFormula(int resolution) +{ + g_resolution = resolution; +}; + +// scales a image down using a simple linear filter +void antialiasImage(Image *theImage) +{ + // calculate new image size + int newWidth = (int) ceil((double) theImage->width / g_AntialiasFactor / 4.0) * 4, + newHeight = (int) ceil((double) theImage->height / g_AntialiasFactor); + + // allocate memory + unsigned char *newImage = (unsigned char*) malloc(newWidth * newHeight); + + // scale image down + for (int x = 0; x < newWidth;x++) + for (int y = 0; y < newHeight;y++) + { + unsigned int sum = 0; + + // sum up intensities + for (int x2 = x * g_AntialiasFactor; x2 < (x + 1) * g_AntialiasFactor;x2++) + for (int y2 = y * g_AntialiasFactor; y2 < (y + 1) * g_AntialiasFactor;y2++) + { + int imgX = max(0,min(theImage->width -1,x2)), + imgY = max(0,min(theImage->height -1,y2)); + sum += theImage->pixmap[imgY * theImage->width + imgX]; + }; + + // store new intensity + sum /= (g_AntialiasFactor * g_AntialiasFactor); + newImage[y * newWidth +x] = sum; + + // No gamma at the moment ... + /*sum = sqrt((double) sum*sum*sum); + sum /= 256;*/ + //double sumf = (double) sum / 256.0; + //sum = pow(sumf, 1.8) * 256;//(double) sqrt((double) sum*sum*sum) * 256; + //newImage[y * newWidth +x] = sum / (g_AntialiasFactor * g_AntialiasFactor)); + } + + // store new image in struct + free(theImage->pixmap); + theImage->pixmap = newImage; + theImage->width = newWidth; + theImage->height = newHeight; +}; + + +// the forbidden commands +const char *unsecureCommands[] = + { + "\\catcode", + "\\include", + "\\includeonly", + "\\input", + "\\newcommand", + "\\newenvironment", + "\\newtheorem", + "\\newfont", + "\\renewcommand", + "\\renewenvironment", + "\\typein", + "\\typeout", + "\\write", + NULL + }; + +// checks if a string doesn't contain any unsecure LaTeX commands +// +// WARNING: We can't say for sure, that there are no other unsecure LaTeX commands. +// The ones here are from wikitex, but there could still be other ones. +// Using this LaTeX plugin might be a security risk! +// +bool isStringSecure(const char* string) +{ + // convert string to lower case + std::string stringLower = string; + std::transform(stringLower.begin(),stringLower.end(),stringLower.begin(),tolower); + //char *stringLower = new char[strlen(string) + 1]; + //strcpy(stringLower,string); + //strlwr(stringLower); + + // check string for forbidden commands + for (const char **ptr = unsecureCommands; *ptr != NULL; ptr++) + if (stringLower.find(*ptr) != std::string::npos) + return false; + + // prevent user from leaving math mode + bool escaped = false; + for (unsigned int i = 0; i < strlen(string); i++) + { + switch (string[i]) + { + case '\\': + escaped = !escaped; + break; + case '$': + if (!escaped) + return false; + escaped = false; + break; + default: + escaped = false; + }; + }; + + return true; +}; + +// creates an image from an expression in LaTex +int DLLEXPORT parseTeXFormula(const char *formula, Image *theImage) +{ + // check if formula is secure + if (!isStringSecure(formula)) + return LIBTEXF_ERROR_INSECURE_FORMULA; + + // create TeX File + std::ofstream file((tempDir + DIR_SEPERATOR "formula.tex").c_str()); + if(!file) + return LIBTEXF_ERROR_TEXFILE_OPEN; + + file << "\\documentclass{minimal} " + << "\\batchmode \\begin{document} " + << "\\newcommand*{\\shipoutpdf}[1]{ " + << "\\newpage " + << "\\setlength{\\parindent}{0cm} " + << "\\setlength{\\leftmargin}{0cm} " + << "\\setbox0=\\vbox{\\kern -1truein \\kern .0ex" + << "\\hbox{\\kern -1truein \\kern .0ex #1 \\kern 1truein \\kern -.7ex}" + << "\\kern 1truein \\kern .0ex} " + << "\\dimen0\\ht0 " + << "\\advance\\dimen0\\dp0 " + << "\\setlength{\\pdfpageheight}{\\dimen0} " + << "\\setlength{\\pdfpagewidth}{\\wd0} " + << "\\shipout\\box0 " + << "} " + << "\\shipoutpdf{$"<< formula <<"$} " + << "\\end{document}\n"; + file.close(); + + // create pdf from TeX File + if (startProcess( "pdflatex formula.tex", tempDir.c_str() ) ) + { + cleanUp(); + return LIBTEXF_ERROR_LATEXRUN; + }; + + // read pdf in ghostscript + char * gsargv[12]; + char arg1[64]; + char arg2[64]; + sprintf(arg1, "-dDisplayHandle=%d", 0); + sprintf(arg2, "-dDisplayFormat=%d", + DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | + DISPLAY_LITTLEENDIAN); + + int gsargc; + char filename[1024], res[15],res2[30]; + strcpy(filename,(tempDir + DIR_SEPERATOR "formula.pdf").c_str()); + sprintf(res,"-r%d",g_resolution * g_AntialiasFactor); + + // use the library + if (g_gsLibAvailable) + { + gsargv[0] = "gs"; /* actual value doesn't matter */ + gsargv[1] = "-dNOPAUSE"; + gsargv[2] = "-dBATCH"; + gsargv[3] = "-dSAFER"; + gsargv[4] = "-sDEVICE=display"; + gsargv[5] = res; + gsargv[6] = "-dTextAlphaBits=1"; + gsargv[7] = arg1; + gsargv[8] = arg2; + gsargv[9] = "-q"; + gsargv[10] = "-f"; + gsargv[11] = filename; + gsargc= 12; + if(gsapi_init_with_args_runtime(g_minst, gsargc, gsargv) < 0 || gsapi_exit_runtime(g_minst) < 0) + { + cleanUp(); + return LIBTEXF_ERROR_GSRUN; + }; + + theImage->width = g_result_width; + theImage->height = g_result_height; + theImage->pixmap = g_result_pixmap; + + } + // use the command line tool + else + { + // determine the image size + std::string output; + if (!startProcess( (g_gsCmdName + " -dNOPAUSE -dBATCH -dWhiteIsOpaque -dTextAlphaBits=1 -dSAFER -sDEVICE=bbox -q " +res +" -f formula.pdf").c_str(), tempDir.c_str(), NULL, &output ) == 0) + { + cleanUp(); + return LIBTEXF_ERROR_GSRUN; + }; + + float x1,x2,y1,y2; + size_t pos = output.find("%%HiResBoundingBox"); + sscanf(output.c_str() + pos,"%%%%HiResBoundingBox: %f %f %f %f",&x1,&y1,&x2,&y2); + + theImage->width = (int) ceil(x2 / 72.0 * g_resolution / 4) * 4 * g_AntialiasFactor, + theImage->height = (int) ceil(y2 / 72.0 * g_resolution ) * g_AntialiasFactor; + + // create the image + sprintf(res2," -g%dx%d", theImage->width, theImage->height); + if (!startProcess( (g_gsCmdName + " -dNOPAUSE -dBATCH -dSAFER -sDEVICE=bit -dTextAlphaBits=1 -dGrayValues=256 -q " +res + res2+ " -sOutputFile=formula.pix -f formula.pdf").c_str(), tempDir.c_str(), NULL, &output ) == 0) + { + cleanUp(); + return LIBTEXF_ERROR_GSRUN; + }; + + // read the image + theImage->pixmap = (unsigned char*) malloc(theImage->width * theImage->height); + std::ifstream image((tempDir + DIR_SEPERATOR "formula.pix").c_str()); + image.read((char*) theImage->pixmap, theImage->width * theImage->height); + if (image.fail()) + { + cleanUp(); + return LIBTEXF_ERROR_GSRUN; + }; + + }; + + if (g_AntialiasFactor > 1) + antialiasImage(theImage); + + // we tidy up behind ourselves! (at most times...) + cleanUp(); + return 1; +}; + + +// frees the memory used by an image +void DLLEXPORT freeTeXFormulaImage(Image *theImage) +{ + if (theImage->pixmap != NULL) + free(theImage->pixmap); +}; + + diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.h psi-0.10/libpsi/libTeXFormula/libTeXFormula.h --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.h 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormula.h 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,37 @@ +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// +#ifndef LIB_TEX_H +#define LIB_TEX_H + +struct Image +{ + int width, height; + unsigned char *pixmap; +}; + +#ifdef WIN32 + #define DLLEXPORT __declspec( dllexport ) +#else + #define DLLEXPORT +#endif + +// error codes +#define LIBTEXF_ERROR_NOTEMPDIR -1 +#define LIBTEXF_ERROR_GSINIT -2 +#define LIBTEXF_ERROR_LATEXRUN -3 +#define LIBTEXF_ERROR_GSRUN -4 +#define LIBTEXF_ERROR_TEXFILE_OPEN -5 +#define LIBTEXF_ERROR_LATEXINIT -6 +#define LIBTEXF_ERROR_SYSTEM -7 +#define LIBTEXF_ERROR_INSECURE_FORMULA -8 + +// libTeX functions +int DLLEXPORT initLibTeXFormula(); +void DLLEXPORT freeLibTeXFormula(); +int DLLEXPORT parseTeXFormula(const char *formula, Image *theImage); +void DLLEXPORT freeTeXFormulaImage(Image *theImage); +void DLLEXPORT setResolutionTeXFormula(int resolution); + +#endif diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaInternal.h psi-0.10/libpsi/libTeXFormula/libTeXFormulaInternal.h --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaInternal.h 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormulaInternal.h 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,28 @@ +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// +#ifndef LIB_TEX_INTERNAL_H +#define LIB_TEX_INTERNAL_H + +#include "gdevdsp.h" +#include "iapi.h" +//#include "ierrors.h" + +#include + +// internal helper functions +int startProcess(const char *CommandLine, const char *workDir = NULL, std::string *stdoutString = NULL, std::string *stderrorString = NULL); +bool LoadGSLibrary(); +void FreeGSLibrary(); +std::string CreateTempDir(); + +// ghostscript API functions +extern PFN_gsapi_new_instance gsapi_new_instance_runtime; +extern PFN_gsapi_delete_instance gsapi_delete_instance_runtime; +extern PFN_gsapi_set_display_callback gsapi_set_display_callback_runtime; +extern PFN_gsapi_init_with_args gsapi_init_with_args_runtime; +extern PFN_gsapi_run_file gsapi_run_file_runtime; +extern PFN_gsapi_exit gsapi_exit_runtime; + +#endif diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaLinux.cpp psi-0.10/libpsi/libTeXFormula/libTeXFormulaLinux.cpp --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaLinux.cpp 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormulaLinux.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,150 @@ +// +// libTeXFormulaLinux.cpp +// +// this file contains the parts of libTeXFormula, which are specific to Linux +// +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include + + +#include "libTeXFormula.h" +#include "gdevdsp.h" +#include "iapi.h" + +static void *gsHandle = 0; + +// function pointers to GhostScript interface +PFN_gsapi_new_instance gsapi_new_instance_runtime; +PFN_gsapi_delete_instance gsapi_delete_instance_runtime; +PFN_gsapi_set_stdio gsapi_set_stdio_runtime; +PFN_gsapi_set_display_callback gsapi_set_display_callback_runtime; +PFN_gsapi_init_with_args gsapi_init_with_args_runtime; +PFN_gsapi_run_file gsapi_run_file_runtime; +PFN_gsapi_exit gsapi_exit_runtime; + +// loads the GS library at runtime +bool LoadGSLibrary() +{ + // Load the library + gsHandle = dlopen("libgs.so",RTLD_LAZY); + + if (!gsHandle || dlerror()) + return false; + + // get the function pointers to the library functions + gsapi_new_instance_runtime = (PFN_gsapi_new_instance) dlsym(gsHandle,"gsapi_new_instance"); + if (dlerror()) return false; + + gsapi_delete_instance_runtime = (PFN_gsapi_delete_instance) dlsym(gsHandle,"gsapi_delete_instance"); + if (dlerror()) return false; + + gsapi_set_stdio_runtime = (PFN_gsapi_set_stdio) dlsym(gsHandle,"gsapi_set_stdio"); + if (dlerror()) return false; + + gsapi_set_display_callback_runtime = (PFN_gsapi_set_display_callback) dlsym(gsHandle,"gsapi_set_display_callback"); + if (dlerror()) return false; + + gsapi_init_with_args_runtime = (PFN_gsapi_init_with_args) dlsym(gsHandle,"gsapi_init_with_args"); + if (dlerror()) return false; + + gsapi_run_file_runtime = (PFN_gsapi_run_file) dlsym(gsHandle,"gsapi_run_file"); + if (dlerror()) return false; + + gsapi_exit_runtime = (PFN_gsapi_exit) dlsym(gsHandle,"gsapi_exit"); + if (dlerror()) return false; + + return true; +}; + + +// frees the Ghostscript library +void FreeGSLibrary() +{ + if (gsHandle) + dlclose(gsHandle); +}; + +// creates an temporary directory +std::string CreateTempDir() +{ + std::string dirTemplate = std::string(P_tmpdir) + "/libTex.XXXXXX"; + char *buffer = new char[dirTemplate.length() + 1]; + strcpy(buffer,dirTemplate.c_str()); + char *dirPtr = mkdtemp(buffer); + if (!dirPtr) + { + delete[] buffer; + return ""; + }; + + dirTemplate = dirPtr; + delete[] buffer; + + return dirTemplate; +}; + +// starts a subprocess and waits until it's termination +int startProcess(const char *CommandLine, const char *workDir = NULL, std::string *stdoutString = NULL, std::string *stderrorString = NULL) +{ + int result; + + // create pipes to redirect output + int stdoutDesc[2], stderrorDesc[2]; + pipe(stdoutDesc); + pipe(stderrorDesc); + int oldStderror, oldStdout; + + // redirect stdout + oldStdout = dup(1); + dup2(stdoutDesc[1], 1); + + // redirect stderror + oldStderror = dup(2); + dup2(stderrorDesc[1], 2); + + // start the process + if (workDir) + result = system( ( std::string("cd ") + workDir + " && " + CommandLine).c_str()); + else + result = system(CommandLine); + + char Buffer[10001]; + + // Read stdout + memset(Buffer,0,10001); + fcntl(stdoutDesc[0], F_SETFL, fcntl(stderrorDesc[0], F_GETFL) | O_NONBLOCK); + read(stdoutDesc[0],Buffer,10000); + if (stdoutString) *stdoutString= Buffer; + + // Read stderror + memset(Buffer,0,10001); + fcntl(stderrorDesc[0], F_SETFL, fcntl(stderrorDesc[0], F_GETFL) | O_NONBLOCK); + read(stderrorDesc[0],Buffer,10000); + if (stderrorString) *stderrorString = Buffer; + + // restore stdout + dup2(oldStdout, 1); + + // restore stderror + dup2(oldStderror, 2); + + // close pipes + close(stdoutDesc[0]); + close(stdoutDesc[1]); + close(stderrorDesc[0]); + close(stderrorDesc[1]); + + return result; +}; + +#endif diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.pri psi-0.10/libpsi/libTeXFormula/libTeXFormula.pri --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.pri 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormula.pri 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,16 @@ +libTeXFormula { + INCLUDEPATH += $$TEXFORMULA_CPP + + SOURCES += \ + $$TEXFORMULA_CPP/libTeXFormula.cpp \ + $$TEXFORMULA_CPP/libTeXFormulaLinux.cpp \ + $$TEXFORMULA_CPP/libTeXFormulaWin32.cpp \ + $$TEXFORMULA_CPP/display.cpp + + HEADERS += \ + $$TEXFORMULA_CPP//display.h \ + $$TEXFORMULA_CPP//libTeXFormula.h \ + $$TEXFORMULA_CPP//libTeXFormulaInternal.h \ + $$TEXFORMULA_CPP//iapi.h \ + $$TEXFORMULA_CPP//gdevdsp.h +} diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.pro psi-0.10/libpsi/libTeXFormula/libTeXFormula.pro --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormula.pro 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormula.pro 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,21 @@ +TEMPLATE = lib +CONFIG += warn_on release plugin +TARGET = libTexFormula +INCLUDEPATH += $$TEXFORMULA_CPP + + +#target.path = $(QTDIR)/plugins/designer +#INSTALLS += target + +SOURCES += \ + libTeXFormula.cpp \ + libTeXFormulaLinux.cpp \ + libTeXFormulaWin32.cpp \ + display.cpp + +HEADERS += \ + display.h \ + libTeXFormula.h \ + libTeXFormulaInternal.h \ + iapi.h \ + gdevdsp.h diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaWin32.cpp psi-0.10/libpsi/libTeXFormula/libTeXFormulaWin32.cpp --- psi-0.10-orig/libpsi/libTeXFormula/libTeXFormulaWin32.cpp 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/libTeXFormulaWin32.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,166 @@ +// +// libTeXFormulaWin32.cpp +// +// this file contains the parts of libTeXFormula, which are specific to win32 +// +// +// this file, part of libTexFormula, is released under the conditions of the zlib license. +// for details see: http://www.gzip.org/zlib/zlib_license.html +// + +#ifdef WIN32 +#include +#include + +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include +#include +#include + +#include "libTeXFormula.h" +#include "gdevdsp.h" +#include "iapi.h" +#include + + +#define STDIN 0 +#define STDOUT 1 +#define STDERROR 2 + +static HMODULE gsDLL = 0; + +// function pointers to GhostScript Interface +PFN_gsapi_new_instance gsapi_new_instance_runtime; +PFN_gsapi_delete_instance gsapi_delete_instance_runtime; +PFN_gsapi_set_stdio gsapi_set_stdio_runtime; +PFN_gsapi_set_display_callback gsapi_set_display_callback_runtime; +PFN_gsapi_init_with_args gsapi_init_with_args_runtime; +PFN_gsapi_run_file gsapi_run_file_runtime; +PFN_gsapi_exit gsapi_exit_runtime; + +// loads the GS Library at runtime +bool LoadGSLibrary() +{ + // Load the DLL + gsDLL = LoadLibraryA("gsdll32.dll"); + + if (!gsDLL) + return false; + + // get the Function Pointers to the DLL functions + if (!(gsapi_new_instance_runtime = (PFN_gsapi_new_instance) GetProcAddress(gsDLL,"gsapi_new_instance"))) + return false; + if (!(gsapi_delete_instance_runtime = (PFN_gsapi_delete_instance) GetProcAddress(gsDLL,"gsapi_delete_instance"))) + return false; + if (!(gsapi_set_stdio_runtime = (PFN_gsapi_set_stdio) GetProcAddress(gsDLL,"gsapi_set_stdio"))) + return false; + if (!(gsapi_set_display_callback_runtime = (PFN_gsapi_set_display_callback) GetProcAddress(gsDLL,"gsapi_set_display_callback"))) + return false; + if (!(gsapi_init_with_args_runtime = (PFN_gsapi_init_with_args) GetProcAddress(gsDLL,"gsapi_init_with_args"))) + return false; + if (!(gsapi_run_file_runtime = (PFN_gsapi_run_file) GetProcAddress(gsDLL,"gsapi_run_file"))) + return false; + if (!(gsapi_exit_runtime = (PFN_gsapi_exit) GetProcAddress(gsDLL,"gsapi_exit"))) + return false; + + return true; +}; + +// creates an temporary directory +std::string CreateTempDir() +{ + char *tempName = _tempnam(NULL, "libTex."); + if (!tempName) + return ""; + + if (!CreateDirectoryA(tempName,NULL)) + return ""; + + return tempName; +}; + +// frees the Ghostscript library +void FreeGSLibrary() +{ + if (gsDLL) + FreeLibrary(gsDLL); +}; + +// starts a subprocess and waits until it's termination +int startProcess(const char *CommandLine, const char *workDir = NULL, std::string *stdoutString = NULL, std::string *stderrorString = NULL) +{ + DWORD returnCode; + STARTUPINFOA si; + SECURITY_ATTRIBUTES sa; + PROCESS_INFORMATION pi; + HANDLE stdoutReadPipe,stdoutWritePipe; + HANDLE stderrorReadPipe,stderrorWritePipe; + + // Create pipe for STDERR + sa.nLength=sizeof(sa); + sa.bInheritHandle=TRUE; + sa.lpSecurityDescriptor=NULL; + CreatePipe(&stdoutReadPipe,&stdoutWritePipe,&sa,1024); + CreatePipe(&stderrorReadPipe,&stderrorWritePipe,&sa,1024); + + // Prepare si structure + ZeroMemory( &si, sizeof(si) ); + si.wShowWindow = SW_HIDE; + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdOutput = stdoutWritePipe; + si.hStdError = stderrorWritePipe; + ZeroMemory( &pi, sizeof(pi) ); + + // Start the child process. + if( !CreateProcessA( + NULL, // No module name (use command line). + const_cast(CommandLine), // Command line. + NULL, // Process handle not inheritable. + NULL, // Thread handle not inheritable. + TRUE, // Set handle inheritance to FALSE. + CREATE_NO_WINDOW | DETACHED_PROCESS, // Don't open Console + NULL, // Use parent's environment block. + const_cast(workDir), // Use parent's starting directory. + &si, // Pointer to STARTUPINFO structure. + &pi ) // Pointer to PROCESS_INFORMATION structure. + ) + return -1; + + // Wait until child process exits + WaitForSingleObject( pi.hProcess, INFINITE ); + + + char Buffer[10001]; + DWORD bytes = 0; + DWORD mode = PIPE_READMODE_BYTE|PIPE_NOWAIT; + + // Read STDOUT + memset(Buffer,0,10001); + SetNamedPipeHandleState(stdoutReadPipe,&mode, NULL, NULL); + ReadFile(stdoutReadPipe,Buffer,10000,&bytes,NULL); + if (stdoutString) *stdoutString= Buffer; + + // Read STDERROR + memset(Buffer,0,10001); + SetNamedPipeHandleState(stderrorReadPipe,&mode, NULL, NULL); + ReadFile(stderrorReadPipe,Buffer,10000,&bytes,NULL); + if (stderrorString) *stderrorString = Buffer; + + // Get processes exit code + GetExitCodeProcess(pi.hProcess,&returnCode); + + // Close process and thread handles + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + CloseHandle( stdoutReadPipe ); + CloseHandle( stdoutWritePipe ); + CloseHandle( stderrorReadPipe ); + CloseHandle( stderrorWritePipe ); + + return returnCode; +}; + +#endif diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/libTeXFormula/LICENSE psi-0.10/libpsi/libTeXFormula/LICENSE --- psi-0.10-orig/libpsi/libTeXFormula/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ psi-0.10/libpsi/libTeXFormula/LICENSE 2006-01-14 23:05:33.000000000 +0000 @@ -0,0 +1,25 @@ + + The files in the src, lib, toolbin, examples, doc and man + directories (folders) and any subdirectories (sub-folders) + thereof are part of GPL Ghostscript. + + The files in the Resource directory and any subdirectories thereof + are also part of GPL Ghostscript, with the explicit exception of + the files in the CMap subdirectory. The CMap files are copyright + Adobe Systems Incorporated and covered by a separate license + which permits only verbatim distribution. + + GPL Ghostscript is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + GPL Ghostscript 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 so you can know your rights and responsibilities. + It should be in a file named doc/COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA + 02111-1307, USA. diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/psiwidgets/psitextview.cpp psi-0.10/libpsi/psiwidgets/psitextview.cpp --- psi-0.10-orig/libpsi/psiwidgets/psitextview.cpp 2006-01-14 23:01:06.000000000 +0000 +++ psi-0.10/libpsi/psiwidgets/psitextview.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -24,9 +24,13 @@ #include #include #include +#include #include #include +#include +#include +#include "libTeXFormula.h" #ifndef WIDGET_PLUGIN #include "iconset.h" @@ -283,6 +287,164 @@ s += ">"; return s; } +//---------------------------------------------------------------------------- +// TeXFormula - helper class for PsiTextView +//---------------------------------------------------------------------------- + +class TeXFormula : public QObject, public QTextCustomItem +{ + Q_OBJECT + +public: + TeXFormula(QTextDocument *p, const QMap &attr, const QString &context, QMimeSourceFactory &factory, QFont font); + ~TeXFormula(); + + void adjustToPainter(QPainter *); + void draw(QPainter *p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup &cg, bool selected); + QString richText() const; + + Placement placement() const { return place; } + int minimumWidth() const { return width; } + virtual int ascent() const { return asc; } + + +private slots: + void iconUpdated(const QPixmap &); + +private: + Placement place; + int tmpwidth, tmpheight; + int asc; + QMap attributes; + QPixmap image; + QString imgId; + bool LaTeXFailed; + QFont myFont; +}; + +TeXFormula::TeXFormula(QTextDocument *p, const QMap &attr, const QString &context, QMimeSourceFactory &factory, QFont font) +: QObject(0, 0), QTextCustomItem (p) +{ + Q_UNUSED(context); + Q_UNUSED(factory); + + Image latexImage; + myFont = font; + + if (parseTeXFormula(attr["formula"],&latexImage) > 0) + { + + width = latexImage.width; + height = latexImage.height; + + // create Image + QImage tmpImage; + tmpImage.create(width, height, 8, 256); + + // Initialise Palette + for (int i=0; i<256; i++) + tmpImage.setColor( i, qRgba(i,i,i,0xff) ); + + // copy the image in the buffer + for (int y = 0; y < height; y++) + memcpy(tmpImage.scanLine(y),latexImage.pixmap + y * width, width); + + // free memory + freeTeXFormulaImage(&latexImage); + + // copy Image to pixmap + image.convertFromImage(tmpImage, 0); + + + tmpwidth = width; + tmpheight = height; + + QFontMetrics met(myFont); + asc = height - 3;; + + LaTeXFailed = false; + } + else + { + LaTeXFailed = true; + QFontMetrics met(myFont); + width = met.width("$$" + attr["formula"] + "$$"); + height = met.height(); + asc = met.ascent(); + }; + + place = PlaceInline; + if ( attr["align"] == "left" ) + place = PlaceLeft; + else if ( attr["align"] == "right" ) + place = PlaceRight; + + attributes = attr; +} + +TeXFormula::~TeXFormula() +{ + +} + +void TeXFormula::adjustToPainter(QPainter *) +{ + // FIXME: This class can be incorrectly printed. Check this sometime later. +} + +void TeXFormula::draw(QPainter *p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup &cg, bool /*selected*/) +{ + if ( placement() != PlaceInline ) { + x = xpos; + y = ypos; + } + + // if formula couldn't be rendered, draw text instead + if (LaTeXFailed) + { + p->save(); + p->setFont(myFont); + p->setPen(QPen(QColor(255,0,0))); + p->drawText(x,y,width,height, Qt::AlignHCenter | Qt::AlignRight | Qt::SingleLine | Qt::DontClip, "$$" + attributes["formula"] + "$$"); + p->restore(); + return; + }; + + if (image.isNull()) + { + p->fillRect( x, y, width, height, cg.dark() ); + return; + }; + + if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) + return; + + if ( placement() == PlaceInline ) + p->drawPixmap( x , y, image ); + else + p->drawPixmap( cx , cy, image, cx - x, cy - y, cw, ch ); +} + +void TeXFormula::iconUpdated(const QPixmap &) +{ + // TODO: any ideas what it should do? ;-) +} + +QString TeXFormula::richText() const +{ + QString s; + s += "::ConstIterator it = attributes.begin(); + for ( ; it != attributes.end(); ++it ) { + s += it.key() + "="; + if ( (*it).find( ' ' ) != -1 ) + s += "\"" + *it + "\"" + " "; + else + s += *it + " "; + } + s += ">"; + return s; +} //---------------------------------------------------------------------------- // PsiStyleSheet - helper class for PsiTextView @@ -296,6 +458,7 @@ : QStyleSheet(parent, name) { new QStyleSheetItem(this, QString::fromLatin1("icon")); + new QStyleSheetItem(this, QString::fromLatin1("latex")); } public: @@ -307,6 +470,16 @@ const QStyleSheetItem *style = item( name ); if ( style && style->name() == "icon" ) return new TextIcon( doc, attr, context, (QMimeSourceFactory&)factory ); + + // Insert LaTeX fFormulas when corresponding tag is found + if ( style && style->name() == "latex" ) + { + // Get text format for element (based on default format) + // TODO: based on current format? + QTextFormat format = doc->formatCollection()->defaultFormat()->makeTextFormat(style,attr,style->logicalFontSize()); + return new TeXFormula( doc, attr, context, (QMimeSourceFactory&)factory, format.font() ); + }; + return QStyleSheet::tag(name, attr, context, factory, emptyTag, doc); } diff --exclude='*orig' -Naur psi-0.10-orig/libpsi/psiwidgets/psiwidgets.pro psi-0.10/libpsi/psiwidgets/psiwidgets.pro --- psi-0.10-orig/libpsi/psiwidgets/psiwidgets.pro 2005-08-21 17:44:28.000000000 +0000 +++ psi-0.10/libpsi/psiwidgets/psiwidgets.pro 2006-01-14 23:05:33.000000000 +0000 @@ -2,6 +2,12 @@ CONFIG += qt thread warn_on release plugin TARGET = psiwidgets +# libTeXFormula +CONFIG += libTeXFormula +TEXFORMULA_CPP = ../libTeXFormula +include($$TEXFORMULA_CPP/libTeXFormula.pri) + + #target.path = $(QTDIR)/plugins/designer #INSTALLS += target diff --exclude='*orig' -Naur psi-0.10-orig/libpsi.pri psi-0.10/libpsi.pri --- psi-0.10-orig/libpsi.pri 2005-08-21 17:44:27.000000000 +0000 +++ psi-0.10/libpsi.pri 2006-01-14 23:05:33.000000000 +0000 @@ -4,6 +4,11 @@ ICONSET_CPP = $$LIBPSI_CPP/iconset include($$ICONSET_CPP/iconset.pri) + # libTeXFormula + CONFIG += libTeXFormula + TEXFORMULA_CPP = $$LIBPSI_CPP/libTeXFormula + include($$TEXFORMULA_CPP/libTeXFormula.pri) + # psiwidgets CONFIG += psiwidgets WIDGETS_CPP = $$LIBPSI_CPP/psiwidgets diff --exclude='*orig' -Naur psi-0.10-orig/psi.pro psi-0.10/psi.pro --- psi-0.10-orig/psi.pro 2005-08-21 17:44:27.000000000 +0000 +++ psi-0.10/psi.pro 2006-01-14 23:05:33.000000000 +0000 @@ -6,6 +6,7 @@ } SUBDIRS += \ + $$LIBPSI_CPP/libTeXFormula \ $$LIBPSI_CPP/psiwidgets \ src diff --exclude='*orig' -Naur psi-0.10-orig/src/chatdlg.cpp psi-0.10/src/chatdlg.cpp --- psi-0.10-orig/src/chatdlg.cpp 2006-01-14 23:01:14.000000000 +0000 +++ psi-0.10/src/chatdlg.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -638,6 +638,10 @@ if(option.useEmoticons && option.emoticonsInChatDlg) ss = emoticonify(ss); + // TODO: extra option for TeX + if(option.useLaTeX && d->pa->psi()->LaTeXReady()) + ss = parseTeX(ss); + msg += QString(" [%1]").arg(ss); } appendSysMsg(msg); @@ -1139,6 +1143,10 @@ if(option.useEmoticons && option.emoticonsInChatDlg) txt = emoticonify(txt); + // TODO: extra option for TeX + if(option.useLaTeX && d->pa->psi()->LaTeXReady()) + txt = parseTeX(txt); + who = expandEntities(who); if(emote) { diff --exclude='*orig' -Naur psi-0.10-orig/src/common.cpp psi-0.10/src/common.cpp --- psi-0.10-orig/src/common.cpp 2006-01-14 23:01:15.000000000 +0000 +++ psi-0.10/src/common.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -46,7 +46,6 @@ #include #include - #include #ifdef Q_WS_X11 @@ -732,6 +731,42 @@ return out; } +// parses the string and replaces TeX formulas by corresponding tags +QString parseTeX(const QString &in) +{ + QString message = in; + + // RegExp for searching the Latex Formulas + QRegExp rg("\\$\\$.+\\$\\$"); + rg.setMinimal(true); + + + // replace Latex Formulas with tag + int pos = 0; + QMap replaceMap; + while (pos >= 0 && (unsigned int)pos < message.length()) + { + // find formula + pos = rg.search(message, pos); + + if (pos >= 0 ) + { + QString match = rg.cap(0); + QString latexFormula = match; + + // remove $$s + latexFormula.replace("$$",""); + + // escape quotation marks in string + latexFormula.replace("\"","""); + + // replace formula with tag + message = message.replace(pos,match.length(),""); + }; + }; + + return message; +}; // sickening QString emoticonify(const QString &in) { @@ -810,6 +845,7 @@ break; p.putRich( QString("").arg(closest->name()).arg(str.mid(foundPos, foundLen)) ); + i = foundPos + foundLen; } } diff --exclude='*orig' -Naur psi-0.10-orig/src/common.h psi-0.10/src/common.h --- psi-0.10-orig/src/common.h 2006-01-14 23:01:32.000000000 +0000 +++ psi-0.10/src/common.h 2006-01-14 23:05:33.000000000 +0000 @@ -142,7 +142,7 @@ QString player; QString customBrowser, customMailer; - bool ignoreHeadline, ignoreNonRoster, excludeGroupChatsFromIgnore, scrollTo, keepSizes, useEmoticons, alertOpenChats, useStatusLinebreak, spaceEmoticons; + bool ignoreHeadline, ignoreNonRoster, excludeGroupChatsFromIgnore, scrollTo, keepSizes, useEmoticons, alertOpenChats, useStatusLinebreak, spaceEmoticons, useLaTeX; bool emoticonsInChatDlg, emoticonsInEventDlg, emoticonsInGroupChatDlg, emoticonsInPopup, emoticonsInToolTip, emoticonsInRoster; bool raiseChatWindow, showSubjects, showCounter, chatSays, chatSaysMerge, chatSoftReturn, showGroupCounts, showTimeStamps; @@ -320,6 +320,7 @@ QString resolveEntities(const QString &); QString linkify(const QString &, QStringList * linkslist = NULL); QString emoticonify(const QString &in); +QString parseTeX(const QString &in); QString encodePassword(const QString &, const QString &); QString decodePassword(const QString &, const QString &); diff --exclude='*orig' -Naur psi-0.10-orig/src/psicon.cpp psi-0.10/src/psicon.cpp --- psi-0.10-orig/src/psicon.cpp 2006-01-14 23:02:42.000000000 +0000 +++ psi-0.10/src/psicon.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -72,6 +72,8 @@ #include #endif +#include "libTeXFormula.h" + //---------------------------------------------------------------------------- // PsiIconFactory //---------------------------------------------------------------------------- @@ -383,6 +385,7 @@ EDB *edb; OpenPGP::Engine *pgp; bool pgpReady; + bool LaTeXReady; S5BServer *s5bServer; ProxyManager *proxy; IconSelectPopup *iconSelect; @@ -415,6 +418,7 @@ d->pgp = 0; d->pgpReady = false; + d->LaTeXReady = false; d->s5bServer = 0; d->proxy = 0; @@ -551,11 +555,19 @@ d->globalAccelManager->setAccel(option.globalAccels[1]); connect(d->globalAccelManager, SIGNAL(activated(int)), SLOT(accel_activated(int))); + // init libTeXFormula + if (initLibTeXFormula() > 0) + d->LaTeXReady = true; + return true; } void PsiCon::deinit() { + // free libTeXFormula + if (d->LaTeXReady) + freeLibTeXFormula(); + // this deletes all dialogs except for mainwin deleteAllDialogs(); @@ -690,6 +702,11 @@ return 0; } +bool PsiCon::LaTeXReady() const +{ + return d->LaTeXReady; +}; + ProxyManager *PsiCon::proxy() const { return d->proxy; diff --exclude='*orig' -Naur psi-0.10-orig/src/psicon.h psi-0.10/src/psicon.h --- psi-0.10-orig/src/psicon.h 2006-01-14 23:01:32.000000000 +0000 +++ psi-0.10/src/psicon.h 2006-01-14 23:05:33.000000000 +0000 @@ -96,6 +96,7 @@ const PsiAccountList & accountList(bool enabledOnly=FALSE) const; EDB *edb() const; OpenPGP::Engine *pgp() const; + bool LaTeXReady() const; ProxyManager *proxy() const; FileTransDlg *ftdlg() const; diff --exclude='*orig' -Naur psi-0.10-orig/src/psi_profiles.cpp psi-0.10/src/psi_profiles.cpp --- psi-0.10-orig/src/psi_profiles.cpp 2006-01-14 23:01:32.000000000 +0000 +++ psi-0.10/src/psi_profiles.cpp 2006-01-14 23:05:33.000000000 +0000 @@ -397,6 +397,7 @@ prefs.emoticonsInPopup = true; prefs.emoticonsInToolTip = true; prefs.emoticonsInRoster = true; + prefs.useLaTeX = true; prefs.alertOpenChats = false; prefs.raiseChatWindow = false; prefs.showSubjects = true; @@ -894,6 +895,7 @@ p_misc.appendChild(textTag(doc, "emoticonsInPopup", prefs.emoticonsInPopup)); p_misc.appendChild(textTag(doc, "emoticonsInToolTip", prefs.emoticonsInToolTip)); p_misc.appendChild(textTag(doc, "emoticonsInRoster", prefs.emoticonsInRoster)); + p_misc.appendChild(textTag(doc, "useLaTeX", prefs.useLaTeX)); p_misc.appendChild(textTag(doc, "alertOpenChats", prefs.alertOpenChats)); p_misc.appendChild(textTag(doc, "raiseChatWindow", prefs.raiseChatWindow)); p_misc.appendChild(textTag(doc, "showSubjects", prefs.showSubjects)); @@ -1766,6 +1768,7 @@ readBoolEntry(tag, "emoticonsInPopup", &prefs.emoticonsInPopup); readBoolEntry(tag, "emoticonsInToolTip", &prefs.emoticonsInToolTip); readBoolEntry(tag, "emoticonsInRoster", &prefs.emoticonsInRoster); + readBoolEntry(tag, "useLaTeX", &prefs.useLaTeX); readBoolEntry(tag, "alertOpenChats", &prefs.alertOpenChats); readBoolEntry(tag, "raiseChatWindow", &prefs.raiseChatWindow); readBoolEntry(tag, "showSubjects", &prefs.showSubjects);