Skip to content

Commit

Permalink
font modding
Browse files Browse the repository at this point in the history
  • Loading branch information
wchristian committed Dec 8, 2018
1 parent 1d59343 commit 207a9c2
Show file tree
Hide file tree
Showing 7 changed files with 591 additions and 0 deletions.
221 changes: 221 additions & 0 deletions font_manipulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# adapted from https://svn.code.sf.net/p/unifraktur/code

# -*- coding: utf-8 -*-

import fileinput
import os
import shutil
import ast

def string_auswerten(string):
try:
string = ast.literal_eval(string)
except ValueError:
pass
return string

def glyph_nach_datei(glyph):
if glyph.startswith("uni"):
return glyph + ".glyph"
elif glyph == " ":
return "space.glyph"
else:
chars = list(glyph)
i = 0
while i < len(chars):
if chars[i].isupper():
chars.insert(i, "_")
i+=1
i+=1
return "".join(chars) + ".glyph"

def stems_zerlegen(stemstring):
ausgabe = []
for stem in stemstring.split(">"):
if stem.strip():
ebene = stem.split("<")[0].split()
positionen_roh = stem.split("<")[1].split()
positionen = map(list,zip(*[iter(positionen_roh)]*2))
ausgabe += [[ebene, positionen]]
return ausgabe

def stems_vereinen(stemslist):
ausgabe = []
for stem in [stem for stems in stemslist for stem in stems]:
neu = True
for bestehender_stem in ausgabe:
if stem[0] == bestehender_stem[0]:
bestehender_stem[1] += stem[1]
neu = False
break
if neu:
ausgabe += [stem]
return ausgabe

def stems_nach_string(stems):
ausgabe = ""
for stem in stems:
ausgabe += " ".join(stem[0])
ausgabe += "<"
ausgabe += " ".join([komp for position in stem[1] for komp in position])
ausgabe += "> "
return ausgabe

class Schrift:
def __init__(self, name, quellordner, zielordner):
self.name = name
self.ordner = zielordner
if self.ordner in os.listdir("."):
raise Exception("Fehler: Zielordner existiert bereits.")
return None
else:
os.mkdir(self.ordner)

self.props = []

for datei in os.listdir(quellordner):
if os.path.isfile(quellordner + "/" + datei):
shutil.copy(quellordner + "/" + datei, self.ordner)

self.props_oeffnen()
for i,zeile in enumerate(self.props):
for nameString in ["FontName:", "FullName:", "FamilyName:"]:
if zeile.startswith(nameString):
self.props[i] = nameString + " " + self.name + "\n"

def __del__(self):
self.props_schliessen()

def props_oeffnen(self):
if not self.props:
with open(self.ordner + "/font.props", "rb") as propsdatei:
self.props = propsdatei.readlines()

def props_schliessen(self):
if self.props:
with open(self.ordner + "/font.props", "wb") as propsdatei:
propsdatei.writelines(self.props)

def ersetzen_durch_Kompositglyph(self, ziel, teil1, teil2):
teile = (teil1,teil2)
self._ersetzen_durch_Kompositglyph(ziel, teile)

def _ersetzen_durch_Kompositglyph(self, ziel, teile):
breiten = []
encodings = []
hstems = []
vstems = []
dstems = []
verschiebungen = []
verschiebungen.append(0)

self.props_oeffnen()
in_kerningtabelle = True
anzahl_vor = None
kerning_start = None
indizes = [None, None]
j = None
kerning = 0
for i,zeile in enumerate(self.props):
if zeile.startswith("KernClass2"):
in_kerningtabelle = True
anzahl_vor = int(zeile.split()[1])
j = anzahl_vor-1
anzahl_nach = int(zeile.split()[2])
kerning_start = i
elif in_kerningtabelle:
if zeile.startswith(" "):
if ("{}" in zeile):
if all(indizes):
a = indizes[0] - kerning_start
b = indizes[1] - kerning_start - anzahl_vor + 1
kerning = int(zeile.split("{}")[a*anzahl_nach+b])
else:
inhalt = zeile.split()[1:]
if teile[j>0] in inhalt:
inhalt += [ziel]
if teile[j<=0] in inhalt:
indizes[j<=0] = i
neuer_inhalt = " ".join(inhalt)
self.props[i] = " " + str(len(neuer_inhalt)) + " " + neuer_inhalt + "\n"
j -= 1
continue

