ghostscript
Advanced tools
| Metadata-Version: 1.1 | ||
| Name: ghostscript | ||
| Version: 0.5.dev0 | ||
| Summary: Interface to the Ghostscript C-API, both high- and low-level, based on ctypes | ||
| Home-page: https://gitlab.com/pdftools/python-ghostscript | ||
| Author: Hartmut Goebel | ||
| Author-email: h.goebel@crazy-compilers.com | ||
| License: GPL 3.0 | ||
| Download-URL: http://pypi.python.org/pypi/ghostscript | ||
| Description-Content-Type: UNKNOWN | ||
| Description: ========================== | ||
| `python-ghostscript` | ||
| ========================== | ||
| --------------------------------------------------------------------- | ||
| Python-Interface to the Ghostscript C-API | ||
| --------------------------------------------------------------------- | ||
| :Author: Hartmut Goebel <h.goebel@crazy-compiler.com> | ||
| :Version: 0.5dev | ||
| :Copyright: GNU Public License v3 (GPLv3) | ||
| :Homepage: https://gitlab.com/pdftools/python-ghostscript | ||
| `Ghostscript`__ is a well known interpreter for the PostScript | ||
| language and for PDF. This package implements a interface to the | ||
| `Ghostscript C-API`__ using `ctypes`__. Both a low-level and a pythonic, | ||
| high-level interface are provided. | ||
| __ http://www.ghostscript.com/ | ||
| __ http://pages.cs.wisc.edu/~ghost/doc/cvs/API.htm | ||
| __ http://docs.python.org/library/ctypes.html | ||
| This package is currently tested only under GNU/Linux. Please report | ||
| whether it works in your environment, too. Thanks. | ||
| Example | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| Here is an example for how to use the high-level interface of | ||
| `python-ghostscript`. This implements a very basic ps2pdf-tool:: | ||
| import sys | ||
| import locale | ||
| import ghostscript | ||
| args = [ | ||
| "ps2pdf", # actual value doesn't matter | ||
| "-dNOPAUSE", "-dBATCH", "-dSAFER", | ||
| "-sDEVICE=pdfwrite", | ||
| "-sOutputFile=" + sys.argv[1], | ||
| "-c", ".setpdfwrite", | ||
| "-f", sys.argv[2] | ||
| ] | ||
| # arguments have to be bytes, encode them | ||
| encoding = locale.getpreferredencoding() | ||
| args = [a.encode(encoding) for a in args] | ||
| ghostscript.Ghostscript(*args) | ||
| Here an example for passing a string document to Ghostscript:: | ||
| doc = b"""%! | ||
| /Helvetica findfont 20 scalefont setfont | ||
| 50 50 moveto | ||
| (Hello World) show | ||
| showpage | ||
| quit | ||
| """ | ||
| import ghostscript | ||
| args = b"""test.py | ||
| -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile=/tmp/out.pdf | ||
| -c .setpdfwrite""".split() | ||
| with ghostscript.Ghostscript(*args) as gs: | ||
| gs.run_string(doc) | ||
| More examples can be found in the `examples` subdirectory of the | ||
| distribution archive. | ||
| Requirements and Installation | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| :Please note: This package is meant for developers. Even if there are | ||
| some usable examples included, installations instructions are meant | ||
| for developers. | ||
| `python-ghostscript` requires | ||
| * `Python`__ 2.7 or higher (tested with Python 2.7 and 3.4) | ||
| * `setuptools`__ for installation (see below) | ||
| * `Ghostscript`__ Version 8.x or higher | ||
| __ http://www.python.org/download/ | ||
| __ http://pypi.python.org/pypi/setuptools | ||
| __ http://www.ghostscript.com/ | ||
| Installing python-ghostscript | ||
| --------------------------------- | ||
| Since this package is meant for developers, we assume you have | ||
| experience in installing Python packages. | ||
| `python-ghostscript` is listed on `PyPI (Python Package Index)`__, so | ||
| you can install it using `pip install ghostscript` as usual. Please | ||
| refer to the manuals of `pip` for further information. | ||
| __ http://pypi.python.org/pypi | ||
| Alternatively you my download and unpack the source package of | ||
| `python-ghostscript` from http://pypi.python.org/pypi/ghostscript and | ||
| run:: | ||
| python ./setup.py install | ||
| .. Emacs config: | ||
| Local Variables: | ||
| mode: rst | ||
| ispell-local-dictionary: "american" | ||
| End: | ||
| Keywords: Ghostscript,PDF,Postscript | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 4 - Beta | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: GNU General Public License (GPL) | ||
| Classifier: Natural Language :: English | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 2.7 | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules |
| CHANGES.txt | ||
| COPYING | ||
| MANIFEST.in | ||
| README.rst | ||
| SConstruct | ||
| projectlogo.svg | ||
| setup.cfg | ||
| setup.py | ||
| examples/gs.py | ||
| examples/lowlevel1.py | ||
| examples/lowlevel2.py | ||
| examples/lowlevel3.py | ||
| examples/ps2pdf.py | ||
| examples/run-string.bat | ||
| examples/run-string.py | ||
| examples/test-gs.sh | ||
| examples/test-lowlevel2.sh | ||
| examples/test-lowlevel3.sh | ||
| examples/test-ps2pdf.sh | ||
| examples/test.ps | ||
| ghostscript/__init__.py | ||
| ghostscript/_errors.py | ||
| ghostscript/_gsprint.py | ||
| ghostscript.egg-info/PKG-INFO | ||
| ghostscript.egg-info/SOURCES.txt | ||
| ghostscript.egg-info/dependency_links.txt | ||
| ghostscript.egg-info/requires.txt | ||
| ghostscript.egg-info/top_level.txt | ||
| ghostscript.egg-info/zip-safe | ||
| test/test_highlevel.py | ||
| test/test_lowlevel.py |
Sorry, the diff of this file is not supported yet
| #!/usr/bin/env python | ||
| # -*- coding: utf-8 -*- | ||
| """ | ||
| ghostscript - A Python interface for the Ghostscript interpreter C-API | ||
| """ | ||
| # | ||
| # Copyright 2010-2016 by Hartmut Goebel <h.goebel@crazy-compilers.com> | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| from __future__ import absolute_import | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2016 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| __version__ = "0.5dev" | ||
| __all__ = ['Ghostscript', 'revision', | ||
| 'GhostscriptError', 'PleaseDisplayUsage'] | ||
| import atexit | ||
| import sys # :todo: remove, debugging only | ||
| from . import _gsprint as gs | ||
| GhostscriptError = gs.GhostscriptError | ||
| def PleaseDisplayUsage(Warning): | ||
| """ | ||
| This exception is raised when Ghostscript asks the application to | ||
| display the usage. The application should catch the exception an | ||
| print the usage message. | ||
| """ | ||
| pass | ||
| def revision(): | ||
| """ | ||
| This function returns the revision numbers and strings of the | ||
| Ghostscript interpreter library as a dict. You should call it | ||
| before any other interpreter library functions to make sure that | ||
| the correct version of the Ghostscript interpreter has been | ||
| loaded. | ||
| """ | ||
| rev = gs.revision() | ||
| return dict((f, getattr(rev, f)) for f, _ in rev._fields_) | ||
| MAX_STRING_LENGTH = gs.MAX_STRING_LENGTH | ||
| class Ghostscript(object): | ||
| @staticmethod | ||
| def revision(): | ||
| return revision() | ||
| def __init__(self, instance, args, stdin=None, stdout=None, stderr=None): | ||
| self._initialized = False | ||
| self._instance = instance | ||
| self._callbacks = None | ||
| if stdin or stdout or stderr: | ||
| self.set_stdio(stdin, stdout, stderr) | ||
| rc = gs.init_with_args(instance, args) | ||
| if rc == gs.e_Info: | ||
| raise PleaseDisplayUsage | ||
| self._initialized = True | ||
| if rc == gs.e_Quit: | ||
| self.exit() | ||
| def __enter__(self): | ||
| return self | ||
| def __exit__(self, *args): | ||
| self.exit() | ||
| def set_stdio(self, stdin=None, stdout=None, stderr=None): | ||
| """Set stdin, stdout and stderr of the ghostscript interpreter. | ||
| The ``stdin`` stream has to support the ``readline()`` | ||
| interface. The ``stdout`` and ``stderr`` streams have to | ||
| support the ``write()`` and ``flush()`` interface. | ||
| Please note that this does not affect the input- and output- | ||
| streams of the devices. Esp. setting stdout does not allow | ||
| catching the devise-output even when using ``-sOutputFile=-``. | ||
| """ | ||
| self._callbacks = ( | ||
| stdin and gs._wrap_stdin(stdin) or None, | ||
| stdout and gs._wrap_stdout(stdout) or None, | ||
| stderr and gs._wrap_stderr(stderr) or None, | ||
| ) | ||
| gs.set_stdio(self._instance, *self._callbacks) | ||
| def __del__(self): | ||
| self.exit() | ||
| def exit(self): | ||
| global __instance__ | ||
| if self._initialized: | ||
| if __instance__: | ||
| #gs.exit(self._instance) | ||
| self._instance = None | ||
| self._initialized = False | ||
| def run_string(self, str, user_errors=False): | ||
| """ | ||
| Run the string ``str`` by Ghostscript | ||
| This takes care of Ghostscripts size-limitations and passes | ||
| the string in pieces if necessary. | ||
| """ | ||
| instance = self._instance | ||
| if len(str) < MAX_STRING_LENGTH: | ||
| gs.run_string(instance, str) | ||
| else: | ||
| gs.run_string_begin(instance) | ||
| for start in range(0, len(str), MAX_STRING_LENGTH): | ||
| gs.run_string_continue(instance, | ||
| str[start:start+MAX_STRING_LENGTH]) | ||
| gs.run_string_end(instance) | ||
| def run_filename(self, filename, user_errors=False): | ||
| """ | ||
| Run the file named by ``filename`` by Ghostscript | ||
| """ | ||
| return gs.run_file(self._instance, filename, user_errors) | ||
| def run_file(self, file, user_errors=False): | ||
| """ | ||
| Read ``file`` and run the content by Ghostscript. | ||
| ``file`` must already by opened and may by any file-like | ||
| object supporting the ``read()`` method. | ||
| """ | ||
| instance = self._instance | ||
| gs.run_string_begin(instance) | ||
| while True: | ||
| str = file.read(MAX_STRING_LENGTH) | ||
| if not str: | ||
| break | ||
| gs.run_string_continue(instance, str) | ||
| gs.run_string_end(instance) | ||
| __Ghostscript = Ghostscript | ||
| __instance__ = None | ||
| def Ghostscript(*args, **kw): | ||
| """ | ||
| Factory function for setting up a Ghostscript instance | ||
| """ | ||
| global __instance__, __object_count__ | ||
| # Ghostscript only supports a single instance | ||
| if __instance__ is None: | ||
| __instance__ = gs.new_instance() | ||
| return __Ghostscript(__instance__, args, | ||
| stdin=kw.get('stdin', None), | ||
| stdout=kw.get('stdout', None), | ||
| stderr=kw.get('stderr', None)) | ||
| def cleanup(): | ||
| global __instance__ | ||
| if __instance__ is not None: | ||
| gs.delete_instance(__instance__) | ||
| __instance__ = None | ||
| #atexit.register(cleanup) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
| """ | ||
| Definition of Ghostscript error codes | ||
| """ | ||
| # | ||
| # Copyright (C) 2010-2016 by Hartmut Goebel | ||
| # | ||
| # Based on iapi.h which is | ||
| # Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved. | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2016 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| # | ||
| # A procedure that may return an error always returns | ||
| # a non-negative value (zero, unless otherwise noted) for success, | ||
| # or negative for failure. | ||
| # We use ints rather than an enum to avoid a lot of casting. | ||
| # | ||
| # ------ PostScript Level 1 errors ------ | ||
| e_unknownerror = -1 # unknown error | ||
| e_dictfull = -2 | ||
| e_dictstackoverflow = -3 | ||
| e_dictstackunderflow = -4 | ||
| e_execstackoverflow = -5 | ||
| e_interrupt = -6 | ||
| # We also need to define gs_error_interrupt, for gpcheck.h | ||
| gs_error_interrupt = e_interrupt | ||
| e_invalidaccess = -7 | ||
| e_invalidexit = -8 | ||
| e_invalidfileaccess = -9 | ||
| e_invalidfont = -10 | ||
| e_invalidrestore = -11 | ||
| e_ioerror = -12 | ||
| e_limitcheck = -13 | ||
| e_nocurrentpoint = -14 | ||
| e_rangecheck = -15 | ||
| e_stackoverflow = -16 | ||
| e_stackunderflow = -17 | ||
| e_syntaxerror = -18 | ||
| e_timeout = -19 | ||
| e_typecheck = -20 | ||
| e_undefined = -21 | ||
| e_undefinedfilename = -22 | ||
| e_undefinedresult = -23 | ||
| e_unmatchedmark = -24 | ||
| e_VMerror = -25 | ||
| LEVEL1_ERROR_NAMES = ["unknownerror", "dictfull", "dictstackoverflow", | ||
| "dictstackunderflow", "execstackoverflow", | ||
| "interrupt", "invalidaccess", "invalidexit", | ||
| "invalidfileaccess", "invalidfont", | ||
| "invalidrestore", "ioerror", "limitcheck", | ||
| "nocurrentpoint", "rangecheck", "stackoverflow", | ||
| "stackunderflow", "syntaxerror", "timeout", | ||
| "typecheck", "undefined", "undefinedfilename", | ||
| "undefinedresult", "unmatchedmark", "VMerror"] | ||
| # ------ Additional Level 2 and DPS errors ------ | ||
| e_configurationerror = -26 | ||
| e_invalidcontext = -27 | ||
| e_undefinedresource = -28 | ||
| e_unregistered = -29 | ||
| # invalidid is for the NeXT DPS extension. | ||
| e_invalidid = -30 | ||
| LEVEL2_ERROR_NAMES = ["configurationerror", "invalidcontext", | ||
| "undefinedresource", "unregistered", | ||
| "invalidid"] | ||
| ERROR_NAMES = LEVEL1_ERROR_NAMES + LEVEL2_ERROR_NAMES | ||
| _PSEUDO_ERRORS = ['Fatal', 'Quit', 'InterpreterExit', 'RemapColor', | ||
| 'ExecStackUnderflow', 'VMreclaim', 'NeedInput', | ||
| 'NeedStdin', 'NeedStdout', 'NeedStderr', 'Info'] | ||
| def error2name(ecode): | ||
| if ecode <= e_Fatal: | ||
| return _PSEUDO_ERRORS[-ecode-100] | ||
| else: | ||
| return ERROR_NAMES[-ecode-1] | ||
| # ------ Pseudo-errors used internally ------ | ||
| # | ||
| # Internal code for a fatal error. | ||
| # gs_interpret also returns this for a .quit with a positive exit code. | ||
| # | ||
| e_Fatal = -100 | ||
| # | ||
| # Internal code for the .quit operator. | ||
| # The real quit code is an integer on the operand stack. | ||
| # gs_interpret returns this only for a .quit with a zero exit code. | ||
| # | ||
| e_Quit = -101 | ||
| # | ||
| # Internal code for a normal exit from the interpreter. | ||
| # Do not use outside of interp.c. | ||
| # | ||
| e_InterpreterExit = -102 | ||
| # | ||
| # Internal code that indicates that a procedure has been stored in the | ||
| # remap_proc of the graphics state, and should be called before retrying | ||
| # the current token. This is used for color remapping involving a call | ||
| # back into the interpreter -- inelegant, but effective. | ||
| # | ||
| e_RemapColor = -103 | ||
| # | ||
| # Internal code to indicate we have underflowed the top block | ||
| # of the e-stack. | ||
| # | ||
| e_ExecStackUnderflow = -104 | ||
| # | ||
| # Internal code for the vmreclaim operator with a positive operand. | ||
| # We need to handle this as an error because otherwise the interpreter | ||
| # won't reload enough of its state when the operator returns. | ||
| # | ||
| e_VMreclaim = -105 | ||
| # | ||
| # Internal code for requesting more input from run_string. | ||
| # | ||
| e_NeedInput = -106 | ||
| # | ||
| # Internal code for stdin callout. | ||
| # | ||
| e_NeedStdin = -107 | ||
| # | ||
| # Internal code for stdout callout. | ||
| # | ||
| e_NeedStdout = -108 | ||
| # | ||
| # Internal code for stderr callout. | ||
| # | ||
| e_NeedStderr = -109 | ||
| # | ||
| # Internal code for a normal exit when usage info is displayed. | ||
| # This allows Window versions of Ghostscript to pause until | ||
| # the message can be read. | ||
| # | ||
| e_Info = -110 | ||
| # | ||
| # Define which error codes require re-executing the current object. | ||
| # | ||
| def ERROR_IS_INTERRUPT(ecode): | ||
| return ecode == e_interrupt or ecode == e_timeout | ||
| if __name__ == '__main__': | ||
| print(error2name(e_unknownerror) == "unknownerror") | ||
| print(error2name(e_VMerror) == "VMerror") | ||
| print(error2name(e_invalidid) == "invalidid") | ||
| print(error2name(e_VMreclaim) == "VMreclaim") |
| #!/usr/bin/env python | ||
| # -*- coding: utf-8 -*- | ||
| """ | ||
| ghostscript._gsprint - A low-lewel interface to the Ghostscript C-API using ctypes | ||
| """ | ||
| # | ||
| # Copyright 2010-2016 by Hartmut Goebel <h.goebel@crazy-compilers.com> | ||
| # | ||
| # Display_callback Structure by Lasse Fister <commander@graphicore.de> in 2013 | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| from __future__ import absolute_import | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2016 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| __version__ = "0.5dev" | ||
| from ctypes import * | ||
| import sys | ||
| from ._errors import * | ||
| MAX_STRING_LENGTH = 65535 | ||
| DISPLAY_VERSION_MAJOR = 2 | ||
| DISPLAY_VERSION_MINOR = 0 | ||
| DISPLAY_VERSION_MAJOR_V1 = 1 # before separation format was added | ||
| DISPLAY_VERSION_MINOR_V1 = 0 | ||
| # The display format is set by a combination of the following bitfields | ||
| # Define the color space alternatives | ||
| # DISPLAY_FORMAT_COLOR | ||
| DISPLAY_COLORS_NATIVE = (1<<0) | ||
| DISPLAY_COLORS_GRAY = (1<<1) | ||
| DISPLAY_COLORS_RGB = (1<<2) | ||
| DISPLAY_COLORS_CMYK = (1<<3) | ||
| DISPLAY_COLORS_SEPARATION = (1<<19) | ||
| DISPLAY_COLORS_MASK = 0x8000f | ||
| # Define whether alpha information, or an extra unused bytes is included | ||
| # DISPLAY_ALPHA_FIRST and DISPLAY_ALPHA_LAST are not implemented | ||
| # DISPLAY_FORMAT_ALPHA | ||
| 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_ALPHA_MASK = 0x00f0 | ||
| # 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. | ||
| # DISPLAY_FORMAT_DEPTH | ||
| 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_DEPTH_MASK = 0xff00 | ||
| # Define whether Red/Cyan should come first, | ||
| # or whether Blue/Black should come first | ||
| # DISPLAY_FORMAT_ENDIAN | ||
| DISPLAY_BIGENDIAN = (0<<16) # Red/Cyan first | ||
| DISPLAY_LITTLEENDIAN = (1<<16) # Blue/Black first | ||
| DISPLAY_ENDIAN_MASK = 0x00010000 | ||
| # Define whether the raster starts at the top or bottom of the bitmap | ||
| # DISPLAY_FORMAT_FIRSTROW | ||
| DISPLAY_TOPFIRST = (0<<17) # Unix, Mac | ||
| DISPLAY_BOTTOMFIRST = (1<<17) # Windows | ||
| DISPLAY_FIRSTROW_MASK = 0x00020000 | ||
| # Define whether packing RGB in 16-bits should use 555 | ||
| # or 565 (extra bit for green) | ||
| # DISPLAY_FORMAT_555 | ||
| DISPLAY_NATIVE_555 = (0<<18) | ||
| DISPLAY_NATIVE_565 = (1<<18) | ||
| DISPLAY_555_MASK = 0x00040000 | ||
| # Define the row alignment, which must be equal to or greater than | ||
| # the size of a pointer. | ||
| # The default (DISPLAY_ROW_ALIGN_DEFAULT) is the size of a pointer, | ||
| # 4 bytes (DISPLAY_ROW_ALIGN_4) on 32-bit systems or 8 bytes | ||
| # (DISPLAY_ROW_ALIGN_8) on 64-bit systems. | ||
| # DISPLAY_FORMAT_ROW_ALIGN | ||
| DISPLAY_ROW_ALIGN_DEFAULT = (0<<20) | ||
| # DISPLAY_ROW_ALIGN_1 = (1<<20), # not currently possible | ||
| # DISPLAY_ROW_ALIGN_2 = (2<<20), # not currently possible | ||
| DISPLAY_ROW_ALIGN_4 = (3<<20) | ||
| DISPLAY_ROW_ALIGN_8 = (4<<20) | ||
| DISPLAY_ROW_ALIGN_16 = (5<<20) | ||
| DISPLAY_ROW_ALIGN_32 = (6<<20) | ||
| DISPLAY_ROW_ALIGN_64 = (7<<20) | ||
| DISPLAY_ROW_ALIGN_MASK = 0x00700000 | ||
| class Revision(Structure): | ||
| _fields_ = [ | ||
| ("product", c_char_p), | ||
| ("copyright", c_char_p), | ||
| ("revision", c_long), | ||
| ("revisiondate", c_long) | ||
| ] | ||
| gs_main_instance = c_void_p | ||
| display_callback = c_void_p | ||
| class GhostscriptError(Exception): | ||
| def __init__(self, ecode): | ||
| # :todo: | ||
| Exception.__init__(self, error2name(ecode)) | ||
| self.code = ecode | ||
| def revision(): | ||
| """ | ||
| 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. | ||
| Returns a Revision instance | ||
| """ | ||
| revision = Revision() | ||
| rc = libgs.gsapi_revision(pointer(revision), sizeof(revision)) | ||
| if rc: | ||
| raise ArgumentError("Revision structure size is incorrect, " | ||
| "requires %s bytes" % rc) | ||
| return revision | ||
| def new_instance(): # display_callback=None): | ||
| """ | ||
| Create a new instance of Ghostscript | ||
| This instance is passed to most other API functions. | ||
| """ | ||
| # :todo: The caller_handle will be provided to callback functions. | ||
| display_callback=None | ||
| instance = gs_main_instance() | ||
| rc = libgs.gsapi_new_instance(pointer(instance), display_callback) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return instance | ||
| def delete_instance(instance): | ||
| """ | ||
| Destroy an instance of Ghostscript | ||
| Before you call this, Ghostscript must have finished. | ||
| If Ghostscript has been initialised, you must call exit() | ||
| before delete_instance() | ||
| """ | ||
| return libgs.gsapi_delete_instance(instance) | ||
| c_stdstream_call_t = CFUNCTYPE(c_int, gs_main_instance, POINTER(c_char), c_int) | ||
| def _wrap_stdin(infp): | ||
| """ | ||
| Wrap a filehandle into a C function to be used as `stdin` callback | ||
| for ``set_stdio``. The filehandle has to support the readline() method. | ||
| """ | ||
| def _wrap(instance, dest, count): | ||
| try: | ||
| data = infp.readline(count) | ||
| except: | ||
| count = -1 | ||
| else: | ||
| if not data: | ||
| count = 0 | ||
| else: | ||
| count = len(data) | ||
| memmove(dest, c_char_p(data), count) | ||
| return count | ||
| return c_stdstream_call_t(_wrap) | ||
| def _wrap_stdout(outfp): | ||
| """ | ||
| Wrap a filehandle into a C function to be used as `stdout` or | ||
| `stderr` callback for ``set_stdio``. The filehandle has to support the | ||
| write() and flush() methods. | ||
| """ | ||
| def _wrap(instance, str, count): | ||
| outfp.write(str[:count]) | ||
| outfp.flush() | ||
| return count | ||
| return c_stdstream_call_t(_wrap) | ||
| _wrap_stderr = _wrap_stdout | ||
| def set_stdio(instance, stdin, stdout, stderr): | ||
| """ | ||
| Set the callback functions for stdio. | ||
| ``stdin``, ``stdout`` and ``stderr`` have to be ``ctypes`` | ||
| callback functions matching the ``_gsprint.c_stdstream_call_t`` | ||
| prototype. You may want to use _wrap_* to wrap file handles. | ||
| Note 1: This function only changes stdio of the Postscript | ||
| interpreter, not that of the devices. | ||
| Note 2: Make sure you keep references to C function objects | ||
| as long as they are used from C code. Otherwise they may be | ||
| garbage collected, crashing your program when a callback is made. | ||
| 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. | ||
| You may pass ``None`` for any of stdin, stdout or stderr , in which | ||
| case the system stdin, stdout resp. stderr will be used. | ||
| """ | ||
| rc = libgs.gsapi_set_stdio(instance, stdin, stdout, stderr) | ||
| if rc not in (0, e_Quit, e_Info): | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| # :todo: set_poll (instance, int(*poll_fn)(void *caller_handle)); | ||
| # :todo: set_display_callback(instance, callback): | ||
| def init_with_args(instance, argv): | ||
| """ | ||
| Initialise the interpreter. | ||
| 1. If quit or EOF occur during init_with_args(), the return value | ||
| will be e_Quit. This is not an error. You must call exit() and | ||
| must not call any other functions. | ||
| 2. If usage info should be displayed, the return value will be | ||
| e_Info which is not an error. Do not call exit(). | ||
| 3. Under normal conditions this returns 0. You would then call one | ||
| or more run_*() functions and then finish with exit() | ||
| """ | ||
| ArgArray = c_char_p * len(argv) | ||
| c_argv = ArgArray(*argv) | ||
| rc = libgs.gsapi_init_with_args(instance, len(argv), c_argv) | ||
| if rc not in (0, e_Quit, e_Info): | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def exit(instance): | ||
| """ | ||
| Exit the interpreter | ||
| This must be called on shutdown if init_with_args() has been | ||
| called, and just before delete_instance() | ||
| """ | ||
| rc = libgs.gsapi_exit(instance) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def run_string_begin(instance, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_begin(instance, c_int(user_errors), | ||
| pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_continue(instance, str, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_continue( | ||
| instance, c_char_p(str), c_int(len(str)), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != e_NeedInput and rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_end(instance, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_end(instance, c_int(user_errors), | ||
| pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_with_length(*args, **kw): | ||
| raise NotImpelmentedError('Use run_string() instead') | ||
| def run_string(instance, str, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_with_length( | ||
| instance, c_char_p(str), c_int(len(str)), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_file(instance, filename, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_file(instance, c_char_p(filename), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def set_visual_tracer(I): | ||
| raise NotImplementedError | ||
| # New device has been opened | ||
| # This is the first event from this device. | ||
| # int (*display_open)(void *handle, void *device); | ||
| c_display_open = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # Device is about to be closed. | ||
| # Device will not be closed until this function returns. | ||
| #int (*display_preclose)(void *handle, void *device); | ||
| c_display_preclose = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # Device has been closed. | ||
| # This is the last event from this device. | ||
| # int (*display_close)(void *handle, void *device); | ||
| c_display_close = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # 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); | ||
| c_display_presize = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_uint) | ||
| # 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); | ||
| c_display_size = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_uint, POINTER(c_ubyte)) | ||
| # flushpage | ||
| #int (*display_sync)(void *handle, void *device); | ||
| c_display_sync = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # showpage | ||
| # If you want to pause on showpage, then don't return immediately | ||
| # int (*display_page)(void *handle, void *device, int copies, int flush); | ||
| c_display_page = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int) | ||
| # 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); | ||
| c_display_update = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_int) | ||
| # 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); | ||
| c_display_memalloc = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_ulong) | ||
| # 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); | ||
| c_display_memfree = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) | ||
| # Added in V2 */ | ||
| # When using separation color space (DISPLAY_COLORS_SEPARATION), | ||
| # give a mapping for one separation component. | ||
| # This is called for each new component found. | ||
| # It may be called multiple times for each component. | ||
| # It may be called at any time between display_size | ||
| # and display_close. | ||
| # The client uses this to map from the separations to CMYK | ||
| # and hence to RGB for display. | ||
| # GS must only use this callback if version_major >= 2. | ||
| # The unsigned short c,m,y,k values are 65535 = 1.0. | ||
| # This function pointer may be set to NULL if not required. | ||
| # | ||
| # int (*display_separation)(void *handle, void *device, | ||
| # int component, const char *component_name, | ||
| # unsigned short c, unsigned short m, | ||
| # unsigned short y, unsigned short k); | ||
| c_display_separation = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_char_p, c_ushort, c_ushort, c_ushort, c_ushort) | ||
| class Display_callback_s (Structure): | ||
| _fields_ = [ | ||
| # Size of this structure | ||
| # Used for checking if we have been handed a valid structure | ||
| # int size; | ||
| ("size", c_int), | ||
| # Major version of this structure | ||
| # The major version number will change if this structure changes. | ||
| # int version_major; | ||
| ("version_major", c_int), | ||
| # 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; | ||
| ("version_minor", c_int), | ||
| ("display_open", c_display_open), | ||
| ("display_preclose", c_display_preclose), | ||
| ("display_close", c_display_close), | ||
| ("display_presize", c_display_presize), | ||
| ("display_size", c_display_size), | ||
| ("display_sync", c_display_sync), | ||
| ("display_page", c_display_page), | ||
| ("display_update", c_display_update), | ||
| ("display_memalloc", c_display_memalloc), | ||
| ("display_memfree", c_display_memfree), | ||
| ("display_separation", c_display_separation) | ||
| ] | ||
| def set_display_callback(instance, callback): | ||
| rc = libgs.gsapi_set_display_callback(instance, callback) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def __win32_finddll(): | ||
| try: | ||
| import winreg | ||
| except ImportError: | ||
| # assume Python 2 | ||
| from _winreg import OpenKey, CloseKey, EnumKey, QueryValueEx, \ | ||
| QueryInfoKey, HKEY_LOCAL_MACHINE | ||
| else: | ||
| from winreg import OpenKey, CloseKey, EnumKey, QueryValueEx, \ | ||
| QueryInfoKey, HKEY_LOCAL_MACHINE | ||
| from distutils.version import LooseVersion | ||
| import os | ||
| dlls = [] | ||
| # Look up different variants of Ghostscript and take the highest | ||
| # version for which the DLL is to be found in the filesystem. | ||
| for key_name in ('AFPL Ghostscript', 'Aladdin Ghostscript', | ||
| 'GPL Ghostscript', 'GNU Ghostscript'): | ||
| try: | ||
| k1 = OpenKey(HKEY_LOCAL_MACHINE, "Software\\%s" % key_name) | ||
| for num in range(0, QueryInfoKey(k1)[0]): | ||
| version = EnumKey(k1, num) | ||
| try: | ||
| k2 = OpenKey(k1, version) | ||
| dll_path = QueryValueEx(k2, 'GS_DLL')[0] | ||
| CloseKey(k2) | ||
| if os.path.exists(dll_path): | ||
| dlls.append((LooseVersion(version), dll_path)) | ||
| except WindowsError: | ||
| pass | ||
| CloseKey(k1) | ||
| except WindowsError: | ||
| pass | ||
| if dlls: | ||
| dlls.sort() | ||
| return dlls[-1][-1] | ||
| else: | ||
| return None | ||
| if sys.platform == 'win32': | ||
| libgs = __win32_finddll() | ||
| if not libgs: | ||
| raise RuntimeError('Can not find Ghostscript DLL in registry') | ||
| libgs = windll.LoadLibrary(libgs) | ||
| else: | ||
| try: | ||
| libgs = cdll.LoadLibrary("libgs.so") | ||
| except OSError: | ||
| # shared object file not found | ||
| import ctypes.util | ||
| libgs = ctypes.util.find_library('gs') | ||
| if not libgs: | ||
| raise RuntimeError('Can not find Ghostscript library (libgs)') | ||
| libgs = cdll.LoadLibrary(libgs) | ||
| del __win32_finddll |
| ========================== | ||
| `python-ghostscript` | ||
| ========================== | ||
| --------------------------------------------------------------------- | ||
| Python-Interface to the Ghostscript C-API | ||
| --------------------------------------------------------------------- | ||
| :Author: Hartmut Goebel <h.goebel@crazy-compiler.com> | ||
| :Version: 0.6 | ||
| :License: GNU Public License v3 (GPLv3) | ||
| :Homepage: https://gitlab.com/pdftools/python-ghostscript | ||
| `Ghostscript`__ is a well known interpreter for the PostScript | ||
| language and for PDF. This package implements a interface to the | ||
| `Ghostscript C-API`__ using `ctypes`__. Both a low-level and a pythonic, | ||
| high-level interface are provided. | ||
| __ http://www.ghostscript.com/ | ||
| __ http://pages.cs.wisc.edu/~ghost/doc/cvs/API.htm | ||
| __ http://docs.python.org/library/ctypes.html | ||
| This package is currently tested only under GNU/Linux. Please report | ||
| whether it works in your environment, too. Thanks. | ||
| Example | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| Here is an example for how to use the high-level interface of | ||
| `python-ghostscript`. This implements a very basic ps2pdf-tool:: | ||
| import sys | ||
| import locale | ||
| import ghostscript | ||
| args = [ | ||
| "ps2pdf", # actual value doesn't matter | ||
| "-dNOPAUSE", "-dBATCH", "-dSAFER", | ||
| "-sDEVICE=pdfwrite", | ||
| "-sOutputFile=" + sys.argv[1], | ||
| "-c", ".setpdfwrite", | ||
| "-f", sys.argv[2] | ||
| ] | ||
| # arguments have to be bytes, encode them | ||
| encoding = locale.getpreferredencoding() | ||
| args = [a.encode(encoding) for a in args] | ||
| ghostscript.Ghostscript(*args) | ||
| Here an example for passing a string document to Ghostscript:: | ||
| doc = b"""%! | ||
| /Helvetica findfont 20 scalefont setfont | ||
| 50 50 moveto | ||
| (Hello World) show | ||
| showpage | ||
| quit | ||
| """ | ||
| import ghostscript | ||
| args = b"""test.py | ||
| -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile=/tmp/out.pdf | ||
| -c .setpdfwrite""".split() | ||
| with ghostscript.Ghostscript(*args) as gs: | ||
| gs.run_string(doc) | ||
| More examples can be found in the `examples` subdirectory of the | ||
| distribution archive. | ||
| Requirements and Installation | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| :Please note: This package is meant for developers. Even if there are | ||
| some usable examples included, installations instructions are meant | ||
| for developers. | ||
| `python-ghostscript` requires | ||
| * `Python`__ 2.7 or higher (tested with Python 2.7, 3.4, 3.6 and 3.6) | ||
| * `setuptools`__ for installation (see below) | ||
| * `Ghostscript`__ Version 8.x or higher (tested with 9.x) | ||
| __ http://www.python.org/download/ | ||
| __ http://pypi.python.org/pypi/setuptools | ||
| __ http://www.ghostscript.com/ | ||
| Installing python-ghostscript | ||
| --------------------------------- | ||
| Since this package is meant for developers, we assume you have | ||
| experience in installing Python packages. | ||
| `python-ghostscript` is listed on `PyPI (Python Package Index)`__, so | ||
| you can install it using `pip install ghostscript` as usual. Please | ||
| refer to the manuals of `pip` for further information. | ||
| __ http://pypi.python.org/pypi | ||
| Alternatively you my download and unpack the source package of | ||
| `python-ghostscript` from http://pypi.python.org/pypi/ghostscript and | ||
| run:: | ||
| python ./setup.py install | ||
| .. Emacs config: | ||
| Local Variables: | ||
| mode: rst | ||
| ispell-local-dictionary: "american" | ||
| End: | ||
| Metadata-Version: 2.0 | ||
| Name: ghostscript | ||
| Version: 0.6 | ||
| Summary: Interface to the Ghostscript C-API, both high- and low-level, based on ctypes | ||
| Home-page: https://gitlab.com/pdftools/python-ghostscript | ||
| Author: Hartmut Goebel | ||
| Author-email: h.goebel@crazy-compilers.com | ||
| License: GPL 3.0 | ||
| Download-URL: http://pypi.python.org/pypi/ghostscript | ||
| Description-Content-Type: UNKNOWN | ||
| Keywords: Ghostscript,PDF,Postscript | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 4 - Beta | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: GNU General Public License (GPL) | ||
| Classifier: Natural Language :: English | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 2.7 | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Requires-Dist: setuptools | ||
| ========================== | ||
| `python-ghostscript` | ||
| ========================== | ||
| --------------------------------------------------------------------- | ||
| Python-Interface to the Ghostscript C-API | ||
| --------------------------------------------------------------------- | ||
| :Author: Hartmut Goebel <h.goebel@crazy-compiler.com> | ||
| :Version: 0.6 | ||
| :License: GNU Public License v3 (GPLv3) | ||
| :Homepage: https://gitlab.com/pdftools/python-ghostscript | ||
| `Ghostscript`__ is a well known interpreter for the PostScript | ||
| language and for PDF. This package implements a interface to the | ||
| `Ghostscript C-API`__ using `ctypes`__. Both a low-level and a pythonic, | ||
| high-level interface are provided. | ||
| __ http://www.ghostscript.com/ | ||
| __ http://pages.cs.wisc.edu/~ghost/doc/cvs/API.htm | ||
| __ http://docs.python.org/library/ctypes.html | ||
| This package is currently tested only under GNU/Linux. Please report | ||
| whether it works in your environment, too. Thanks. | ||
| Example | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| Here is an example for how to use the high-level interface of | ||
| `python-ghostscript`. This implements a very basic ps2pdf-tool:: | ||
| import sys | ||
| import locale | ||
| import ghostscript | ||
| args = [ | ||
| "ps2pdf", # actual value doesn't matter | ||
| "-dNOPAUSE", "-dBATCH", "-dSAFER", | ||
| "-sDEVICE=pdfwrite", | ||
| "-sOutputFile=" + sys.argv[1], | ||
| "-c", ".setpdfwrite", | ||
| "-f", sys.argv[2] | ||
| ] | ||
| # arguments have to be bytes, encode them | ||
| encoding = locale.getpreferredencoding() | ||
| args = [a.encode(encoding) for a in args] | ||
| ghostscript.Ghostscript(*args) | ||
| Here an example for passing a string document to Ghostscript:: | ||
| doc = b"""%! | ||
| /Helvetica findfont 20 scalefont setfont | ||
| 50 50 moveto | ||
| (Hello World) show | ||
| showpage | ||
| quit | ||
| """ | ||
| import ghostscript | ||
| args = b"""test.py | ||
| -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile=/tmp/out.pdf | ||
| -c .setpdfwrite""".split() | ||
| with ghostscript.Ghostscript(*args) as gs: | ||
| gs.run_string(doc) | ||
| More examples can be found in the `examples` subdirectory of the | ||
| distribution archive. | ||
| Requirements and Installation | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| :Please note: This package is meant for developers. Even if there are | ||
| some usable examples included, installations instructions are meant | ||
| for developers. | ||
| `python-ghostscript` requires | ||
| * `Python`__ 2.7 or higher (tested with Python 2.7, 3.4, 3.6 and 3.6) | ||
| * `setuptools`__ for installation (see below) | ||
| * `Ghostscript`__ Version 8.x or higher (tested with 9.x) | ||
| __ http://www.python.org/download/ | ||
| __ http://pypi.python.org/pypi/setuptools | ||
| __ http://www.ghostscript.com/ | ||
| Installing python-ghostscript | ||
| --------------------------------- | ||
| Since this package is meant for developers, we assume you have | ||
| experience in installing Python packages. | ||
| `python-ghostscript` is listed on `PyPI (Python Package Index)`__, so | ||
| you can install it using `pip install ghostscript` as usual. Please | ||
| refer to the manuals of `pip` for further information. | ||
| __ http://pypi.python.org/pypi | ||
| Alternatively you my download and unpack the source package of | ||
| `python-ghostscript` from http://pypi.python.org/pypi/ghostscript and | ||
| run:: | ||
| python ./setup.py install | ||
| .. Emacs config: | ||
| Local Variables: | ||
| mode: rst | ||
| ispell-local-dictionary: "american" | ||
| End: | ||
| {"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules"], "description_content_type": "UNKNOWN", "download_url": "http://pypi.python.org/pypi/ghostscript", "extensions": {"python.details": {"contacts": [{"email": "h.goebel@crazy-compilers.com", "name": "Hartmut Goebel", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://gitlab.com/pdftools/python-ghostscript"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "keywords": ["Ghostscript", "PDF", "Postscript"], "license": "GPL 3.0", "metadata_version": "2.0", "name": "ghostscript", "run_requires": [{"requires": ["setuptools"]}], "summary": "Interface to the Ghostscript C-API, both high- and low-level, based on ctypes", "version": "0.6"} |
| ghostscript/__init__.py,sha256=zlTi8OkNklYmB0yJLmgULcEpNepeKJj3Jj1huX6UHAE,5812 | ||
| ghostscript/_errors.py,sha256=L4imjH7bO6YKfd6pieKhpsZYguvNkQRb9kx4BSRQBr8,5234 | ||
| ghostscript/_gsprint.py,sha256=eImia_TYeNExLABPNaL4DBv_611WJ2UL1n9TovzfD2U,17218 | ||
| ghostscript-0.6.dist-info/DESCRIPTION.rst,sha256=YQdIIkfTBERuUO1GWDeL7tf_PGYoYPs-dPnN3ouaaCA,3232 | ||
| ghostscript-0.6.dist-info/METADATA,sha256=WTfOq_9p3e8Qml-oJz17-DT5GUQBCHH6vgas66ZTZDo,4143 | ||
| ghostscript-0.6.dist-info/RECORD,, | ||
| ghostscript-0.6.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 | ||
| ghostscript-0.6.dist-info/metadata.json,sha256=UR4KJZ6Cmcbca0OgPgYNRGoBl6yVaxOq_vLmEO_uQFE,1092 | ||
| ghostscript-0.6.dist-info/top_level.txt,sha256=4oyhegeuLGZzu0jStqsvTLDipfr3KtKTqUbmgMT46H8,12 | ||
| ghostscript-0.6.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 |
| ghostscript |
| Wheel-Version: 1.0 | ||
| Generator: bdist_wheel (0.30.0) | ||
| Root-Is-Purelib: true | ||
| Tag: py2-none-any | ||
| Tag: py3-none-any | ||
Sorry, the diff of this file is not supported yet
| #!/usr/bin/env python | ||
| # -*- coding: utf-8 -*- | ||
| """ | ||
| ghostscript - A Python interface for the Ghostscript interpreter C-API | ||
| """ | ||
| # | ||
| # Copyright 2010-2018 by Hartmut Goebel <h.goebel@crazy-compilers.com> | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| from __future__ import absolute_import | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2018 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| __version__ = '0.6' | ||
| __all__ = ['Ghostscript', 'revision', | ||
| 'GhostscriptError', 'PleaseDisplayUsage'] | ||
| import atexit | ||
| import sys # :todo: remove, debugging only | ||
| from . import _gsprint as gs | ||
| GhostscriptError = gs.GhostscriptError | ||
| def PleaseDisplayUsage(Warning): | ||
| """ | ||
| This exception is raised when Ghostscript asks the application to | ||
| display the usage. The application should catch the exception an | ||
| print the usage message. | ||
| """ | ||
| pass | ||
| def revision(): | ||
| """ | ||
| This function returns the revision numbers and strings of the | ||
| Ghostscript interpreter library as a dict. You should call it | ||
| before any other interpreter library functions to make sure that | ||
| the correct version of the Ghostscript interpreter has been | ||
| loaded. | ||
| """ | ||
| rev = gs.revision() | ||
| return dict((f, getattr(rev, f)) for f, _ in rev._fields_) | ||
| MAX_STRING_LENGTH = gs.MAX_STRING_LENGTH | ||
| class Ghostscript(object): | ||
| @staticmethod | ||
| def revision(): | ||
| return revision() | ||
| def __init__(self, instance, args, stdin=None, stdout=None, stderr=None): | ||
| self._initialized = False | ||
| self._instance = instance | ||
| self._callbacks = None | ||
| if stdin or stdout or stderr: | ||
| self.set_stdio(stdin, stdout, stderr) | ||
| rc = gs.init_with_args(instance, args) | ||
| if rc == gs.e_Info: | ||
| raise PleaseDisplayUsage | ||
| self._initialized = True | ||
| if rc == gs.e_Quit: | ||
| self.exit() | ||
| def __enter__(self): | ||
| return self | ||
| def __exit__(self, *args): | ||
| self.exit() | ||
| def set_stdio(self, stdin=None, stdout=None, stderr=None): | ||
| """Set stdin, stdout and stderr of the ghostscript interpreter. | ||
| The ``stdin`` stream has to support the ``readline()`` | ||
| interface. The ``stdout`` and ``stderr`` streams have to | ||
| support the ``write()`` and ``flush()`` interface. | ||
| Please note that this does not affect the input- and output- | ||
| streams of the devices. Esp. setting stdout does not allow | ||
| catching the devise-output even when using ``-sOutputFile=-``. | ||
| """ | ||
| self._callbacks = ( | ||
| stdin and gs._wrap_stdin(stdin) or None, | ||
| stdout and gs._wrap_stdout(stdout) or None, | ||
| stderr and gs._wrap_stderr(stderr) or None, | ||
| ) | ||
| gs.set_stdio(self._instance, *self._callbacks) | ||
| def __del__(self): | ||
| self.exit() | ||
| def exit(self): | ||
| global __instance__ | ||
| if self._initialized: | ||
| if __instance__: | ||
| #gs.exit(self._instance) | ||
| self._instance = None | ||
| self._initialized = False | ||
| def run_string(self, str, user_errors=False): | ||
| """ | ||
| Run the string ``str`` by Ghostscript | ||
| This takes care of Ghostscripts size-limitations and passes | ||
| the string in pieces if necessary. | ||
| """ | ||
| instance = self._instance | ||
| if len(str) < MAX_STRING_LENGTH: | ||
| gs.run_string(instance, str) | ||
| else: | ||
| gs.run_string_begin(instance) | ||
| for start in range(0, len(str), MAX_STRING_LENGTH): | ||
| gs.run_string_continue(instance, | ||
| str[start:start+MAX_STRING_LENGTH]) | ||
| gs.run_string_end(instance) | ||
| def run_filename(self, filename, user_errors=False): | ||
| """ | ||
| Run the file named by ``filename`` by Ghostscript | ||
| """ | ||
| return gs.run_file(self._instance, filename, user_errors) | ||
| def run_file(self, file, user_errors=False): | ||
| """ | ||
| Read ``file`` and run the content by Ghostscript. | ||
| ``file`` must already by opened and may by any file-like | ||
| object supporting the ``read()`` method. | ||
| """ | ||
| instance = self._instance | ||
| gs.run_string_begin(instance) | ||
| while True: | ||
| str = file.read(MAX_STRING_LENGTH) | ||
| if not str: | ||
| break | ||
| gs.run_string_continue(instance, str) | ||
| gs.run_string_end(instance) | ||
| __Ghostscript = Ghostscript | ||
| __instance__ = None | ||
| def Ghostscript(*args, **kw): | ||
| """ | ||
| Factory function for setting up a Ghostscript instance | ||
| """ | ||
| global __instance__, __object_count__ | ||
| # Ghostscript only supports a single instance | ||
| if __instance__ is None: | ||
| __instance__ = gs.new_instance() | ||
| return __Ghostscript(__instance__, args, | ||
| stdin=kw.get('stdin', None), | ||
| stdout=kw.get('stdout', None), | ||
| stderr=kw.get('stderr', None)) | ||
| def cleanup(): | ||
| global __instance__ | ||
| if __instance__ is not None: | ||
| gs.delete_instance(__instance__) | ||
| __instance__ = None | ||
| #atexit.register(cleanup) |
| """ | ||
| Definition of Ghostscript error codes | ||
| """ | ||
| # | ||
| # Copyright (C) 2010-2018 by Hartmut Goebel | ||
| # | ||
| # Based on iapi.h which is | ||
| # Copyright (C) 1989, 1995, 1998, 1999 Aladdin Enterprises. All rights reserved. | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2018 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| # | ||
| # A procedure that may return an error always returns | ||
| # a non-negative value (zero, unless otherwise noted) for success, | ||
| # or negative for failure. | ||
| # We use ints rather than an enum to avoid a lot of casting. | ||
| # | ||
| # ------ PostScript Level 1 errors ------ | ||
| e_unknownerror = -1 # unknown error | ||
| e_dictfull = -2 | ||
| e_dictstackoverflow = -3 | ||
| e_dictstackunderflow = -4 | ||
| e_execstackoverflow = -5 | ||
| e_interrupt = -6 | ||
| # We also need to define gs_error_interrupt, for gpcheck.h | ||
| gs_error_interrupt = e_interrupt | ||
| e_invalidaccess = -7 | ||
| e_invalidexit = -8 | ||
| e_invalidfileaccess = -9 | ||
| e_invalidfont = -10 | ||
| e_invalidrestore = -11 | ||
| e_ioerror = -12 | ||
| e_limitcheck = -13 | ||
| e_nocurrentpoint = -14 | ||
| e_rangecheck = -15 | ||
| e_stackoverflow = -16 | ||
| e_stackunderflow = -17 | ||
| e_syntaxerror = -18 | ||
| e_timeout = -19 | ||
| e_typecheck = -20 | ||
| e_undefined = -21 | ||
| e_undefinedfilename = -22 | ||
| e_undefinedresult = -23 | ||
| e_unmatchedmark = -24 | ||
| e_VMerror = -25 | ||
| LEVEL1_ERROR_NAMES = ["unknownerror", "dictfull", "dictstackoverflow", | ||
| "dictstackunderflow", "execstackoverflow", | ||
| "interrupt", "invalidaccess", "invalidexit", | ||
| "invalidfileaccess", "invalidfont", | ||
| "invalidrestore", "ioerror", "limitcheck", | ||
| "nocurrentpoint", "rangecheck", "stackoverflow", | ||
| "stackunderflow", "syntaxerror", "timeout", | ||
| "typecheck", "undefined", "undefinedfilename", | ||
| "undefinedresult", "unmatchedmark", "VMerror"] | ||
| # ------ Additional Level 2 and DPS errors ------ | ||
| e_configurationerror = -26 | ||
| e_invalidcontext = -27 | ||
| e_undefinedresource = -28 | ||
| e_unregistered = -29 | ||
| # invalidid is for the NeXT DPS extension. | ||
| e_invalidid = -30 | ||
| LEVEL2_ERROR_NAMES = ["configurationerror", "invalidcontext", | ||
| "undefinedresource", "unregistered", | ||
| "invalidid"] | ||
| ERROR_NAMES = LEVEL1_ERROR_NAMES + LEVEL2_ERROR_NAMES | ||
| _PSEUDO_ERRORS = ['Fatal', 'Quit', 'InterpreterExit', 'RemapColor', | ||
| 'ExecStackUnderflow', 'VMreclaim', 'NeedInput', | ||
| 'NeedStdin', 'NeedStdout', 'NeedStderr', 'Info'] | ||
| def error2name(ecode): | ||
| if ecode <= e_Fatal: | ||
| return _PSEUDO_ERRORS[-ecode-100] | ||
| else: | ||
| return ERROR_NAMES[-ecode-1] | ||
| # ------ Pseudo-errors used internally ------ | ||
| # | ||
| # Internal code for a fatal error. | ||
| # gs_interpret also returns this for a .quit with a positive exit code. | ||
| # | ||
| e_Fatal = -100 | ||
| # | ||
| # Internal code for the .quit operator. | ||
| # The real quit code is an integer on the operand stack. | ||
| # gs_interpret returns this only for a .quit with a zero exit code. | ||
| # | ||
| e_Quit = -101 | ||
| # | ||
| # Internal code for a normal exit from the interpreter. | ||
| # Do not use outside of interp.c. | ||
| # | ||
| e_InterpreterExit = -102 | ||
| # | ||
| # Internal code that indicates that a procedure has been stored in the | ||
| # remap_proc of the graphics state, and should be called before retrying | ||
| # the current token. This is used for color remapping involving a call | ||
| # back into the interpreter -- inelegant, but effective. | ||
| # | ||
| e_RemapColor = -103 | ||
| # | ||
| # Internal code to indicate we have underflowed the top block | ||
| # of the e-stack. | ||
| # | ||
| e_ExecStackUnderflow = -104 | ||
| # | ||
| # Internal code for the vmreclaim operator with a positive operand. | ||
| # We need to handle this as an error because otherwise the interpreter | ||
| # won't reload enough of its state when the operator returns. | ||
| # | ||
| e_VMreclaim = -105 | ||
| # | ||
| # Internal code for requesting more input from run_string. | ||
| # | ||
| e_NeedInput = -106 | ||
| # | ||
| # Internal code for stdin callout. | ||
| # | ||
| e_NeedStdin = -107 | ||
| # | ||
| # Internal code for stdout callout. | ||
| # | ||
| e_NeedStdout = -108 | ||
| # | ||
| # Internal code for stderr callout. | ||
| # | ||
| e_NeedStderr = -109 | ||
| # | ||
| # Internal code for a normal exit when usage info is displayed. | ||
| # This allows Window versions of Ghostscript to pause until | ||
| # the message can be read. | ||
| # | ||
| e_Info = -110 | ||
| # | ||
| # Define which error codes require re-executing the current object. | ||
| # | ||
| def ERROR_IS_INTERRUPT(ecode): | ||
| return ecode == e_interrupt or ecode == e_timeout | ||
| if __name__ == '__main__': | ||
| print(error2name(e_unknownerror) == "unknownerror") | ||
| print(error2name(e_VMerror) == "VMerror") | ||
| print(error2name(e_invalidid) == "invalidid") | ||
| print(error2name(e_VMreclaim) == "VMreclaim") |
| #!/usr/bin/env python | ||
| # -*- coding: utf-8 -*- | ||
| """ | ||
| ghostscript._gsprint - A low-lewel interface to the Ghostscript C-API using ctypes | ||
| """ | ||
| # | ||
| # Copyright 2010-2018 by Hartmut Goebel <h.goebel@crazy-compilers.com> | ||
| # | ||
| # Display_callback Structure by Lasse Fister <commander@graphicore.de> in 2013 | ||
| # | ||
| # 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 3 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, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| from __future__ import absolute_import | ||
| __author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __copyright__ = "Copyright 2010-2018 by Hartmut Goebel <h.goebel@crazy-compilers.com>" | ||
| __licence__ = "GNU General Public License version 3 (GPL v3)" | ||
| __version__ = "0.5dev" | ||
| from ctypes import * | ||
| import sys | ||
| from ._errors import * | ||
| MAX_STRING_LENGTH = 65535 | ||
| DISPLAY_VERSION_MAJOR = 2 | ||
| DISPLAY_VERSION_MINOR = 0 | ||
| DISPLAY_VERSION_MAJOR_V1 = 1 # before separation format was added | ||
| DISPLAY_VERSION_MINOR_V1 = 0 | ||
| # The display format is set by a combination of the following bitfields | ||
| # Define the color space alternatives | ||
| # DISPLAY_FORMAT_COLOR | ||
| DISPLAY_COLORS_NATIVE = (1<<0) | ||
| DISPLAY_COLORS_GRAY = (1<<1) | ||
| DISPLAY_COLORS_RGB = (1<<2) | ||
| DISPLAY_COLORS_CMYK = (1<<3) | ||
| DISPLAY_COLORS_SEPARATION = (1<<19) | ||
| DISPLAY_COLORS_MASK = 0x8000f | ||
| # Define whether alpha information, or an extra unused bytes is included | ||
| # DISPLAY_ALPHA_FIRST and DISPLAY_ALPHA_LAST are not implemented | ||
| # DISPLAY_FORMAT_ALPHA | ||
| 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_ALPHA_MASK = 0x00f0 | ||
| # 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. | ||
| # DISPLAY_FORMAT_DEPTH | ||
| 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_DEPTH_MASK = 0xff00 | ||
| # Define whether Red/Cyan should come first, | ||
| # or whether Blue/Black should come first | ||
| # DISPLAY_FORMAT_ENDIAN | ||
| DISPLAY_BIGENDIAN = (0<<16) # Red/Cyan first | ||
| DISPLAY_LITTLEENDIAN = (1<<16) # Blue/Black first | ||
| DISPLAY_ENDIAN_MASK = 0x00010000 | ||
| # Define whether the raster starts at the top or bottom of the bitmap | ||
| # DISPLAY_FORMAT_FIRSTROW | ||
| DISPLAY_TOPFIRST = (0<<17) # Unix, Mac | ||
| DISPLAY_BOTTOMFIRST = (1<<17) # Windows | ||
| DISPLAY_FIRSTROW_MASK = 0x00020000 | ||
| # Define whether packing RGB in 16-bits should use 555 | ||
| # or 565 (extra bit for green) | ||
| # DISPLAY_FORMAT_555 | ||
| DISPLAY_NATIVE_555 = (0<<18) | ||
| DISPLAY_NATIVE_565 = (1<<18) | ||
| DISPLAY_555_MASK = 0x00040000 | ||
| # Define the row alignment, which must be equal to or greater than | ||
| # the size of a pointer. | ||
| # The default (DISPLAY_ROW_ALIGN_DEFAULT) is the size of a pointer, | ||
| # 4 bytes (DISPLAY_ROW_ALIGN_4) on 32-bit systems or 8 bytes | ||
| # (DISPLAY_ROW_ALIGN_8) on 64-bit systems. | ||
| # DISPLAY_FORMAT_ROW_ALIGN | ||
| DISPLAY_ROW_ALIGN_DEFAULT = (0<<20) | ||
| # DISPLAY_ROW_ALIGN_1 = (1<<20), # not currently possible | ||
| # DISPLAY_ROW_ALIGN_2 = (2<<20), # not currently possible | ||
| DISPLAY_ROW_ALIGN_4 = (3<<20) | ||
| DISPLAY_ROW_ALIGN_8 = (4<<20) | ||
| DISPLAY_ROW_ALIGN_16 = (5<<20) | ||
| DISPLAY_ROW_ALIGN_32 = (6<<20) | ||
| DISPLAY_ROW_ALIGN_64 = (7<<20) | ||
| DISPLAY_ROW_ALIGN_MASK = 0x00700000 | ||
| class Revision(Structure): | ||
| _fields_ = [ | ||
| ("product", c_char_p), | ||
| ("copyright", c_char_p), | ||
| ("revision", c_long), | ||
| ("revisiondate", c_long) | ||
| ] | ||
| gs_main_instance = c_void_p | ||
| display_callback = c_void_p | ||
| class GhostscriptError(Exception): | ||
| def __init__(self, ecode): | ||
| # :todo: | ||
| Exception.__init__(self, error2name(ecode)) | ||
| self.code = ecode | ||
| def revision(): | ||
| """ | ||
| 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. | ||
| Returns a Revision instance | ||
| """ | ||
| revision = Revision() | ||
| rc = libgs.gsapi_revision(pointer(revision), sizeof(revision)) | ||
| if rc: | ||
| raise ArgumentError("Revision structure size is incorrect, " | ||
| "requires %s bytes" % rc) | ||
| return revision | ||
| def new_instance(): # display_callback=None): | ||
| """ | ||
| Create a new instance of Ghostscript | ||
| This instance is passed to most other API functions. | ||
| """ | ||
| # :todo: The caller_handle will be provided to callback functions. | ||
| display_callback=None | ||
| instance = gs_main_instance() | ||
| rc = libgs.gsapi_new_instance(pointer(instance), display_callback) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return instance | ||
| def delete_instance(instance): | ||
| """ | ||
| Destroy an instance of Ghostscript | ||
| Before you call this, Ghostscript must have finished. | ||
| If Ghostscript has been initialised, you must call exit() | ||
| before delete_instance() | ||
| """ | ||
| return libgs.gsapi_delete_instance(instance) | ||
| c_stdstream_call_t = CFUNCTYPE(c_int, gs_main_instance, POINTER(c_char), c_int) | ||
| def _wrap_stdin(infp): | ||
| """ | ||
| Wrap a filehandle into a C function to be used as `stdin` callback | ||
| for ``set_stdio``. The filehandle has to support the readline() method. | ||
| """ | ||
| def _wrap(instance, dest, count): | ||
| try: | ||
| data = infp.readline(count) | ||
| except: | ||
| count = -1 | ||
| else: | ||
| if not data: | ||
| count = 0 | ||
| else: | ||
| count = len(data) | ||
| memmove(dest, c_char_p(data), count) | ||
| return count | ||
| return c_stdstream_call_t(_wrap) | ||
| def _wrap_stdout(outfp): | ||
| """ | ||
| Wrap a filehandle into a C function to be used as `stdout` or | ||
| `stderr` callback for ``set_stdio``. The filehandle has to support the | ||
| write() and flush() methods. | ||
| """ | ||
| def _wrap(instance, str, count): | ||
| outfp.write(str[:count]) | ||
| outfp.flush() | ||
| return count | ||
| return c_stdstream_call_t(_wrap) | ||
| _wrap_stderr = _wrap_stdout | ||
| def set_stdio(instance, stdin, stdout, stderr): | ||
| """ | ||
| Set the callback functions for stdio. | ||
| ``stdin``, ``stdout`` and ``stderr`` have to be ``ctypes`` | ||
| callback functions matching the ``_gsprint.c_stdstream_call_t`` | ||
| prototype. You may want to use _wrap_* to wrap file handles. | ||
| Note 1: This function only changes stdio of the Postscript | ||
| interpreter, not that of the devices. | ||
| Note 2: Make sure you keep references to C function objects | ||
| as long as they are used from C code. Otherwise they may be | ||
| garbage collected, crashing your program when a callback is made. | ||
| 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. | ||
| You may pass ``None`` for any of stdin, stdout or stderr , in which | ||
| case the system stdin, stdout resp. stderr will be used. | ||
| """ | ||
| rc = libgs.gsapi_set_stdio(instance, stdin, stdout, stderr) | ||
| if rc not in (0, e_Quit, e_Info): | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| # :todo: set_poll (instance, int(*poll_fn)(void *caller_handle)); | ||
| # :todo: set_display_callback(instance, callback): | ||
| def init_with_args(instance, argv): | ||
| """ | ||
| Initialise the interpreter. | ||
| 1. If quit or EOF occur during init_with_args(), the return value | ||
| will be e_Quit. This is not an error. You must call exit() and | ||
| must not call any other functions. | ||
| 2. If usage info should be displayed, the return value will be | ||
| e_Info which is not an error. Do not call exit(). | ||
| 3. Under normal conditions this returns 0. You would then call one | ||
| or more run_*() functions and then finish with exit() | ||
| """ | ||
| ArgArray = c_char_p * len(argv) | ||
| c_argv = ArgArray(*argv) | ||
| rc = libgs.gsapi_init_with_args(instance, len(argv), c_argv) | ||
| if rc not in (0, e_Quit, e_Info): | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def exit(instance): | ||
| """ | ||
| Exit the interpreter | ||
| This must be called on shutdown if init_with_args() has been | ||
| called, and just before delete_instance() | ||
| """ | ||
| rc = libgs.gsapi_exit(instance) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def run_string_begin(instance, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_begin(instance, c_int(user_errors), | ||
| pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_continue(instance, str, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_continue( | ||
| instance, c_char_p(str), c_int(len(str)), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != e_NeedInput and rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_end(instance, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_end(instance, c_int(user_errors), | ||
| pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_string_with_length(*args, **kw): | ||
| raise NotImpelmentedError('Use run_string() instead') | ||
| def run_string(instance, str, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_string_with_length( | ||
| instance, c_char_p(str), c_int(len(str)), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def run_file(instance, filename, user_errors=False): | ||
| exit_code = c_int() | ||
| rc = libgs.gsapi_run_file(instance, c_char_p(filename), | ||
| c_int(user_errors), pointer(exit_code)) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return exit_code.value | ||
| def set_visual_tracer(I): | ||
| raise NotImplementedError | ||
| # New device has been opened | ||
| # This is the first event from this device. | ||
| # int (*display_open)(void *handle, void *device); | ||
| c_display_open = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # Device is about to be closed. | ||
| # Device will not be closed until this function returns. | ||
| #int (*display_preclose)(void *handle, void *device); | ||
| c_display_preclose = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # Device has been closed. | ||
| # This is the last event from this device. | ||
| # int (*display_close)(void *handle, void *device); | ||
| c_display_close = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # 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); | ||
| c_display_presize = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_uint) | ||
| # 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); | ||
| c_display_size = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_uint, POINTER(c_ubyte)) | ||
| # flushpage | ||
| #int (*display_sync)(void *handle, void *device); | ||
| c_display_sync = CFUNCTYPE(c_int, c_void_p, c_void_p) | ||
| # showpage | ||
| # If you want to pause on showpage, then don't return immediately | ||
| # int (*display_page)(void *handle, void *device, int copies, int flush); | ||
| c_display_page = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int) | ||
| # 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); | ||
| c_display_update = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_int, c_int, c_int) | ||
| # 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); | ||
| c_display_memalloc = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_ulong) | ||
| # 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); | ||
| c_display_memfree = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) | ||
| # Added in V2 */ | ||
| # When using separation color space (DISPLAY_COLORS_SEPARATION), | ||
| # give a mapping for one separation component. | ||
| # This is called for each new component found. | ||
| # It may be called multiple times for each component. | ||
| # It may be called at any time between display_size | ||
| # and display_close. | ||
| # The client uses this to map from the separations to CMYK | ||
| # and hence to RGB for display. | ||
| # GS must only use this callback if version_major >= 2. | ||
| # The unsigned short c,m,y,k values are 65535 = 1.0. | ||
| # This function pointer may be set to NULL if not required. | ||
| # | ||
| # int (*display_separation)(void *handle, void *device, | ||
| # int component, const char *component_name, | ||
| # unsigned short c, unsigned short m, | ||
| # unsigned short y, unsigned short k); | ||
| c_display_separation = CFUNCTYPE(c_int, c_void_p, c_void_p, | ||
| c_int, c_char_p, c_ushort, c_ushort, c_ushort, c_ushort) | ||
| class Display_callback_s (Structure): | ||
| _fields_ = [ | ||
| # Size of this structure | ||
| # Used for checking if we have been handed a valid structure | ||
| # int size; | ||
| ("size", c_int), | ||
| # Major version of this structure | ||
| # The major version number will change if this structure changes. | ||
| # int version_major; | ||
| ("version_major", c_int), | ||
| # 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; | ||
| ("version_minor", c_int), | ||
| ("display_open", c_display_open), | ||
| ("display_preclose", c_display_preclose), | ||
| ("display_close", c_display_close), | ||
| ("display_presize", c_display_presize), | ||
| ("display_size", c_display_size), | ||
| ("display_sync", c_display_sync), | ||
| ("display_page", c_display_page), | ||
| ("display_update", c_display_update), | ||
| ("display_memalloc", c_display_memalloc), | ||
| ("display_memfree", c_display_memfree), | ||
| ("display_separation", c_display_separation) | ||
| ] | ||
| def set_display_callback(instance, callback): | ||
| rc = libgs.gsapi_set_display_callback(instance, callback) | ||
| if rc != 0: | ||
| raise GhostscriptError(rc) | ||
| return rc | ||
| def __win32_finddll(): | ||
| try: | ||
| import winreg | ||
| except ImportError: | ||
| # assume Python 2 | ||
| from _winreg import OpenKey, CloseKey, EnumKey, QueryValueEx, \ | ||
| QueryInfoKey, HKEY_LOCAL_MACHINE | ||
| else: | ||
| from winreg import OpenKey, CloseKey, EnumKey, QueryValueEx, \ | ||
| QueryInfoKey, HKEY_LOCAL_MACHINE | ||
| from distutils.version import LooseVersion | ||
| import os | ||
| dlls = [] | ||
| # Look up different variants of Ghostscript and take the highest | ||
| # version for which the DLL is to be found in the filesystem. | ||
| for key_name in ('AFPL Ghostscript', 'Aladdin Ghostscript', | ||
| 'GPL Ghostscript', 'GNU Ghostscript'): | ||
| try: | ||
| k1 = OpenKey(HKEY_LOCAL_MACHINE, "Software\\%s" % key_name) | ||
| for num in range(0, QueryInfoKey(k1)[0]): | ||
| version = EnumKey(k1, num) | ||
| try: | ||
| k2 = OpenKey(k1, version) | ||
| dll_path = QueryValueEx(k2, 'GS_DLL')[0] | ||
| CloseKey(k2) | ||
| if os.path.exists(dll_path): | ||
| dlls.append((LooseVersion(version), dll_path)) | ||
| except WindowsError: | ||
| pass | ||
| CloseKey(k1) | ||
| except WindowsError: | ||
| pass | ||
| if dlls: | ||
| dlls.sort() | ||
| return dlls[-1][-1] | ||
| else: | ||
| return None | ||
| if sys.platform == 'win32': | ||
| libgs = __win32_finddll() | ||
| if not libgs: | ||
| raise RuntimeError('Can not find Ghostscript DLL in registry') | ||
| libgs = windll.LoadLibrary(libgs) | ||
| else: | ||
| try: | ||
| libgs = cdll.LoadLibrary("libgs.so") | ||
| except OSError: | ||
| # shared object file not found | ||
| import ctypes.util | ||
| libgs = ctypes.util.find_library('gs') | ||
| if not libgs: | ||
| raise RuntimeError('Can not find Ghostscript library (libgs)') | ||
| libgs = cdll.LoadLibrary(libgs) | ||
| del __win32_finddll |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
54539
Infinity%12
Infinity%731
Infinity%