diff --git a/scripts/get-fonts.py b/scripts/get-fonts.py new file mode 100644 index 000000000..b0f55cc01 --- /dev/null +++ b/scripts/get-fonts.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 +# This script downloads several built fonts from repos of https://github.com/notofonts +# Additional fonts can be found on https://notofonts.github.io + +import os +import requests +import tempfile +import shutil +import warnings +import zipfile + +FONTDIR = os.environ.get("FONTDIR", "./fonts") + +try: + os.mkdir(FONTDIR) +except FileExistsError: + warnings.warn("Font directory already exists") + +# Fonts available in regular, bold, and italic +REGULAR_BOLD_ITALIC = ["NotoSans"] + +# Fonts available in regular and bold +REGULAR_BOLD = [ + "NotoSansAdlamUnjoined", + "NotoSansArabicUI", + "NotoSerifArmenian", + "NotoSansBalinese", + "NotoSansBamum", + "NotoSansBengaliUI", + "NotoSansCanadianAboriginal", + "NotoSansCham", + "NotoSansCherokee", + "NotoSansDevanagariUI", + "NotoSansEthiopic", + "NotoSansGeorgian", + "NotoSansGujaratiUI", + "NotoSansGurmukhiUI", + "NotoSansHebrew", + "NotoSansJavanese", + "NotoSansKannadaUI", + "NotoSansKayahLi", + "NotoSansKhmerUI", + "NotoSansLaoUI", + "NotoSansLisu", + "NotoSansMalayalamUI", + "NotoSansMyanmarUI", + "NotoSansOlChiki", + "NotoSansOriya", + "NotoSansSinhalaUI", + "NotoSansSundanese", + "NotoSansSymbols", + "NotoSansTaiTham", + "NotoSansTamilUI", + "NotoSansTeluguUI", + "NotoSansThaana", + "NotoSansThaiUI", + "NotoSerifTibetan", +] + +# Fonts with regular and black, but no bold +REGULAR_BLACK = ["NotoSansSyriac"] + +# Fonts only available in regular +REGULAR = [ + "NotoSansBatak", + "NotoSansBuginese", + "NotoSansBuhid", + "NotoSansChakma", + "NotoSansCoptic", + "NotoSansHanunoo", + "NotoSansLepcha", + "NotoSansLimbu", + "NotoSansMandaic", + "NotoSansMongolian", + "NotoSansNewTaiLue", + "NotoSansNKo", + "NotoSansOsage", + "NotoSansOsmanya", + "NotoSansSamaritan", + "NotoSansSaurashtra", + "NotoSansShavian", + "NotoSansSymbols2", + "NotoSansTagalog", + "NotoSansTagbanwa", + "NotoSansTaiLe", + "NotoSansTaiViet", + "NotoSansTifinagh", + "NotoSansVai", + "NotoSansYi", +] + +SOUTH_ASIAN_UI_FONTS = [ + "BengaliUI", + "GujaratiUI", + "GurmukhiUI", + "KannadaUI", + "MalayalamUI", + "SinhalaUI", + "TamilUI", + "TeluguUI", +] + +# hyphenated or irregular Noto repo names +NOTO_REPO_FOR_FONT = { + "NotoSans": "latin-greek-cyrillic", + "NotoSansAdlamUnjoined": "adlam", + "NotoSansCanadianAboriginal": "canadian-aboriginal", + "NotoSansKayahLi": "kayah-li", + "NotoSansNewTaiLue": "new-tai-lue", + "NotoSansOlChiki": "ol-chiki", + "NotoSansSymbols2": "symbols", + "NotoSansTaiLe": "tai-le", + "NotoSansTaiTham": "tai-tham", + "NotoSansTaiViet": "tai-viet", + "NotoSerifArmenian": "armenian", + "NotoSerifTibetan": "tibetan", +} + +# Download the fonts in the lists above +def findFontUrl(fontName, modifier): + # remove 'UI' from South Asian font names (not consistent with Arabic, Khmer, Thai) + if fontName.replace("NotoSans", "") in SOUTH_ASIAN_UI_FONTS: + fontName = fontName.replace("UI", "") + + # pick up regular and irregular repo names for path + repo = NOTO_REPO_FOR_FONT.get( + fontName, fontName.replace("NotoSans", "").replace("UI", "").lower() + ) + + return f"{repo}/fonts/{fontName}/hinted/ttf/{fontName}-{modifier}.ttf" + + +def downloadToFile(url, destination, dir=FONTDIR): + headers = {"User-Agent": "get-fonts.py/osm-carto"} + try: + r = requests.get(url, headers=headers) + if r.status_code != 200: + raise Exception + with open(os.path.join(dir, destination), "wb") as f: + f.write(r.content) + except: + raise Exception(f"Failed to download {url}") + + +for font in REGULAR_BOLD + REGULAR_BOLD_ITALIC + REGULAR_BLACK + REGULAR: + regular = f"{font}-Regular.ttf" + regularFontUrl = findFontUrl(font, "Regular") + downloadToFile(f"https://notofonts.github.io/{regularFontUrl}", regular) + + if (font in REGULAR_BOLD) or (font in REGULAR_BOLD_ITALIC): + bold = f"{font}-Bold.ttf" + boldFontUrl = findFontUrl(font, "Bold") + downloadToFile(f"https://notofonts.github.io/{boldFontUrl}", bold) + + if font in REGULAR_BOLD_ITALIC: + italic = f"{font}-Italic.ttf" + italicFontUrl = findFontUrl(font, "Italic") + downloadToFile(f"https://notofonts.github.io/{italicFontUrl}", italic) + + if font in REGULAR_BLACK: + black = f"{font}-Black.ttf" + blackFontUrl = findFontUrl(font, "Black") + downloadToFile(f"https://notofonts.github.io/{blackFontUrl}", black) + +# Other noto fonts which don't follow the URL pattern above + +# CJK fonts +downloadToFile( + "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/Japanese/NotoSansCJKjp-Regular.otf", + "NotoSansCJKjp-Regular.otf", +) +downloadToFile( + "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/Japanese/NotoSansCJKjp-Bold.otf", + "NotoSansCJKjp-Bold.otf", +) + +# Fonts in zipfiles need a temporary directory +TMPDIR = tempfile.mkdtemp(prefix="get-fonts.") + +# Noto Emoji B&W isn't available as a separate download, so we need to download the package and unzip it +downloadToFile( + "https://fonts.google.com/download?family=Noto%20Emoji", + "Noto_Emoji.zip", + dir=TMPDIR, +) +emojiPath = os.path.join(TMPDIR, "Noto_Emoji.zip") +emojiExtract = ["static/NotoEmoji-Regular.ttf", "static/NotoEmoji-Bold.ttf"] +with zipfile.ZipFile(emojiPath, "r") as zip_ref: + for file in emojiExtract: + source = zip_ref.getinfo(file) + zip_ref.extract(source, FONTDIR) + # move from FONTDIR/static/x to FONTDIR + shutil.move(os.path.join(FONTDIR, file), FONTDIR) + +downloadToFile( + "https://mirrors.dotsrc.org/osdn/hanazono-font/68253/hanazono-20170904.zip", + "hanazono.zip", + dir=TMPDIR, +) +hanazonoPath = os.path.join(TMPDIR, "hanazono.zip") +with zipfile.ZipFile(hanazonoPath, "r") as zip_ref: + for file in ["HanaMinA.ttf", "HanaMinB.ttf"]: + source = zip_ref.getinfo(file) + zip_ref.extract(source, FONTDIR) + +# clean up tmp directories +shutil.rmtree(TMPDIR) +fontdir_static = os.path.join(FONTDIR, "static") +if os.path.exists(fontdir_static): + shutil.rmtree(fontdir_static) diff --git a/scripts/get-fonts.sh b/scripts/get-fonts.sh deleted file mode 100755 index 7281752cb..000000000 --- a/scripts/get-fonts.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash -set -e - -FONTDIR="${FONTDIR:-./fonts}" - -mkdir -p "${FONTDIR}" - -# download filename url -download() { - ## Download if newer, and if curl fails, clean up and exit - curl --fail --compressed -A "get-fonts.sh/osm-carto" -o "$1" -z "$1" -L "$2" || { echo "Failed to download $1 $2"; rm -f "$1"; exit 1; } -} - -# TTF Hinted Noto Fonts - -# Fonts available in regular, bold, and italic -REGULAR_BOLD_ITALIC="NotoSans" - -# Fonts available in regular and bold -REGULAR_BOLD="NotoSansAdlamUnjoined;adlam -NotoSansArabicUI;arabic -NotoSansArmenian;armenian -NotoSansBalinese;balinese -NotoSansBamum;bamum -NotoSansBengaliUI;bengali -NotoSansCanadianAboriginal;canadian-aboriginal -NotoSansCham;cham -NotoSansCherokee;cherokee -NotoSansDevanagariUI;devanagari -NotoSansEthiopic;ethiopic -NotoSansGeorgian;georgian -NotoSansGujaratiUI;gujarati -NotoSansGurmukhiUI;gurmukhi -NotoSansHebrew;hebrew -NotoSansJavanese;javanese -NotoSansKannadaUI;kannada -NotoSansKayahLi;kayah-li -NotoSansKhmerUI;khmer -NotoSansLaoUI;lao -NotoSansLisu;lisu -NotoSansMalayalamUI;malayalam -NotoSansMyanmarUI;myanmar -NotoSansOlChiki;ol-chiki -NotoSansOriya;oriya -NotoSansSinhalaUI;sinhala -NotoSansSundanese;sundanese -NotoSansSymbols;symbols -NotoSansTaiTham;tai-tham -NotoSansTamilUI;tamil -NotoSansTeluguUI;telugu -NotoSansThaana;thaana -NotoSansThaiUI;thai -NotoSerifTibetan;tibetan" - -# Fonts with regular and black, but no bold -REGULAR_BLACK="NotoSansSyriac;syriac" - -# Fonts only available in regular -REGULAR="NotoSansBatak;batak -NotoSansBuginese;buginese -NotoSansBuhid;buhid -NotoSansChakma;chakma -NotoSansCoptic;coptic -NotoSansHanunoo;hanunoo -NotoSansLepcha;lepcha -NotoSansLimbu;limbu -NotoSansMandaic;mandaic -NotoSansMongolian;mongolian -NotoSansNewTaiLue;new-tai-lue -NotoSansNKo;nko -NotoSansOsage;osage -NotoSansOsmanya;osmanya -NotoSansSamaritan;samaritan -NotoSansSaurashtra;saurashtra -NotoSansShavian;shavian -NotoSansSymbols2;symbols -NotoSansTagalog;tagalog -NotoSansTagbanwa;tagbanwa -NotoSansTaiLe;tai-le -NotoSansTaiViet;tai-viet -NotoSansTifinagh;tifinagh -NotoSansVai;vai -NotoSansYi;yi" - -# Download the fonts in the lists above - -for font in $REGULAR_BOLD_ITALIC; do - regular="$font-Regular.ttf" - bold="$font-Bold.ttf" - italic="$font-Italic.ttf" - download "${FONTDIR}/${regular}" "https://notofonts.github.io/latin-greek-cyrillic/fonts/${font}/hinted/ttf/${regular}" - download "${FONTDIR}/${bold}" "https://notofonts.github.io/latin-greek-cyrillic/fonts/${font}/hinted/ttf/${bold}" - download "${FONTDIR}/${italic}" "https://notofonts.github.io/latin-greek-cyrillic/fonts/${font}/hinted/ttf/${italic}" -done - -for fontDir in $REGULAR_BOLD; do - IFS=";" read -r -a arr <<< "${fontDir}" - font="${arr[0]}" - subfolder="${arr[1]}" - regular="$font-Regular.ttf" - bold="$font-Bold.ttf" - # remove UI from South Asian scripts path (not consistent with Arabic, Khmer, Thai) - font="${font/BengaliUI/Bengali}" - font="${font/GujaratiUI/Gujarati}" - font="${font/GurmukhiUI/Gurmukhi}" - font="${font/KannadaUI/Kannada}" - font="${font/MalayalamUI/Malayalam}" - font="${font/SinhalaUI/Sinhala}" - font="${font/TamilUI/Tamil}" - font="${font/TeluguUI/Telugu}" - download "${FONTDIR}/${regular}" "https://notofonts.github.io/${subfolder}/fonts/${font}/hinted/ttf/${regular}" - download "${FONTDIR}/${bold}" "https://notofonts.github.io/${subfolder}/fonts/${font}/hinted/ttf/${bold}" -done - -for fontDir in $REGULAR_BLACK; do - IFS=";" read -r -a arr <<< "${fontDir}" - font="${arr[0]}" - subfolder="${arr[1]}" - regular="$font-Regular.ttf" - black="$font-Black.ttf" - download "${FONTDIR}/${regular}" "https://notofonts.github.io/${subfolder}/fonts/${font}/hinted/ttf/${regular}" - download "${FONTDIR}/${black}" "https://notofonts.github.io/${subfolder}/fonts/${font}/hinted/ttf/${black}" -done - -for fontDir in $REGULAR; do - IFS=";" read -r -a arr <<< "${fontDir}" - font="${arr[0]}" - subfolder="${arr[1]}" - regular="$font-Regular.ttf" - download "${FONTDIR}/${regular}" "https://notofonts.github.io/${subfolder}/fonts/${font}/hinted/ttf/${regular}" -done - -# Other noto fonts which don't follow the URL pattern above -download "${FONTDIR}/NotoSansCJKjp-Regular.otf" "https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/Japanese/NotoSansCJKjp-Regular.otf" -download "${FONTDIR}/NotoSansCJKjp-Bold.otf" "https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/Japanese/NotoSansCJKjp-Bold.otf" - -# Fonts in zipfiles need a temporary directory -TMPDIR=$(mktemp -d -t get-fonts.XXXXXXXXX) -trap "rm -rf ${TMPDIR} ${FONTDIR}/static" EXIT - -# Noto Emoji B&W isn't available as a separate download, so we need to download the package and unzip it -curl --fail -A "get-fonts.sh/osm-carto" -o "${TMPDIR}/Noto_Emoji.zip" -L 'https://fonts.google.com/download?family=Noto%20Emoji' - -unzip -oqq "${TMPDIR}/Noto_Emoji.zip" static/NotoEmoji-Regular.ttf static/NotoEmoji-Bold.ttf -d "${FONTDIR}" -mv "${FONTDIR}/static/NotoEmoji-Regular.ttf" "${FONTDIR}" -mv "${FONTDIR}/static/NotoEmoji-Bold.ttf" "${FONTDIR}" - -curl --fail -A "get-fonts.sh/osm-carto" -o "${TMPDIR}/hanazono.zip" -L 'https://mirrors.dotsrc.org/osdn/hanazono-font/68253/hanazono-20170904.zip' - -unzip -oqq "${TMPDIR}/hanazono.zip" HanaMinA.ttf HanaMinB.ttf -d "${FONTDIR}"