File: t1Imaging.py

package info (click to toggle)
t1lib0 0.7.1-5
  • links: PTS
  • area: main
  • in suites: slink
  • size: 2,740 kB
  • ctags: 2,569
  • sloc: ansic: 20,709; sh: 2,298; makefile: 878; python: 532
file content (145 lines) | stat: -rw-r--r-- 4,129 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Copyright 1997 by Corporation for National Research Initiatives.
# See the file LICENSE for details.

"""Interface for using t1lib-generated bitmaps with Fredrik Lundh's
Python Imaging Library.

This module provides alternate classes for FontSetter and Glyph from the
t1lib module.  These classes, ImagingSetter and ImagingGlyph, are used by
instantiating an ImagingSetter instead of a FontSetter object.  This works
by overriding the FontSetter.newGlyph() method so that it creates
ImagingGlyph objects instead of Glyph objects.  The ImagingGlyphs have
additional methods which support the creation of PIL images.  The PIL images
available via the additional interface can be used anywhere PIL images can
be used.
"""

import Image
import string
import t1lib


class ConversionError(t1lib.T1Error):
    """Raised when a glyph cannot be converted to a PIL image."""
    pass


class DepthError(ConversionError):
    """Raised when a particular bitmap depth is required but not present."""
    def __init__(self, required, found):
	self.required = required
	self.found = found

    def __str__(self):
	return "bit depth of %d is required; found %d" \
	       % (self.required, self.found)


class ImagingSetter(t1lib.FontSetter):
    """FontSetter extension which can be used to derive PIL images."""

    __32bitmode = "RGB"

    def __init__(self, font, size, angle=0.0, spaceoff=0.0, kerning=0, bpp=1):
	"""Ensure that we don't have to deal with 16-bit bitmaps later."""
	if bpp == 16:
	    raise ValueError("setter object does not support 16-bit bitmaps")
	t1lib.FontSetter.__init__(
	    self, font, size, angle, spaceoff, kerning, bpp)

    def newGlyph(self, bits, metrics, bpp):
	"""Create a glyph which can be converted to a PIL image.

	The arguments match those of t1lib.FontSetter.newGlyph().
	"""
	height = metrics[0] + metrics[1]
	width = metrics[3] - metrics[2]
	if bpp == 1:
	    mode = "1"
	    rawmode = "1;IR"		# XXX: undocumented rawmode, but works
	elif bpp == 8:
	    mode = rawmode = "L"
	elif bpp == 24:
	    mode = "RGB"
	    rawmode = "RGBX"		# account for padding
	elif bpp == 32:
	    mode = self.__32bitmode
	    rawmode = (mode == "RGBA") and "RGBA" or "RGBX"
	im = Image.fromstring(mode, (width, height), bits, "raw", rawmode)
	im.__class__ = ImagingGlyph
	t1lib.Glyph.__init__(im, bits, metrics, bpp)
	return im

    def get32BitMode(self):
	"""Return the conversion mode for 32-bit images."""
	return self.__32bitmode

    def set32BitMode(self, mode):
	"""Set the conversion mode for 32-bit images.

	mode -- mode indicator; must be 'RGB' or 'RGBA'

	Glyphs 32 bits deep can be converted to RGB or RGBA images.
	"""
	mode = string.upper(mode)
	if mode not in ("RGB", "RGBA"):
	    raise ValueError("illegal 32-bit mode; must be 'RGB' or 'RGBA'")
	self.__32bitmode = mode

    def getmask(self, string):
	"""Rasterize a string.

	string -- the string to be rendered

	This is provided to support the ImageDraw class from the Python
	Imaging Library.  This interface allows ImageSetter instances which
	generate glyphs of 1 bit per pixel to be passed to the
	ImageDraw.setfont() method.

	If the bits-per-pixel for generated glyphs is not 1, DepthError is
	raised.
	"""
	if self.bpp != 1:
	    raise DepthError(1, self.bpp)
	return self.setString(string)


class ImagingGlyph(Image.Image, t1lib.Glyph):
    """A rasterized image which is also a PIL image."""
    pass



def test():
    """Run a stand-alone test.

    This function parses the command line.  It provides a limited self-test
    for this module.
    """
    import getopt
    import sys
    #
    fontname = "CharterBT-Roman"
    depth = 1
    fontsize = 120.0
    text = "abc"
    #
    opts, args = getopt.getopt(sys.argv[1:], "d:f:s:")
    for opt, val in opts:
	if opt == "-d":
	    depth = string.atoi(val)
	elif opt == "-f":
	    fontname = val
	elif opt == "-s":
	    fontsize = string.atof(val)
    if args:
	text = string.join(args)
    #
    font = t1lib.getFont(fontname)
    setter = ImagingSetter(font, fontsize, bpp=depth)
    glyph = setter.setString(text)
    glyph.show()


if __name__ == "__main__":
    test()