diff --git a/README.md b/README.md index ab7be32..1fb2653 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,20 @@ # Go Noto Universal -Noto fonts go universal! Download Noto fonts combined to suit your region (South Asia, SE Asia, East -Asia, Africa-MiddleEast, Europe-Americas). +Noto fonts go universal! Download merged [Noto Fonts](https://github.com/googlefonts/noto-fonts) +according to region-based or time-based combination. -This software combines/merges multiple [Noto Fonts](https://github.com/googlefonts/noto-fonts) to a -single, region-specific font. +We offer two types of pan-Unicode converged fonts: + +1. Time-based: + - `GoNotoCurrent.ttf` covers pretty much all the scripts in current, widespread use all over the + world. This is designed to be a "good enough" font for modern, living scripts without being + exhaustive. If you're unsure what to download, just go with this. + - `GoNotoAncient.ttf` covers all the historical, obsolete and liturgical scripts. +2. Region-based: + Choose a single font based on where you live or whichever region you're interested in: + Africa - Middle East, East Asia, Europe - Americas, South Asia or South East Asia. + +See [caveats](#caveats) too. ## Download @@ -13,8 +23,8 @@ page](https://github.com/satbyy/go-noto-universal/releases/) and download what y Development builds are available from [GitHub Actions](https://github.com/satbyy/go-noto-universal/actions) page. Click on any workflow with green -checkmark ✅ (pipeline passed) and under "Artifacts", download "GoNotoUniversal.zip" (login -required). +checkmark ✅ (pipeline passed) and under "Artifacts", download "GoNotoTemporalFonts.zip" and +"GoNotoRegionalFonts.zip" (login required). ## Build @@ -23,31 +33,53 @@ If you want to _build_ the fonts yourself, create a virtual environment (venv) a ``` python3 -m venv venv_fonty source venv_fonty/bin/activate -./run.sh +./temporal_fonts.sh # generates GoNotoAncient.ttf and GoNotoCurrent.ttf +./regional_fonts.sh # generates GoNoto[AfricaMiddleEast|EuropeAmericas|...].ttf deactivate ``` -Font generation can take 10 to 20 min, depending on your computer's capabilities. +Font generation can take 15 to 30 min, depending on your computer's capabilities. -`run.sh` is designed to be reentrant, so you can run it multiple times without altering the working -state of the repository or downloading stuff again and again. +Each script is designed to be reentrant, so you can run it multiple times without altering the +working state of the repository or downloading stuff again and again. Latest CI status: -[![CI](https://github.com/satbyy/go-noto-universal/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/satbyy/go-noto-universal/actions/workflows/main.yml) +[![Regional fonts](https://github.com/satbyy/go-noto-universal/actions/workflows/regional_fonts.yml/badge.svg)](https://github.com/satbyy/go-noto-universal/actions/workflows/regional_fonts.yml) + +[![Temporal fonts](https://github.com/satbyy/go-noto-universal/actions/workflows/temporal_fonts.yml/badge.svg)](https://github.com/satbyy/go-noto-universal/actions/workflows/temporal_fonts.yml) ## Dependencies -There is no dependency other than [`nototools`](https://github.com/googlefonts/nototools) and -[`fonttools`](https://github.com/fonttools/fonttools/). Both are automatically fetched and used. +[`fonttools`](https://github.com/fonttools/fonttools/) is automatically fetched and used. + ## Coverage -Fonts are merged/combined as per the regions defined in the [Unicode Standard +### Temporal Fonts + +Temporal, i.e., time-based fonts are: + +- **Go Noto Current** -- combines 80+ Noto fonts of scripts which are in current, daily usage. It is + a superset of all the "[Regional Fonts](#regional-fonts)" (see below) excluding historical or + specialty fonts. It includes support for Chinese, Japanese and Korean (CJK) too, using the [Unihan + IICore][1] subset. +- **Go Noto Ancient** -- combines 70+ Noto fonts of ancient, historical or liturgical scripts which + are not used widely today. This font is probably useful for research or scholarly purposes or + language enthusiasts. This font does not support any CJK. + +Each of these fonts includes Noto Sans (Regular), Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans +Math and Noto Music so that notations, symbols and emoji are not missed out. + +The exact fonts which are combined are too long to list here but can be seen from the source code. + +### Regional Fonts + +These fonts are merged/combined as per the regions defined in the [Unicode Standard (pdf)](https://www.unicode.org/versions/Unicode14.0.0/UnicodeStandard-14.0.pdf). Chapter numbers below refer to that spec. -| Regional font | Coverage | +| Go Noto font | Coverage | |----------------------------|-----------------------------------------------------------------------------------------| | GoNotoEuropeAmericas.ttf | "Europe" - ch. 7, 8, "Americas" - ch 20, "Notational Systems" - ch 21 | | GoNotoAfricaMiddleEast.ttf | "Middle East" - ch. 9, 10, 11 and "Africa" - ch. 19 | @@ -108,9 +140,8 @@ Noto fonts do not exist for Chorasmian. ### Go Noto East Asia -Tibetan, Lisu, Marchen, Miao, Yi, etc. excluding Han/CJK (Chinese-Japanese-Korean). - -Mongolian, Nüshu and Tangut could not be included. +Lisu, Marchen, Miao, Mongolian, Nüshu, Tangut, Tibetan, Yi, etc. excluding Han/CJK +(Chinese-Japanese-Korean). Vertical text writing is not supported. ### Go Noto CJK Core 2005 @@ -132,30 +163,32 @@ fonts have "vmtx" table, which is absent in other fonts, thus preventing `pyftme ## Font Statistics -Statistics below correspond to release v3.0. +Statistics below correspond to release v4.0. -| Regional font | Code blocks | Codepoints | Glyphs | -|----------------------------|------------:|-----------:|-------:| -| GoNotoEuropeAmericas.ttf | 120 | 13389 | 53570 | -| GoNotoAfricaMiddleEast.ttf | 128 | 16053 | 20329 | -| GoNotoSouthAsia.ttf | 117 | 11502 | 21553 | -| GoNotoAsiaHistorical.ttf | 122 | 11001 | 18248 | -| GoNotoSouthEastAsia.ttf | 111 | 10786 | 15013 | -| GoNotoEastAsia.ttf | 109 | 18708 | 25043 | -| GoNotoCJKCore2005.ttf | 20 | 10338 | 20099 | +| Go Noto Font | Unicode blocks | Characters | Glyphs | +|----------------------------|---------------:|-----------:|-------:| +| GoNotoCurrent.ttf | 196 | 32710 | 61456 | +| GoNotoAncient.ttf | 175 | 24429 | 33469 | +| GoNotoEuropeAmericas.ttf | 120 | 13389 | 53570 | +| GoNotoAfricaMiddleEast.ttf | 128 | 16053 | 20333 | +| GoNotoSouthAsia.ttf | 117 | 11502 | 21382 | +| GoNotoAsiaHistorical.ttf | 122 | 11001 | 18248 | +| GoNotoSouthEastAsia.ttf | 111 | 10786 | 15013 | +| GoNotoEastAsia.ttf | 109 | 18708 | 25043 | +| GoNotoCJKCore2005.ttf | 20 | 10338 | 20522 | NotoSansSignWriting alone contributes about 37900 glyphs to GoNotoEuropeAmericas.ttf. Note that each of the above (except CJKCore2005) include statistics of: -| Upstream font | Code blocks | Codepoints | Glyphs | -|---------------------|------------:|-----------:|-------:| -| Noto Sans | 37 | 2840 | 3317 | -| Noto Sans Math | 22 | 2472 | 2655 | -| Noto Music | 7 | 559 | 579 | -| Noto Sans Symbols | 15 | 840 | 1218 | -| Noto Sans Symbols 2 | 37 | 2655 | 2674 | -| Total | 111 | 8807 | 9864 | +| Upstream font | Unicode blocks | Characters | Glyphs | +|---------------------|---------------:|-----------:|-------:| +| Noto Sans | 37 | 2840 | 3317 | +| Noto Sans Math | 22 | 2472 | 2655 | +| Noto Music | 7 | 559 | 579 | +| Noto Sans Symbols | 15 | 840 | 1218 | +| Noto Sans Symbols 2 | 37 | 2655 | 2674 | +| Total | 111 | 8807 | 9864 | ## Caveats @@ -171,6 +204,9 @@ Note that each of the above (except CJKCore2005) include statistics of: `vmtx`/`vhea`. 4. GoNotoCJKCore2005 does not contain Noto Sans Math and Noto Sans Symbols because fonttools does not support merging CFF with others. +5. Go Noto Current has limited support for CJK -- it offers the full Unihan IICore subset plus a few + more glyphs, so it should work ok-ish for daily use but there can be missing glyphs. As before, + vertical text writing is not supported with this font. ## License @@ -185,7 +221,10 @@ Version 1.1, as required by the upstream Noto Fonts Project. FontTools package comes with nice utilities `ttx` (ttf to xml and back), `pyftsubset` (create font with subset of given font) and `pyftmerge` (merging fonts, basically same as this repo). +`libharfbuzz-bin` offers CLI utilities `hb-view` and `hb-shape` which are useful for visualising +rendered characters. + `otfinfo` gives useful info about glyphs, codepoints, scripts and more. -[1]: https://en.wikipedia.org/wiki/International_Ideographs_Core +[1]: https://wikipedia.org/wiki/International_Ideographs_Core [2]: https://github.com/googlefonts/noto-cjk/ diff --git a/generate.py b/generate.py deleted file mode 100755 index 347a60c..0000000 --- a/generate.py +++ /dev/null @@ -1,275 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys - -import merge_fonts -import merge_noto - -all_regions = { - 'GoNotoSouthAsia.ttf': [ - "NotoSans-Regular.ttf", - "NotoNastaliqUrdu-Regular.ttf", - "NotoSansBengali-Regular.ttf", - "NotoSansChakma-Regular.ttf", - "NotoSansDevanagari-Regular.ttf", - "NotoSansGujarati-Regular.ttf", - "NotoSansGunjalaGondi-Regular.ttf", - "NotoSansGurmukhi-Regular.ttf", - "NotoSansKannada-Regular.ttf", - "NotoSansLepcha-Regular.ttf", - "NotoSansLimbu-Regular.ttf", - "NotoSansMalayalam-Regular.ttf", - "NotoSansMasaramGondi-Regular.ttf", - "NotoSansMeeteiMayek-Regular.ttf", - "NotoSansMro-Regular.ttf", - "NotoSansNewa-Regular.ttf", - "NotoSansOlChiki-Regular.ttf", - "NotoSansOriya-Regular.ttf", - "NotoSansSaurashtra-Regular.ttf", - "NotoSansSinhala-Regular.ttf", - "NotoSansTamil-Regular.ttf", - "NotoSansTelugu-Regular.ttf", - "NotoSansThaana-Regular.ttf", - "NotoSerifTibetanSubset-Regular.ttf", - "NotoSansWancho-Regular.ttf", - "NotoSansWarangCiti-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], - 'GoNotoAsiaHistorical.ttf': [ - "NotoSans-Regular.ttf", - "NotoSansBhaiksuki-Regular.ttf", - "NotoSansBrahmi-Regular.ttf", - "NotoSansGrantha-Regular.ttf", - "NotoSansKaithi-Regular.ttf", - "NotoSansKharoshthi-Regular.ttf", - "NotoSansKhudawadi-Regular.ttf", - "NotoSansMahajani-Regular.ttf", - "NotoSansMarchen-Regular.ttf", - "NotoSansModi-Regular.ttf", - "NotoSansMultani-Regular.ttf", - "NotoSansNandinagariSubset-Regular.ttf", - "NotoSansOldSogdian-Regular.ttf", - "NotoSansOldTurkic-Regular.ttf", - "NotoSansPhagsPa-Regular.ttf", - "NotoSansSharada-Regular.ttf", - "NotoSansSiddham-Regular.ttf", - "NotoSansSogdian-Regular.ttf", - "NotoSansSoraSompeng-Regular.ttf", - "NotoSansSoyombo-Regular.ttf", - "NotoSansSylotiNagri-Regular.ttf", - "NotoSansTakri-Regular.ttf", - "NotoSansTirhuta-Regular.ttf", - "NotoSansZanabazarSquare-Regular.ttf", - "NotoSansIndicSiyaqNumbers-Regular.ttf", - "NotoSerifAhom-Regular.ttf", - "NotoSerifDograSubset-Regular.ttf", - "NotoSerifKhojki-Regular.ttf", - "NotoSerifOldUyghur-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], - 'GoNotoSouthEastAsia.ttf': [ - "NotoSans-Regular.ttf", - "NotoSansBalinese-Regular.ttf", - "NotoSansBatak-Regular.ttf", - "NotoSansBuginese-Regular.ttf", - "NotoSansBuhid-Regular.ttf", - "NotoSansCham-Regular.ttf", - "NotoSansHanifiRohingya-Regular.ttf", - "NotoSansHanunoo-Regular.ttf", - "NotoSansJavanese-Regular.ttf", - "NotoSansKayahLi-Regular.ttf", - "NotoSansKhmer-Regular.ttf", - "NotoSansLao-Regular.ttf", - # "NotoSansMakasar-Regular.ttf", # doesn't exist - "NotoSansMyanmar-Regular.ttf", - "NotoSansNewTaiLue-Regular.ttf", - "NotoSansPahawhHmong-Regular.ttf", - "NotoSerifNyiakengPuachueHmong-Regular.ttf", - "NotoSansPauCinHau-Regular.ttf", - "NotoSansRejang-Regular.ttf", - "NotoSansSundanese-Regular.ttf", - "NotoSansTagalog-Regular.ttf", - "NotoSansTagbanwa-Regular.ttf", - "NotoSansTaiLe-Regular.ttf", - "NotoSansTaiTham-Regular.ttf", - "NotoSansTaiViet-Regular.ttf", - "NotoSansThai-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], - 'GoNotoEuropeAmericas.ttf': [ - "NotoSans-Regular.ttf", - "NotoSansArmenian-Regular.ttf", - "NotoSansCherokee-Regular.ttf", - "NotoSansCoptic-Regular.ttf", - "NotoSansDeseret-Regular.ttf", - "NotoSansGeorgian-Regular.ttf", - "NotoSansGlagolitic-Regular.ttf", - "NotoSansOsage-Regular.ttf", - "NotoSansSignWriting-Regular.ttf", - "NotoSerifNyiakengPuachueHmong-Regular.ttf", - # Historical - "NotoSansCypriot-Regular.ttf", - "NotoSansCaucasianAlbanian-Regular.ttf", - "NotoSansCarian-Regular.ttf", - "NotoSansCanadianAboriginal-Regular.ttf", - "NotoSansLinearA-Regular.ttf", - "NotoSansLinearB-Regular.ttf", - "NotoSansLycian-Regular.ttf", - "NotoSansLydian-Regular.ttf", - "NotoSansAnatolianHieroglyphs-Regular.ttf", - "NotoSansOldItalic-Regular.ttf", - "NotoSansRunic-Regular.ttf", - "NotoSansOldHungarian-Regular.ttf", - "NotoSansGothic-Regular.ttf", - "NotoSansElbasan-Regular.ttf", - "NotoSansCaucasianAlbanian-Regular.ttf", - "NotoSansVithkuqi-Regular.ttf", - "NotoSansOgham-Regular.ttf", - "NotoSansOldPermic-Regular.ttf", - "NotoSansShavian-Regular.ttf", - "NotoSansDuployan-Regular.ttf", - "NotoSansMayanNumerals-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], - 'GoNotoAfricaMiddleEast.ttf': [ - "NotoSans-Regular.ttf", - "NotoNaskhArabic-Regular.ttf", # or "NotoSansArabic-Regular.ttf" - "NotoSansAdlam-Regular.ttf", - "NotoSansBamum-Regular.ttf", - "NotoSansBassaVah-Regular.ttf", - "NotoSansHebrew-Regular.ttf", - "NotoSansSyriac-Regular.ttf", - "NotoSansSamaritan-Regular.ttf", - "NotoSansMandaic-Regular.ttf", - "NotoSerifYezidi-Regular.ttf", - # Historical scripts - "NotoSansOldNorthArabian-Regular.ttf", - "NotoSansOldSouthArabian-Regular.ttf", - "NotoSansPhoenician-Regular.ttf", - "NotoSansImperialAramaic-Regular.ttf", - "NotoSansManichaean-Regular.ttf", - "NotoSansInscriptionalParthian-Regular.ttf", - "NotoSansInscriptionalPahlavi-Regular.ttf", - "NotoSansPsalterPahlavi-Regular.ttf", - "NotoSansAvestan-Regular.ttf", - # "NotoSansChorasmian-Regular.ttf", # doesn't exist - "NotoSansElymaic-Regular.ttf", - "NotoSansNabataean-Regular.ttf", - "NotoSansPalmyrene-Regular.ttf", - "NotoSansHatran-Regular.ttf", - # Cuneiform and Hieroglyphs - "NotoSansCuneiform-Regular.ttf", - "NotoSansUgaritic-Regular.ttf", - "NotoSansOldPersian-Regular.ttf", - "NotoSansEgyptianHieroglyphs-Regular.ttf", - "NotoSansMeroitic-Regular.ttf", - "NotoSansAnatolianHieroglyphs-Regular.ttf", - # Africa - "NotoSansEthiopic-Regular.ttf", - "NotoSansOsmanya-Regular.ttf", - "NotoSansTifinagh-Regular.ttf", # TODO: check Tifinagh variants - "NotoSansNKo-Regular.ttf", - "NotoSansVai-Regular.ttf", - "NotoSansMendeKikakui-Regular.ttf", - "NotoSansMedefaidrin-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], - 'GoNotoEastAsia.ttf': [ - "NotoSans-Regular.ttf", - "NotoSansMarchen-Regular.ttf", - "NotoSansMongolianSubset-Regular.ttf", - "NotoSansOldSogdian-Regular.ttf", - "NotoSansOldTurkic-Regular.ttf", - "NotoSansPhagsPa-Regular.ttf", - "NotoSansSogdian-Regular.ttf", - "NotoSansSoyombo-Regular.ttf", - "NotoSansZanabazarSquare-Regular.ttf", - "NotoSerifTibetanSubset-Regular.ttf", - "NotoSansYi-Regular.ttf", - "NotoSansNushuSubset-Regular.ttf", - "NotoSansLisu-Regular.ttf", - "NotoSansMiao-Regular.ttf", - "NotoSerifTangutSubset-Regular.ttf", - # Common for all scripts - "NotoSansSymbols-Regular.ttf", - "NotoSansSymbols2-Regular.ttf", - "NotoSansMath-Regular.ttf", - "NotoMusic-Regular.ttf", - ], -} - -def download_fonts(directory="./"): - """Download all the fonts in the @c files list""" - from urllib.request import urlretrieve - from time import sleep - url_base = "https://github.com/googlefonts/noto-fonts/raw/main/hinted/ttf/%s/%s" - for ttf in merge_fonts.files: - outfile = os.path.join(directory, ttf) - if os.path.exists(outfile): continue - url = url_base % (ttf.split('-')[0], ttf) - print("Fetching %s" % url) - try: - urlretrieve(url, outfile) - except: - print("Could not retrieve %s. Please check if it exists", ttf) - sleep(0.5) # poor man's rate-limiting - -# append new entries from # https://docs.microsoft.com/en-gb/typography/opentype/spec/scripttags -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['TaiLe'] = 'tale' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Multani'] = 'mult' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['SoraSompeng'] = 'sora' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['NewTaiLue'] = 'talu' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['TaiViet'] = 'tavt' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Rejang'] = 'rjng' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Tagalog'] = 'tglg' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Tagbanwa'] = 'tagb' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Thaana'] = 'thaa' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Mro'] = 'mroo' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['PahawhHmong'] = "hmng" -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Bamum'] = "bamu" -# TODO Why does this begin with 'NotoSerif'? -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['NotoSerifYezidi'] = "yezi" -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Nushul'] = "nshu" -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['LinearA'] = "lina" -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['AnatolianHieroglyphs'] = 'hluw' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Vithkuqi'] = 'vith' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['OldPermic'] = 'perm' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['OldNorthArabian'] = 'narb' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Nabataean'] = 'nbat' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Hatran'] = 'hatr' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Medefaidrin'] = 'medf' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Duployan'] = 'dupl' -# TODO: NotoSansMayanNumerals-Regular.ttf does not contain any script tag at all! -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['MayanNumerals'] = 'maya' -# TODO Why does this begin with 'NotoSerif'? -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['NotoSerifNyiakengPuachueHmong'] = 'hmnp' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['SignWriting'] = 'sgnw' -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['Mahajani'] = 'mahj' -# TODO Why's this decuding 'Subset'? -merge_noto.SCRIPT_TO_OPENTYPE_SCRIPT_TAG['NushuSubset'] = 'nshu' - -if __name__ == "__main__": - merge_fonts.files = all_regions[sys.argv[2]] - download_fonts(sys.argv[4]) - merge_fonts.main()