├── .gitignore ├── .vscode └── settings.json ├── .github └── workflows │ └── build.yml └── extract.py /.gitignore: -------------------------------------------------------------------------------- 1 | data 2 | out 3 | .venv 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build msyh 2 | on: 3 | push: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | container: archlinux:latest 11 | steps: 12 | - name: Install dependencies 13 | run: pacman -Syu --noconfirm git fontforge curl p7zip jq 14 | - uses: actions/checkout@v2 15 | - name: Grab latest version 16 | run: | 17 | curl -L https://api.github.com/repos/be5invis/Sarasa-Gothic/releases/latest -o api.json 18 | UPSTREAM_VERSION=$(cat api.json | jq -r .tag_name) 19 | DOWNLOAD_URL=$(cat api.json | jq -r '.assets[] | select(.name | test("sarasa-gothic-ttc-(?!unhinted)")) | .browser_download_url') 20 | echo "UPSTREAM_VERSION=$UPSTREAM_VERSION" >> $GITHUB_ENV 21 | echo "DOWNLOAD_URL=$DOWNLOAD_URL" >> $GITHUB_ENV 22 | - name: Download font 23 | run: curl -Lvo /tmp/ttc.7z $DOWNLOAD_URL 24 | - name: Extract font 25 | run: 7z x -odata /tmp/ttc.7z 26 | - name: Run script 27 | run: | 28 | mkdir out 29 | python3 extract.py 30 | - name: Compress font 31 | run: | 32 | cd out 33 | 7z a ../out.zip * 34 | - name: Upload artifact 35 | uses: actions/upload-artifact@v2 36 | with: 37 | name: out 38 | path: out 39 | - name: Upload release 40 | uses: marvinpinto/action-automatic-releases@latest 41 | with: 42 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 43 | automatic_release_tag: "upstream-${{ env.UPSTREAM_VERSION }}" 44 | prerelease: true 45 | title: Nightly build 46 | files: out.zip 47 | -------------------------------------------------------------------------------- /extract.py: -------------------------------------------------------------------------------- 1 | import re 2 | import fontforge as ff 3 | from glob import glob 4 | 5 | class TTFTask: 6 | def __init__(self, font, variant, ui) -> None: 7 | self.font = font 8 | for locale, name, value in font.sfnt_names: 9 | if name == "Preferred Styles": 10 | self.variant = value 11 | break 12 | self.ui = ui 13 | 14 | def get_subfamily(self): 15 | return None 16 | 17 | def edit(self): 18 | enusr = "Microsoft YaHei" 19 | if self.ui: 20 | enusr = "Microsoft YaHei UI" 21 | enus = enusr + " " + self.variant 22 | zhcnr = "微软雅黑" 23 | if self.ui: 24 | zhcnr = enusr 25 | zhcn = zhcnr + " " + self.variant 26 | if self.variant == "Regular": 27 | enus = enusr 28 | zhcn = zhcnr 29 | # self.font.fullname = enus 30 | self.font.fontname = enus.replace(" ", "") 31 | self.font.fullname = enus 32 | self.font.familyname = enusr 33 | print(self.font.fontname) 34 | print(self.font.fullname) 35 | print(self.font.familyname) 36 | self.font.appendSFNTName("English (US)", "Family", enusr) 37 | self.font.appendSFNTName("English (US)", "UniqueID", enus) 38 | self.font.appendSFNTName("English (US)", "Fullname", enus) 39 | self.font.appendSFNTName("English (US)", "Preferred Family", enusr) 40 | self.font.appendSFNTName("Chinese (PRC)", "Family", zhcnr) 41 | self.font.appendSFNTName("Chinese (PRC)", "UniqueID", zhcn) 42 | self.font.appendSFNTName("Chinese (PRC)", "Fullname", zhcn) 43 | self.font.appendSFNTName("Chinese (PRC)", "Preferred Family", zhcnr) 44 | for (lang, key, field) in self.font.sfnt_names: 45 | print(lang, '%s=%s'%(key, field)) 46 | # print(self.font.sfnt_names) 47 | 48 | class TTCFile: 49 | def __init__(self, file, variant): 50 | self.file = file 51 | self.variant = variant 52 | self.output = transformVariant(variant) 53 | 54 | def openTTF(self, isui): 55 | target = "Sarasa Gothic SC" 56 | if isui: 57 | target = "Sarasa UI SC" 58 | font = ff.open('%s(%s%s)'%(self.file, target, self.variant)) 59 | return TTFTask(font, self.variant, isui) 60 | 61 | def build(self): 62 | ttf = self.openTTF(False) 63 | ttf.edit() 64 | ttfui = self.openTTF(True) 65 | ttfui.edit() 66 | ttf.font.generateTtc("out/%s"%self.output, ttfui.font, ttcflags = ("merge"), layer = 1) 67 | ttf.font.close() 68 | ttfui.font.close() 69 | 70 | def __str__(self) -> str: 71 | return 'TTCFile(%s, %s) -> %s'%(self.file, self.variant, self.output) 72 | 73 | def listTtc(pattern): 74 | for ttc in glob(pattern): 75 | for face in ff.fontsInFile(ttc): 76 | if m := re.match(r"Sarasa Gothic SC(.*)?", face): 77 | yield TTCFile(ttc, m.group(1)) 78 | 79 | def transformVariant(input): 80 | ret = "msyh" 81 | if "Bold" in input: 82 | ret += "bd" 83 | if "Semibold" in input: 84 | ret += "sb" 85 | if "Light" in input: 86 | ret += "l" 87 | if "Xlight" in input: 88 | ret += "xl" 89 | if "Italic" in input: 90 | ret += "i" 91 | return ret + ".ttc" 92 | 93 | for ttc in listTtc("data/*.ttc"): 94 | print(ttc) 95 | ttc.build() --------------------------------------------------------------------------------