# Sketch - A Python-based interactive drawing program
# Copyright (C) 1998, 1999, 2000, 2002 by Bernhard Herzog
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# A GraphicsObject for Encapsulated Postscript Pictures
#
import os, math
import PIL.Image
from Sketch.Lib import dscparser,util
IsEpsFileStart = dscparser.IsEpsFileStart
from Sketch import _,Point,config
from base import GraphicsObject
from external import ExternalData,get_cached,ExternalGraphics
gs_command = ('gs -sDEVICE=ppmraw -r%(resolution)d -dNOPAUSE -dSAFER -q'
' -sOutputFile=%(temp)s -g%(width)dx%(height)d'
' -c %(offx)f %(offy)f translate'
' /oldshowpage /showpage load def /showpage \'{}\' def '
' -f %(filename)s -c oldshowpage quit')
def render_preview(filename, startx, starty, width, height, resolution = None):
import tempfile
temp = tempfile.mktemp()
try:
# quote the filename so that it can have spaces and to avoid a
# security hole
filename = util.sh_quote(filename)
if resolution is None:
resolution = config.preferences.eps_preview_resolution
factor = resolution / 72.0
width = int(math.ceil(width * factor))
height = int(math.ceil(height * factor))
offx = -startx
offy = -starty
os.system(gs_command % locals())
image = PIL.Image.open(temp)
image.load()
return image
finally:
try:
os.unlink(temp)
except:
pass
class EpsData(ExternalData):
def __init__(self, filename):
self.info = info = dscparser.parse_eps_file(filename)
self.filename = filename
if info.BoundingBox:
llx, lly, urx, ury = info.BoundingBox
self.width = Point(urx - llx, 0)
self.height = Point(0, ury - lly)
self.start = (llx, lly)
self.size = (urx - llx, ury - lly)
self.image = None
try:
self.image = render_preview(filename, llx, lly,
urx - llx, ury - lly)
except IOError:
pass
else:
raise TypeError, '%s has no BoundingBox' % filename
ExternalData.__init__(self, filename)
def Start(self):
return self.start
def Size(self):
return self.size
def WriteLines(self, file):
write = file.write
try:
infile = open(self.filename, 'r')
except IOError, val:
raise IOError, (filename, val)
try:
readline = infile.readline
line = readline()
while line:
if line[:15] == '%%BeginPreview:':
while line[:12] != '%%EndPreview':
line = readline()
continue
write(line)
line = readline()
finally:
infile.close()
def load_eps(filename):
eps = get_cached(filename)
if eps:
return eps
return EpsData(filename)
class EpsImage(ExternalGraphics):
has_edit_mode = 0
is_Eps = 1
def __init__(self, filename = '', trafo = None, duplicate = None):
if duplicate is None:
if not filename:
raise ValueError, 'filename must be provided'
data = load_eps(filename)
else:
data = None
ExternalGraphics.__init__(self, data, trafo,
duplicate = duplicate)
def DrawShape(self, device, rect = None):
device.DrawEps(self.data, self.trafo)
def Info(self):
filename = os.path.basename(self.data.Filename())
width, height = self.data.Size()
x, y = self.trafo.offset()
return _("EpsFile `%(filename)s' %(width)d x %(height)d "
"at (%(x)d, %(y)d)") % locals()
def SaveToFile(self, file):
file.EpsFile(self.data, self.trafo)
def PSNeededResources(self):
return self.data.info.DocumentNeededResources
|