in_kerningtabelle = False
kerning_start = None
anzahl_vor = None
indizes = [None, None]
j = None

for i,teil in enumerate(teile):
for zeile in open(self.ordner + "/" + glyph_nach_datei(teil), "rb"):
if zeile.startswith("Width:"):
breiten += [int(zeile.split()[1])]
elif zeile.startswith("Encoding:"):
encodings += [zeile.split()[2:]]
elif zeile.startswith("HStem:"):
hstems += [stems_zerlegen(zeile[7:-1])]
elif zeile.startswith("VStem:"):
vstems += [stems_zerlegen(zeile[7:-1])]
elif zeile.startswith("DStem2:"):
dstems += [stems_zerlegen(zeile[8:-1])]

zieldatei = glyph_nach_datei(ziel)

first = True
for j,teil in enumerate(teile):
if(first):
first = False
continue

verschiebung = kerning
r = range(0, j)
for x in r:
verschiebung = verschiebung + breiten[x]
verschiebungen.append(verschiebung)

if j < len(hstems):
for hstem in hstems[j]:
for position in hstem[1]:
for i in (0,1):
position[i] = str(string_auswerten(position[i]) + verschiebung)

if j < len(vstems):
for vstem in vstems[j]:
vstem[0][0] = str(string_auswerten(vstem[0][0]) + verschiebung)

if j < len(dstems):
for dstem in dstems[j]:
for i in (0,2):
dstem[0][i] = str(string_auswerten(dstem[0][i]) + verschiebung)

for zeile in fileinput.input (self.ordner + "/" + zieldatei, inplace=1):
if (
zeile.startswith("StartChar:")
or zeile.startswith("Encoding:")
or zeile.startswith("VWidth:")
or zeile.startswith("GlyphClass:")
or zeile.startswith("Flags:")
or zeile.startswith("EndChar")
):
print zeile,
elif zeile.startswith("Fore"):
print zeile,
for j,teil in enumerate(teile):
print "Refer: %s %s N 1 0 0 1 %s 0 2" % (encodings[j][1], encodings[j][0], verschiebungen[j])
elif zeile.startswith("Width:"):
print "Width: %i" % (sum(map(int, breiten))+kerning)
elif zeile.startswith("LayerCount:"):
print zeile,

stemstring = stems_nach_string(stems_vereinen(hstems))
if stemstring:
print "HStem: " + stems_nach_string(stems_vereinen(hstems))

stemstring = stems_nach_string(stems_vereinen(vstems))
if stemstring:
print "VStem: " + stems_nach_string(stems_vereinen(vstems))

stemstring = stems_nach_string(stems_vereinen(dstems))
if stemstring:
print "DStem2: " + stems_nach_string(stems_vereinen(dstems))
2 changes: 2 additions & 0 deletions font_mod_character_pairs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Str|ate|Ret|urn|Adm|ira|l C|Cho|ose
Sel|ect
18 changes: 18 additions & 0 deletions font_mod_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from font_manipulator import *
import itertools

start_unicode = "0xE000"
unicode_point_int = int(start_unicode, 0)
pairs = [line.rstrip('\n').split("|") for line in open('font_mod_character_pairs')]
pairs = filter(None, list(itertools.chain.from_iterable(pairs)))

name = "A-OTF-UDShinGoPro-Regular"
M20 = Schrift(name, "../"+name+".sfdir", "../"+name+"_mod.sfdir")

for pair in pairs:
name = "uni%X" % unicode_point_int
M20._ersetzen_durch_Kompositglyph(name, list(pair))
unicode_point_int = unicode_point_int + 1
Loading

0 comments on commit 207a9c2

Please sign in to comment.