87 lines
1.9 KiB
Python
Executable File
87 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import enum
|
|
import graphite2
|
|
|
|
from argparse import ArgumentParser
|
|
|
|
|
|
class Dir(enum.IntEnum):
|
|
ltr = 0
|
|
rtl = 1
|
|
|
|
def usv(v): return int(v,16)
|
|
|
|
|
|
p = ArgumentParser()
|
|
p.add_argument('fontname', help='font file')
|
|
p.add_argument('codes', nargs='+', type=usv, help='USV codes')
|
|
p.add_argument('--ppm', type=int, default=96, help='Pixels per EM')
|
|
p.add_argument('--script', type=bytes, default=b'latn', help='Script tag')
|
|
p.add_argument('--dir', type=Dir, choices=[Dir.ltr, Dir.rtl],
|
|
default=Dir.ltr,
|
|
help='Text direction')
|
|
|
|
args = p.parse_args()
|
|
|
|
face = graphite2.Face(args.fontname)
|
|
font = graphite2.Font(face, args.ppm)
|
|
|
|
args.codes = ''.join(chr(c) for c in args.codes)
|
|
seg = graphite2.Segment(font, face, args.script, args.codes, args.dir)
|
|
print(f'Glyphs: {[s.gid for s in seg.slots]!r}')
|
|
|
|
def reordering_clusters(seg):
|
|
slots_first = seg.cinfo(0).before
|
|
slots_last = seg.cinfo(0).after
|
|
char_first = 0
|
|
|
|
for n in range(1,seg.num_cinfo):
|
|
ci = seg.cinfo(n)
|
|
|
|
slots_first = min(ci.before, slots_first)
|
|
if ci.before > slots_last:
|
|
yield (char_first, slots_last)
|
|
char_first = n
|
|
slots_first = ci.before
|
|
|
|
slots_last = max(ci.after, slots_last)
|
|
|
|
yield (char_first, slots_last)
|
|
|
|
|
|
print(list(reordering_clusters(seg)))
|
|
|
|
|
|
def clusters(seg):
|
|
slots = seg.slots
|
|
bounds = reordering_clusters(seg)
|
|
|
|
glyphs = [slots[0].index]
|
|
fc,ls = next(bounds)
|
|
|
|
for s in slots[1:]:
|
|
if s.index > ls:
|
|
fc_,ls = next(bounds)
|
|
if s.insert_before:
|
|
yield (fc_ - fc, glyphs)
|
|
fc = fc_
|
|
glyphs = []
|
|
glyphs.append(s.index)
|
|
yield (seg.num_cinfo - fc, glyphs)
|
|
|
|
print(list(clusters(seg)))
|
|
|
|
# 1a23 1a6e 1a55 1a60 1a75 1a26 1a23 1a6e 1a55 1a60 1a75 1a26
|
|
# [73, 4, 27, 76, 102, 73), 4, 27, 76, 102, 73, 4, 27, 76, 102]
|
|
|
|
|
|
# 1a23 1a6e 1a55 1a60 1a75 1a26: [73, 4, 27, 76, 102]
|
|
# 1a23 1a6e 1a55: [73]
|
|
|
|
|
|
|
|
|
|
|