# Sketch - A Python-based interactive drawing program
# Copyright (C) 1997, 1998, 1999, 2000 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
#
# Handle external data
#
#
# This module defines two classes to represent external graphics like
# bitmapped images or encapsulated PostScript files.
from Sketch import Rect,Trafo,IdentityMatrix,NullUndo,SKCache
from base import GraphicsObject,RectangularObject
from properties import EmptyProperties
instance_cache = SKCache()
class ExternalData:
# default instance variables
stored_in_cache = 0
filename = ''
def __init__(self, filename = '', do_cache = 1):
if filename and do_cache:
self.stored_in_cache = 1
instance_cache[filename] = self
if filename:
self.filename = filename
def __del__(self):
if self.stored_in_cache and instance_cache.has_key(self.filename):
del instance_cache[self.filename]
def Filename(self):
return self.filename
# to be supplied by derived classes
#
# Size() return the size as a tuple (width, height)
def get_cached(filename):
if instance_cache.has_key(filename):
return instance_cache[filename]
return None
class ExternalGraphics(RectangularObject, GraphicsObject):
has_edit_mode = 0
# by default this has no properties:
has_fill = has_line = has_font = 0
data = None
def __init__(self, data = None, trafo = None, duplicate = None):
RectangularObject.__init__(self, trafo, duplicate = duplicate)
GraphicsObject.__init__(self, duplicate = duplicate)
if duplicate is not None:
data = duplicate.data
self.data = data
def Data(self):
return self.data
def SetData(self, data):
undo = self.SetData, self.data
self.data = data
# XXX issue_changed() here ?
return undo
def Hit(self, p, rect, device, clip = 0):
width, height = self.data.Size()
return device.ParallelogramHit(p, self.trafo, width, height, 1,
ignore_outline_mode = clip)
def SetLowerLeftCorner(self, corner):
# Used by the place mode in SketchCanvas. Currently no undo
# needed since this is called *before* self is a part of a
# document.
self.trafo = apply(Trafo, self.trafo.coeff()[:4] + tuple(corner))
self.del_lazy_attrs()
def RemoveTransformation(self):
if self.trafo.matrix() != IdentityMatrix:
center = self.coord_rect.center()
width, height = self.data.Size()
trafo = Trafo(1, 0, 0, 1,
center.x - width / 2, center.y - height / 2)
return self.set_transformation(trafo)
return NullUndo
def update_rects(self):
width, height = self.data.Size()
rect = self.trafo(Rect(0, 0, width, height))
self.coord_rect = rect
self.bounding_rect = rect.grown(2)
def Info(self):
# Should be overwritten by derived classes
return 'ExternalGraphics'
def SetProperties(self, **kw):
return NullUndo
def AddStyle(self, style):
return NullUndo
def Properties(self):
return EmptyProperties
def GetSnapPoints(self):
width, height = self.data.Size()
corners = ((0, 0), (width, 0), (width, height), (0, height))
return map(self.trafo, corners)
def Snap(self, p):
width, height = self.data.Size()
try:
x, y = self.trafo.inverse()(p)
if 0 <= x <= width:
if 0 <= y <= height:
x = round(x / width) * width
y = round(y / height) * height
else:
y = min(max(y, 0), height)
else:
x = min(max(x, 0), width)
if 0 > y or y > height:
y = min(max(y, 0), height)
p2 = self.trafo(x, y)
return (abs(p - p2), p2)
except SingularMatrix:
return (1e200, p)
|