| 355 | ## TrueTypeFont |
| 356 | ## |
| 357 | class TrueTypeFont(object): |
| 358 | |
| 359 | class CMapNotFound(Exception): pass |
| 360 | |
| 361 | def __init__(self, name, fp): |
| 362 | self.name = name |
| 363 | self.fp = fp |
| 364 | self.tables = {} |
| 365 | self.fonttype = fp.read(4) |
| 366 | (ntables, _1, _2, _3) = struct.unpack('>HHHH', fp.read(8)) |
| 367 | for _ in xrange(ntables): |
| 368 | (name, tsum, offset, length) = struct.unpack('>4sLLL', fp.read(16)) |
| 369 | self.tables[name] = (offset, length) |
| 370 | return |
| 371 | |
| 372 | def create_unicode_map(self): |
| 373 | if 'cmap' not in self.tables: |
| 374 | raise TrueTypeFont.CMapNotFound |
| 375 | (base_offset, length) = self.tables['cmap'] |
| 376 | fp = self.fp |
| 377 | fp.seek(base_offset) |
| 378 | (version, nsubtables) = struct.unpack('>HH', fp.read(4)) |
| 379 | subtables = [] |
| 380 | for i in xrange(nsubtables): |
| 381 | subtables.append(struct.unpack('>HHL', fp.read(8))) |
| 382 | char2gid = {} |
| 383 | # Only supports subtable type 0, 2 and 4. |
| 384 | for (_1, _2, st_offset) in subtables: |
| 385 | fp.seek(base_offset+st_offset) |
| 386 | (fmttype, fmtlen, fmtlang) = struct.unpack('>HHH', fp.read(6)) |
| 387 | if fmttype == 0: |
| 388 | char2gid.update(enumerate(struct.unpack('>256B', fp.read(256)))) |
| 389 | elif fmttype == 2: |
| 390 | subheaderkeys = struct.unpack('>256H', fp.read(512)) |
| 391 | firstbytes = [0]*8192 |
| 392 | for (i,k) in enumerate(subheaderkeys): |
| 393 | firstbytes[k/8] = i |
| 394 | nhdrs = max(subheaderkeys)/8 + 1 |
| 395 | hdrs = [] |
| 396 | for i in xrange(nhdrs): |
| 397 | (firstcode,entcount,delta,offset) = struct.unpack('>HHhH', fp.read(8)) |
| 398 | hdrs.append((i,firstcode,entcount,delta,fp.tell()-2+offset)) |
| 399 | for (i,firstcode,entcount,delta,pos) in hdrs: |
| 400 | if not entcount: continue |
| 401 | first = firstcode + (firstbytes[i] << 8) |
| 402 | fp.seek(pos) |
| 403 | for c in xrange(entcount): |
| 404 | gid = struct.unpack('>H', fp.read(2)) |
| 405 | if gid: |
| 406 | gid += delta |
| 407 | char2gid[first+c] = gid |
| 408 | elif fmttype == 4: |
| 409 | (segcount, _1, _2, _3) = struct.unpack('>HHHH', fp.read(8)) |
| 410 | segcount /= 2 |
| 411 | ecs = struct.unpack('>%dH' % segcount, fp.read(2*segcount)) |
| 412 | fp.read(2) |
| 413 | scs = struct.unpack('>%dH' % segcount, fp.read(2*segcount)) |
| 414 | idds = struct.unpack('>%dh' % segcount, fp.read(2*segcount)) |
no outgoing calls
no test coverage detected
searching dependent graphs…