~ubuntu-branches/debian/experimental/calibre/experimental

« back to all changes in this revision

Viewing changes to src/calibre/utils/fonts/sfnt/cmap.py

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-02-12 16:45:34 UTC
  • mfrom: (1.3.38)
  • Revision ID: package-import@ubuntu.com-20130212164534-4tue9c37ui3lgdsl
Tags: 0.9.18+dfsg-1
* New upstream release. (Closes: #699700)
* Unfuzz patches.
* Add new libqt4-private-dev build dependency, required by this version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
from struct import unpack_from, calcsize, pack
14
14
from collections import OrderedDict
15
15
 
16
 
from calibre.utils.fonts.utils import get_bmp_glyph_ids, read_bmp_prefix
 
16
from calibre.utils.fonts.utils import read_bmp_prefix
17
17
from calibre.utils.fonts.sfnt import UnknownTable, max_power_of_two
18
18
from calibre.utils.fonts.sfnt.errors import UnsupportedFont
19
19
 
117
117
    return id_delta
118
118
# }}}
119
119
 
 
120
class BMPTable(object):
 
121
 
 
122
    def __init__(self, raw):
 
123
        self.raw = raw
 
124
        (self.start_count, self.end_count, self.range_offset, self.id_delta,
 
125
         self.glyph_id_len, self.glyph_id_map, self.array_len) = \
 
126
                read_bmp_prefix(raw, 0)
 
127
 
 
128
    def get_glyph_ids(self, codes):
 
129
        for code in codes:
 
130
            found = False
 
131
            for i, ec in enumerate(self.end_count):
 
132
                if ec >= code:
 
133
                    sc = self.start_count[i]
 
134
                    if sc <= code:
 
135
                        found = True
 
136
                        ro = self.range_offset[i]
 
137
                        if ro == 0:
 
138
                            glyph_id = self.id_delta[i] + code
 
139
                        else:
 
140
                            idx = ro//2 + (code - sc) + i - self.array_len
 
141
                            glyph_id = self.glyph_id_map[idx]
 
142
                            if glyph_id != 0:
 
143
                                glyph_id += self.id_delta[i]
 
144
                        yield glyph_id % 0x1000
 
145
                        break
 
146
            if not found:
 
147
                yield 0
 
148
 
 
149
    def get_glyph_map(self, glyph_ids):
 
150
        ans = {}
 
151
        for i, ec in enumerate(self.end_count):
 
152
            sc = self.start_count[i]
 
153
            for code in xrange(sc, ec+1):
 
154
                ro = self.range_offset[i]
 
155
                if ro == 0:
 
156
                    glyph_id = self.id_delta[i] + code
 
157
                else:
 
158
                    idx = ro//2 + (code - sc) + i - self.array_len
 
159
                    glyph_id = self.glyph_id_map[idx]
 
160
                    if glyph_id != 0:
 
161
                        glyph_id += self.id_delta[i]
 
162
                glyph_id %= 0x1000
 
163
                if glyph_id in glyph_ids and code not in ans:
 
164
                    ans[code] = glyph_id
 
165
        return ans
 
166
 
120
167
class CmapTable(UnknownTable):
121
168
 
122
169
    def __init__(self, *args, **kwargs):
147
194
            if table:
148
195
                fmt = unpack_from(b'>H', table)[0]
149
196
                if platform == 3 and encoding == 1 and fmt == 4:
150
 
                    self.bmp_table = table
 
197
                    self.bmp_table = BMPTable(table)
151
198
 
152
199
    def get_character_map(self, chars):
153
200
        '''
159
206
        chars = list(set(chars))
160
207
        chars.sort()
161
208
        ans = OrderedDict()
162
 
        for i, glyph_id in enumerate(get_bmp_glyph_ids(self.bmp_table, 0,
163
 
            chars)):
 
209
        for i, glyph_id in enumerate(self.bmp_table.get_glyph_ids(chars)):
164
210
            if glyph_id > 0:
165
211
                ans[chars[i]] = glyph_id
166
212
        return ans
167
213
 
168
 
    def get_char_codes(self, glyph_ids):
 
214
    def get_glyph_map(self, glyph_ids):
 
215
        '''
 
216
        Get a mapping of character codes to glyph ids for the specified glyph
 
217
        ids.
 
218
        '''
169
219
        if self.bmp_table is None:
170
220
            raise UnsupportedFont('This font has no Windows BMP cmap subtable.'
171
221
                    ' Most likely a special purpose font.')
172
 
        ans = {}
173
 
        (start_count, end_count, range_offset, id_delta, glyph_id_len,
174
 
        glyph_id_map, array_len) = read_bmp_prefix(self.bmp_table, 0)
175
 
 
176
222
        glyph_ids = frozenset(glyph_ids)
177
 
 
178
 
        for i, ec in enumerate(end_count):
179
 
            sc = start_count[i]
180
 
            ro = range_offset[i]
181
 
            for code in xrange(sc, ec+1):
182
 
                if ro == 0:
183
 
                    glyph_id = id_delta[i] + code
184
 
                else:
185
 
                    idx = ro//2 + (code - sc) + i - array_len
186
 
                    glyph_id = glyph_id_map[idx]
187
 
                    if glyph_id != 0:
188
 
                        glyph_id += id_delta[i]
189
 
                glyph_id %= 0x1000
190
 
                if glyph_id in glyph_ids:
191
 
                    ans[glyph_id] = code
192
 
 
193
 
        return ans
 
223
        return self.bmp_table.get_glyph_map(glyph_ids)
194
224
 
195
225
    def set_character_map(self, cmap):
196
226
        self.version, self.num_tables = 0, 1