~ubuntu-branches/ubuntu/feisty/fonttools/feisty

« back to all changes in this revision

Viewing changes to Lib/fontTools/ttLib/tables/_n_a_m_e.py

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Fok
  • Date: 2003-11-18 00:53:59 UTC
  • Revision ID: james.westby@ubuntu.com-20031118005359-pqirsxbgdz0f0xmx
Tags: upstream-1.99+2.0b1+cvs20031014
ImportĀ upstreamĀ versionĀ 1.99+2.0b1+cvs20031014

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import DefaultTable
 
2
import struct, sstruct
 
3
from fontTools.misc.textTools import safeEval
 
4
import string
 
5
import types
 
6
 
 
7
nameRecordFormat = """
 
8
                >       # big endian
 
9
                platformID:     H
 
10
                platEncID:      H
 
11
                langID:         H
 
12
                nameID:         H
 
13
                length:         H
 
14
                offset:         H
 
15
"""
 
16
 
 
17
nameRecordSize = sstruct.calcsize(nameRecordFormat)
 
18
 
 
19
 
 
20
class table__n_a_m_e(DefaultTable.DefaultTable):
 
21
        
 
22
        def decompile(self, data, ttFont):
 
23
                format, n, stringOffset = struct.unpack(">HHH", data[:6])
 
24
                expectedStringOffset = 6 + n * nameRecordSize
 
25
                if stringOffset != expectedStringOffset:
 
26
                        # XXX we need a warn function
 
27
                        print "Warning: 'name' table stringOffset incorrect.",
 
28
                        print "Expected: %s; Actual: %s" % (expectedStringOffset, stringOffset)
 
29
                stringData = data[stringOffset:]
 
30
                data = data[6:]
 
31
                self.names = []
 
32
                for i in range(n):
 
33
                        name, data = sstruct.unpack2(nameRecordFormat, data, NameRecord())
 
34
                        name.string = stringData[name.offset:name.offset+name.length]
 
35
                        assert len(name.string) == name.length
 
36
                        #if (name.platEncID, name.platformID) in ((0, 0), (1, 3)):
 
37
                        #       if len(name.string) % 2:
 
38
                        #               print "2-byte string doesn't have even length!"
 
39
                        #               print name.__dict__
 
40
                        del name.offset, name.length
 
41
                        self.names.append(name)
 
42
        
 
43
        def compile(self, ttFont):
 
44
                if not hasattr(self, "names"):
 
45
                        # only happens when there are NO name table entries read
 
46
                        # from the TTX file
 
47
                        self.names = []
 
48
                self.names.sort()  # sort according to the spec; see NameRecord.__cmp__()
 
49
                stringData = ""
 
50
                format = 0
 
51
                n = len(self.names)
 
52
                stringOffset = 6 + n * sstruct.calcsize(nameRecordFormat)
 
53
                data = struct.pack(">HHH", format, n, stringOffset)
 
54
                lastoffset = 0
 
55
                done = {}  # remember the data so we can reuse the "pointers"
 
56
                for name in self.names:
 
57
                        if done.has_key(name.string):
 
58
                                name.offset, name.length = done[name.string]
 
59
                        else:
 
60
                                name.offset, name.length = done[name.string] = len(stringData), len(name.string)
 
61
                                stringData = stringData + name.string
 
62
                        data = data + sstruct.pack(nameRecordFormat, name)
 
63
                return data + stringData
 
64
        
 
65
        def toXML(self, writer, ttFont):
 
66
                for name in self.names:
 
67
                        name.toXML(writer, ttFont)
 
68
        
 
69
        def fromXML(self, (name, attrs, content), ttFont):
 
70
                if name <> "namerecord":
 
71
                        return # ignore unknown tags
 
72
                if not hasattr(self, "names"):
 
73
                        self.names = []
 
74
                name = NameRecord()
 
75
                self.names.append(name)
 
76
                name.fromXML((name, attrs, content), ttFont)
 
77
        
 
78
        def getName(self, nameID, platformID, platEncID, langID=None):
 
79
                for namerecord in self.names:
 
80
                        if (    namerecord.nameID == nameID and 
 
81
                                        namerecord.platformID == platformID and 
 
82
                                        namerecord.platEncID == platEncID):
 
83
                                if langID is None or namerecord.langID == langID:
 
84
                                        return namerecord
 
85
                return None # not found
 
86
        
 
87
        def __cmp__(self, other):
 
88
                return cmp(self.names, other.names)
 
89
        
 
90
 
 
91
class NameRecord:
 
92
        
 
93
        def toXML(self, writer, ttFont):
 
94
                writer.begintag("namerecord", [
 
95
                                ("nameID", self.nameID),
 
96
                                ("platformID", self.platformID),
 
97
                                ("platEncID", self.platEncID),
 
98
                                ("langID", hex(self.langID)),
 
99
                                                ])
 
100
                writer.newline()
 
101
                if self.platformID == 0 or (self.platformID == 3 and self.platEncID in (0, 1)):
 
102
                        if len(self.string) % 2:
 
103
                                # no, shouldn't happen, but some of the Apple
 
104
                                # tools cause this anyway :-(
 
105
                                writer.write16bit(self.string + "\0")
 
106
                        else:
 
107
                                writer.write16bit(self.string)
 
108
                else:
 
109
                        writer.write8bit(self.string)
 
110
                writer.newline()
 
111
                writer.endtag("namerecord")
 
112
                writer.newline()
 
113
        
 
114
        def fromXML(self, (name, attrs, content), ttFont):
 
115
                self.nameID = safeEval(attrs["nameID"])
 
116
                self.platformID = safeEval(attrs["platformID"])
 
117
                self.platEncID = safeEval(attrs["platEncID"])
 
118
                self.langID =  safeEval(attrs["langID"])
 
119
                if self.platformID == 0 or (self.platformID == 3 and self.platEncID in (0, 1)):
 
120
                        s = ""
 
121
                        for element in content:
 
122
                                s = s + element
 
123
                        s = unicode(s, "utf8")
 
124
                        s = s.strip()
 
125
                        self.string = s.encode("utf_16_be")
 
126
                else:
 
127
                        s = string.strip(string.join(content, ""))
 
128
                        self.string = unicode(s, "utf8").encode("latin1")
 
129
        
 
130
        def __cmp__(self, other):
 
131
                """Compare method, so a list of NameRecords can be sorted
 
132
                according to the spec by just sorting it..."""
 
133
                selftuple = (self.platformID,
 
134
                                self.platEncID,
 
135
                                self.langID,
 
136
                                self.nameID,
 
137
                                self.string)
 
138
                othertuple = (other.platformID,
 
139
                                other.platEncID,
 
140
                                other.langID,
 
141
                                other.nameID,
 
142
                                other.string)
 
143
                return cmp(selftuple, othertuple)
 
144
        
 
145
        def __repr__(self):
 
146
                return "<NameRecord NameID=%d; PlatformID=%d; LanguageID=%d>" % (
 
147
                                self.nameID, self.platformID, self.langID)