home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / EVE_1424_100181.exe / ImageFont.py < prev    next >
Encoding:
Python Source  |  2004-04-20  |  5.0 KB  |  162 lines

  1. #
  2. # The Python Imaging Library.
  3. # $Id: //modules/pil/PIL/ImageFont.py#4 $
  4. #
  5. # PIL raster font management
  6. #
  7. # History:
  8. # 1996-08-07 fl   created (experimental)
  9. # 1997-08-25 fl   minor adjustments to handle fonts from pilfont 0.3
  10. # 1999-02-06 fl   rewrote most font management stuff in C
  11. # 1999-03-17 fl   take pth files into account in load_path (from Richard Jones)
  12. # 2001-02-17 fl   added freetype support
  13. # 2001-05-09 fl   added TransposedFont wrapper class
  14. # 2002-03-04 fl   make sure we have a "L" or "1" font
  15. #
  16. # Todo:
  17. # Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
  18. #
  19. # Copyright (c) 1997-2002 by Secret Labs AB
  20. # Copyright (c) 1996-2001 by Fredrik Lundh
  21. #
  22. # See the README file for information on usage and redistribution.
  23. #
  24.  
  25. import Image
  26. import os, string, sys
  27.  
  28. # --------------------------------------------------------------------
  29. # Font metrics format:
  30. #       "PILfont" LF
  31. #       fontdescriptor LF
  32. #       (optional) key=value... LF
  33. #       "DATA" LF
  34. #       binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
  35. #
  36. # To place a character, cut out srcbox and paste at dstbox,
  37. # relative to the character position.  Then move the character
  38. # position according to dx, dy.
  39. # --------------------------------------------------------------------
  40.  
  41. # FIXME: add support for pilfont2 format (see FontFile.py)
  42.  
  43. class ImageFont:
  44.     "PIL font wrapper"
  45.  
  46.     def _load_pilfont(self, filename):
  47.  
  48.         fp = open(filename, "rb")
  49.  
  50.         # read PILfont header
  51.         if fp.readline() != "PILfont\n":
  52.             raise SyntaxError, "Not a PILfont file"
  53.         d = string.split(fp.readline(), ";")
  54.         self.info = [] # FIXME: should be a dictionary
  55.         s = fp.readline()
  56.         while s and s != "DATA\n":
  57.             self.info.append(s)
  58.  
  59.         # read PILfont metrics
  60.         data = fp.read(256*20)
  61.  
  62.         # read PILfont bitmap
  63.         for ext in (".png", ".gif", ".pbm"):
  64.             try:
  65.                 fullname = os.path.splitext(filename)[0] + ext
  66.                 image = Image.open(fullname)
  67.             except:
  68.                 pass
  69.             else:
  70.                 if image and image.mode in ("1", "L"):
  71.                     break
  72.         else:
  73.             raise IOError, "cannot find glyph data file"
  74.  
  75.         image.load()
  76.  
  77.         self.file = fullname
  78.         self.font = Image.core.font(image.im, data)
  79.  
  80.         # delegate critical operations to internal type
  81.         self.getsize = self.font.getsize
  82.         self.getmask = self.font.getmask
  83.  
  84.  
  85. class FreeTypeFont:
  86.     "FreeType font wrapper (requires _imagingft service)"
  87.  
  88.     def __init__(self, file, size, index=0):
  89.         # FIXME: use service provider instead
  90.         import _imagingft
  91.         self.font = _imagingft.getfont(file, size, index)
  92.  
  93.     def getsize(self, text):
  94.         return self.font.getsize(text)
  95.  
  96.     def getmask(self, text, fill=Image.core.fill):
  97.         size = self.font.getsize(text)
  98.         im = fill("L", size, 0)
  99.         self.font.render(text, im.id)
  100.         return im
  101.  
  102.  
  103. class TransposedFont:
  104.     "Wrapper for writing rotated or mirrored text"
  105.  
  106.     def __init__(self, font, orientation=None):
  107.         self.font = font
  108.         self.orientation = orientation # any 'transpose' argument, or None
  109.  
  110.     def getsize(self, text):
  111.         w, h = self.font.getsize(text)
  112.         if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
  113.             return h, w
  114.         return w, h
  115.  
  116.     def getmask(self, text):
  117.         im = self.font.getmask(text)
  118.         if self.orientation is not None:
  119.             return im.transpose(self.orientation)
  120.         return im
  121.  
  122. #
  123. # --------------------------------------------------------------------
  124.  
  125. def load(filename):
  126.     "Load a font file."
  127.     f = ImageFont()
  128.     f._load_pilfont(filename)
  129.     return f
  130.  
  131. def truetype(filename, size, index=0):
  132.     "Load a truetype font file."
  133.     try:
  134.         return FreeTypeFont(filename, size, index)
  135.     except IOError:
  136.         if sys.platform == "win32":
  137.             # check the windows font repository
  138.             # NOTE: must use uppercase WINDIR, to work around bugs in
  139.             # 1.5.2's os.environ.get()
  140.             windir = os.environ.get("WINDIR")
  141.             if windir:
  142.                 filename = os.path.join(windir, "fonts", filename)
  143.                 return FreeTypeFont(filename, size, index)
  144.         raise
  145.  
  146. def load_path(filename):
  147.     "Load a font file, searching along the Python path."
  148.     for dir in sys.path:
  149.         try:
  150.             return load(os.path.join(dir, filename))
  151.         except IOError:
  152.             pass
  153.         # disabled: site.py already does this for us
  154. ##         import glob
  155. ##         for extra in glob.glob(os.path.join(dir, "*.pth")):
  156. ##             try:
  157. ##                 dir = os.path.join(dir, string.strip(open(extra).read()))
  158. ##                 return load(os.path.join(dir, filename))
  159. ##             except IOError:
  160. ##                 pass
  161.     raise IOError, "cannot find font file"
  162.