1# This script gathers Noto versions from third-party sources. 2# It's designed to run on Simon's computer, and probably not 3# anywhere else. 4import json 5import os 6import platform 7import plistlib 8import re 9from collections import defaultdict 10from pathlib import Path 11 12import requests 13from fontTools.ttLib import TTFont 14from gfpipeline import \ 15 FontFamilies # This is a private module, you won't find it 16from tqdm import tqdm 17 18MACOS_PATH = Path("/System/Library/Fonts/") 19MAC_VERSION = "macOS " + re.sub(r".\d+$", "", platform.mac_ver()[0]) 20 21IOS_PATH_1 = Path( 22 "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Fonts/UnicodeSupport/" 23) 24IOS_PATH_2 = Path(IOS_PATH_1.parent) / "Core" 25 26ANDROID_PATH = Path("~/Downloads/android_fonts-master/api_level/").expanduser() 27LATEST_ANDROID_PATH = sorted(list(ANDROID_PATH.glob("??")))[-1] 28IOS_VERSION_PATH = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Info.plist" 29IOS_VERSION = plistlib.load(open(IOS_VERSION_PATH, "rb"))["CFBundleExecutable"] 30 31ANDROID_API_VERSION_MAP = { 32 "31": "Android 12", 33 "32": "Android 12L", 34 "33": "Android 13", 35} 36 37ANDROID_VERSION = ANDROID_API_VERSION_MAP[LATEST_ANDROID_PATH.stem] 38 39# These will need manual updates 40FEDORA_VERSION = "Fedora 38" 41FEDORA_SRC = "https://kojipkgs.fedoraproject.org//packages/google-noto-fonts/20201206^1.git0c78c8329/9.fc38/src/google-noto-fonts-20201206^1.git0c78c8329-9.fc38.src.rpm" 42FEDORA_TAR = "noto-fonts-0c78c8329.tar.xz" 43 44 45notoversions = defaultdict(dict) 46 47 48def tidy_name(name): 49 if "Old Italic" not in name: 50 name = re.sub(r" Italic", "", name) 51 if "Hmong Nyiakeng" in name: 52 name = "Noto Serif Nyiakeng Puachue Hmong" 53 name = re.sub(r"( (Regular|Bold|Black))+$", "", name) 54 name = re.sub(r" PhagsPa$", " Phags Pa", name) 55 return name 56 57 58def tidy_version(name5version): 59 version = re.sub(";.*", "", name5version) 60 version = re.sub("Version ", "", version) 61 return version 62 63 64def register_version(file, system): 65 global notoversions 66 ttfont = TTFont(file, fontNumber=0) 67 name = tidy_name(ttfont["name"].getDebugName(4)) 68 if "Emoji" in name: 69 return 70 version = "%1.3f" % ttfont["head"].fontRevision 71 notoversions[name][system] = version 72 73 74if __name__ == "__main__": 75 for file in (IOS_PATH_1).glob("Noto*.tt?"): 76 register_version(file, IOS_VERSION) 77 for file in (IOS_PATH_2).glob("Noto*.tt?"): 78 register_version(file, IOS_VERSION) 79 80 assert "Noto Sans Armenian" in notoversions 81 82 for file in MACOS_PATH.glob("Noto*.tt?"): 83 register_version(file, MAC_VERSION) 84 85 for file in (MACOS_PATH / "Supplemental/").glob("Noto*.tt?"): 86 register_version(file, MAC_VERSION) 87 88 for file in (LATEST_ANDROID_PATH).glob("Noto*.tt?"): 89 register_version(file, ANDROID_VERSION) 90 91 # Fedora 38 92 if not os.path.exists(FEDORA_TAR): 93 if not os.path.exists("noto-fedora.src.rpm"): 94 response = requests.get(FEDORA_SRC, stream=True) 95 total_size_in_bytes = int(response.headers.get("content-length", 0)) 96 print("Downloading Fedora 38 sources") 97 progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True) 98 with open("noto-fedora.src.rpm", "wb") as file: 99 for data in response.iter_content(1024): 100 progress_bar.update(len(data)) 101 file.write(data) 102 progress_bar.close() 103 print("Opening RPM") 104 os.system("rpm2cpio noto-fedora.src.rpm | cpio -id noto-fonts-0c78c8329.tar.xz") 105 if not os.path.exists("fedora-noto"): 106 os.makedirs("fedora-noto") 107 os.system( 108 " xz -dc " + FEDORA_TAR + " | tar -C fedora-noto -xf - '*Regular.ttf'" 109 ) 110 111 for file in Path("fedora-noto").glob("**/Noto*.tt?"): 112 register_version(file, "Fedora 38") 113 114 # Google Fonts 115 versions = FontFamilies(list(notoversions.keys())) 116 for family_dict in versions.data: 117 notoversions[family_dict["name"]]["Google Fonts"] = tidy_version( 118 family_dict["production"]["version_nameid5"] 119 ) 120 121 json.dump( 122 notoversions, open("docs/versions.json", "w"), indent=True, sort_keys=True 123 ) 124