font-detect-rhl
v1.1.4
Published
A React Hook Library for Detecting Fonts
Downloads
976
Maintainers
Keywords
Readme
Font-Detect-RHL [ npm | github | netlify ]
Font-Detect-RHL is a React.js Hook Library (RHL) that:
- Detects if fonts are locally installed and returns the status, catering to a stylable font dropdown list.
- Considers Graphite-enabled fonts and supporting environments.
- Calculates the text direction ratio by identifying characters as either LTR, RTL, neutral, or markup (optional) as per RegEx.
Use the exported arrays listing over 1000 font families[1], and/or supplied RegEx, customizing as needed.
See also: How To Tell If A Font Is Copyrighted & Why You Should Always Check.
————————————————————————————
Contents:
- Font Families
- Font Detection Approach 2.1 Font Test String
- Font Features 3.1 Graphite-enabled Smart Font Features 3.2 Both Graphite-Enabled and OpenType Font Features 3.3 OpenType Font Features
- Handling Right-to-Left (RTL) and Left-to-Right (LTR) Text
- Getting Started 3.1 Web Fonts 3.2 To Quote or Not to Quote 3.3 Minor Browser Differences Possible
- Endnotes
————————————————————————————
Font Families [ fontList | graphiteEnabledFontList ] ... ↩
Provided font lists focus on normal, regular, roman, and plain fonts. The primary exported font array is fontList.json (fontList), which includes:
- Windows 11 system and supplemental font families
- MacOS system and downloadable font families thru Sonoma (v14)
- Over 250 fonts common to multiple Linux desktop environments/distributions[2]
- Pre-installed Android fonts and a few common App fonts[3]
- iOS system fonts[4]
Note, however that this provided font list excludes:
- Font names that include hairline, thin, ultra-light, extra-light, light, book, medium, demi-bold, semi-bold, bold, extra-bold, heavy, extra heavy, black, extra-black, ultra-black, ultra, italic, slanted, and oblique.
- Thick fonts such as Impact and Cooper
- Symbols, icons, emojis, assets, wingdings, webdings, dingbats, ornaments, math, music, hieroglyphs, cuneiform, numbers, Marlett, etc.
- MS Office Cloud fonts or MacOS document fonts except where there is overlap
A separate array of Graphite-enabled fonts is also exported -- graphiteEnabledFontList.json (graphiteEnabledFontList):
- These fonts are for use in applications with Graphite implemented, a rendering engine for complex scripts that supports “smart fonts” capable of advanced behaviors, including combination and positioning of letters in complex ways.
- Firefox[5] is an application in which Graphite is implemented, and Electronite is a framework that can be used to build and package others.
- Addition of line-height settings and font-size settings are recommended for Graphite-enabled fonts, for purposes of mitigating collisions or near collisions across rows, and for presentation optimization.
Font Detection Approach [ useDetectFonts ] ... ↩
The current approach compares the width of a test string in each font to that of a baseline generic-family, defaulted to monospace.[6] Apps can also define their own baseline generic-family if preferred. Some other font detect approaches use multiple fallback generic-families, such as serif, sans-serif, monospace
, though not always in that order.
Font Test String ... ↩
The default test string is currently 'abcdefghijklmnopqrstuvwxyz0123456789'
. If a font exists that does not support any of these characters, then that font will not be detected. That use-case can be mitigated through use of a custom test string that exists in both the baseline font and the tested font. Some test strings observed in other font detect approaches include 'abcdefghijklmnopqrstuvwxyz& #0123456789'
, 'random_words_#!@#$^&*()+mdvejreu_RANDOM_WORDS'
, and the following suggestion (which seem to have originated with Lalit Patel[7]): "Use m or w because these two characters take up the maximum width." See endnotes[7] for links to additional information.
Font Features ... ↩
Graphite-enabled Smart Font Features [ graphiteEnabledFeatures ] ... ↩
Graphite-enabled font features have been compiled into json from the following sources as of the indicated font versions. Reference implementations are provided showcasing available font variations for user selection from a Graphite-enabled environment (e.g., Firefox or Electronite). Options range from collision avoidance and spacing to regional character variation and other adjustable font-specific display features.
| Links to Smart Font Settings source | Font Version | # of Feature Settings | Brief Font Description | | :--- | :---: | :---: | :--- | | Awami Nastaliq | 3.300 | 10 | wide variety of languages of South Asia, including but not limited to Urdu |
Both Graphite-Enabled and OpenType Font Features ... ↩
The following fonts are both Graphite enabled and OpenType enabled. They are included in both openTypeEnabledFeatures and graphiteEnabledFeatures as the 'RenderingUnknown' test confirms both RenderingOpenType and RenderingGraphite, depending on the environment. The font features settings are the same in both arrays.
| Links to Smart Font Settings source | Font Version | # of Feature Settings | Brief Font Description | | :--- | :---: | :---: | :--- | | Abyssinica SIL | 2.201 | 29 | many of the languages of Ethiopia and Eritrea | | Padauk | 5.001 | 15 | writing systems that use the Myanmar script. |
The following font currently utilize some different font feature settings when rendered in Graphite vs. when rendered in OpenType enabled. It is included in both graphiteEnabledFeatures and openTypeEnabledFeatures with differing font feature settings.
| Links to Smart Font Settings source | Font Version | # of Feature Settings | Brief Font Description | | :--- | :---: | :---: | :--- | | Annapurna SIL | 2.100 | 18 | writing systems that use the Devanagari script |
OpenType Font Features [ openTypeEnabledFeatures ] ... ↩
| Links to Font Settings source | Font Version | # of Feature Settings | Brief Font Description | | :--- | :---: | :---: | :--- | | Alkalami | 3.000 | 7 | the Kano region of Nigeria and in Niger | | Andika | 6.200 | 53 | comprehensive support for thousands of languages around the world written with Latin and Cyrillic letters and their many variants, including a wide range of additional characters and symbols useful for linguistic and literacy work. | | Charis SIL | 6.200 | 41 | wide range of languages that use the Latin and Cyrillic scripts. | | Doulos SIL | 6.200 | 40 | wide range of languages that use the Latin and Cyrillic scripts | | Gentium Plus | 6.200 | 45 | Latin, Cyrillic, and Greek scripts | | Harmattan | 4.300 | 19 | languages using the Arabic script in West Africa. | | Kanchenjunga | 2.001 | 4 | Kirat Rai script of South Asia. | | Lateef | 4.300 | 17 | Sindhi and other languages of southern Asia | | Ruwudu | 3.000 | 7 | style of writing is used by the Manga people in Niger, West Africa | | Scheherazade New | 4.300 | 18 | a “simplified” rendering of Arabic script, using basic - connecting glyphs but not including a wide variety of additional ligatures or contextual alternates (only the required lam-alef ligatures) | | Tagmukay(*) | 2.000 | 2 | a Shifinagh script font with support for the Tawallammat Tamajaq language |
(*) The Tagumukay font desription indicates both "Graphite and OpenType tables..." The 'RenderingUnknown' test leads to 'RenderingUnknown' with version 2.000. The font features settings are presently only included in openTypeEnabledFeatures. However, it is rendering in Graphite in Firefox, the OpenType font features settings will still work.
Handling Right-to-Left (RTL) and Left-to-Right (LTR) Text [ useDetectDir ] ... ↩
The useDetectDir hook enables simple autodetection of RTL/LTR text through examining the range of unicode values of characters of the text. Code utilized in this hook originated from Christopher Klapp's detectRTL.js.
While a custom RTL scope can be utilized, the default RTL scope is comprehensive for all RTL unicode ranges in v16.0 standards, as follows:
- Contemporary Scripts
- Adlam (U+1E900 - U+1E95F)
- Arabic, Arabic Supplement, Arabic Presentation Forms-A, Arabic Presentation Forms-B, Arabic Extended-A, Arabic Extended-B, Arabic Extended-C (U+0600 - U+06FF, U+0750 - U+077F, U+FB50 - U+FDFF, U+FE70 - U+FEFF, U+08A0 – U+08FF, U+0870 – U+089F, U+10EC0 – U+10EFF)
- Garay (U+10D40 - U+10D8F)
- Hanifi Rohingya (U+10D00 - U+10D3F)
- Hebrew, Alphabetic Presentation Forms (U+0590 - U+05FF, U+FB00 - U+FB4F)
- Mandaic (U+0840 - U+085F)
- Mende Kikakui (U+1E800 - U+1E8DF)
- N'Ko (U+07C0 - U+07FF)
- Samaritan (U+0800 - U+083F)
- Syriac (U+0700 - U+074F)
- Thaana (U+0780 - U+07BF)
- Yezidi (U+10E80 - U+10EBF)
- Ancient Scripts
- Old South Arabian (U+10A60 - U+10A7F)
- Old North Arabian (U+10A80 - U+10A9F)
- Imperial Aramaic (U+10840 - U+1085F)
- Avestan (U+10B00 - U+10B3F)
- Cypriot Syllabary (U+10800 - U+1083F)
- Egyptian Hieroglyphs, Egyptian Hieroglyph Format Controls, Egyptian Hieroglyphs Extended-A (U+13000 - U+1342F, U+13430 - U+1345F, U+13460 – U+143FF)
- Ethiopic, Ethiopic Supplement, Ethiopic Extended, Ethiopic Extended-A, Ethiopic Extended-B (U+1200 - U+137F, U+1380 - U+139F, U+2D80 - U+2DDF, U+AB00 - U+AB2F, U+1E7E0 - U+1E7FF)
- Hatran (U+108E0 - U+108FF)
- Old Hungarian (U+10C80 - U+10CFF)
- Old Italic (U+10300 - U+1032F)
- Kharoshthi (U+10A00 - U+10A5F)
- Lydian (U+10920 - U+1093F)
- Nabataean (U+10880 - U+108AF)
- Inscriptional Pahlavi, Inscriptional Parthian, Psalter Pahlavi (U+10B60 - U+10B7F, U+10B40 - U+10B5F, U+10B80 - U+10BAF)
- Old Persian (U+103A0 - U+103DF)
- Phoenician (U+10900 - U+1091F)
- Sogdian, Old Sogdian (U+10F30 - U+10F6F , U+10F00 - U+10F2F)
- Todhri (U+105C0 - U+105FF)
- Old Turkic (U+10C00 - U+10C4F)
A custom neutral character scope can also be utilized to specify text that is not meant to be considered in the RTL or LTR direction test. The default neutral scope includes:
- line breaks -- /\r?\n|\r/g (also matches unix \n and old Mac's single \r)
- periods -- /./g
- hyphen-minus -- /-/g
- no-break space (NBSP) -- U+00A0
- narrow no-break space (NNBSP) -- U+202F
- Directionality characters
- left-to-right mark (LRM) -- U+200E
- right-to-left-mark (RLM) -- U+200F
- Zero Width Characters
- zero width space (ZWSP) -- U+200B
- zero width non-joiner (ZWNJ) - U+200C
- zero width joiner (ZWJ) -- U+200D
- word joiner (WJ) -- U+2060
- zero-width no-break space (ZWNBSP) -- U+FEFF
- Characters that Act Like Spaces
- mongolian vowel separator (MVS) -- U+180e
- braille pattern blank -- U+2800
- hangul filler -- U+3164
- Visible Spaces
- symbol for space -- U+2420
- blank symbol -- U+2422
- open box -- U+2423
- Bidirectional "White Space" Characters
- Form Feed -- U+000C = \f
- Space -- U+0020
- Ogham Space Mark -- U+1680
- En Quad -- U+2000
- Em Quad -- U+2001
- En Space -- U+2002
- Em Space -- U+2003
- Three-Per-Em Space -- U+2004
- Four-Per-Em Space -- U+2005
- Six-Per-Em Space -- U+2006
- Figure Space -- U+2007
- Punctuation Space -- U+2008
- Thin Space -- U+2009
- Hair Space -- U+200A
- Line Separator -- U+2028
- Medium Mathematical Space -- U+205F
- Ideographic Space -- U+3000
Getting Started ... ↩
Explore the Style Guide Example and documentation of useDetectFonts, fontList, useAssumeGraphite, graphiteEnabledFontList, and useDetectDir.
Then take advantage of these CodeSandbox examples applying font-detect-rhl:
- Material UI Examples: Font Dropdown | with type your font See also Simple USFM Editor App | source code
- Tailwind CSS Examples with Tailwind Elements with sliders for Font Size and Height: Font Dropdown | with type your font
- Tailwind CSS Examples with Headless UI: Font Dropdown | with type your font See also Simple USFM Alignment Prototype | source code
- useDetectDir
- useAssumeGraphite
Web Fonts ... ↩
Web fonts are not addressed by this rhl, though are an additional app concern for developers to consider. There are multiple ways in which web fonts can be delivered, such as base64, woff2, woff, ttf, otf, packaged with an app, self hosted, or third-party-hosted.
If providing a web font for which a user may also have a local version, consider making allowances for the possibility that version differences can exist. Consider giving users maximum control by allowing selection of either a web font or a locally installed version of the font, taking care not to override one with the other.
For one approach to web fonts coupled with locally detected fonts, see:
- Font-Detect-RHL + Embedded Web Fonts with MUI
- Font-Detect-RHL + Embedded Web Fonts with TailwindCSS and Tailwind Elements with sliders for Font Size and Height
- Font-Detect-RHL + Embedded Web Fonts with TailwindCSS and HeadlessUI
And for further insight on application of web fonts, see How to Optimize Web Font Loading Performance with Best Practices.
To Quote or Not to Quote ... ↩
Font lists provided here do not include any Generic Font Families. It is recommended[8] to add quotes around detected font results. useDetectFonts tests fonts with quotes around them against a baseline generic font without quotes.
Generic[9] font families, global values[10], and Apple's aliases[11] for default fonts must be requested without quotes. Adding quotes requests a specific font by that name rather than applying the keyword.
Minor Browser Differences Possible ... ↩
There are some one-off cases in which at least one web browser does not properly apply a few locally installed fonts to pages served over the Internet. So, if your browser is not cooperating with an installed font in the detectable list used, then try a different browser or serve your page locally.[12]
Endnotes ... ↩
[1] ... "Font family refers to all the variations of a typeface that share a common name. For example, Times Roman, Times Italic, Times Bold, and Times Bold Italic are all members of the same font family." [source] ... ↩
[2] ... Fonts installed with linux vary significantly by desktop environment and distribution. The compiled list included here represents style="Regular", style="Normal", and style="Roman" from an fc-list
that overlap in four or more of the following combinations:
- Cinnamon - Linux Mint 20.3
- Fluxbox - MX Linux 22.1
- Gnome - Manjaro 21.2.6
- Gnome - Ubuntu 22.04
- KDE (Plasma) - MX Linux 22.1
- Mate - Linux Mint 20.3
- Mate - Ubuntu 20.04.4
- Xfce - Endeavour Apollo 22.1
- Xfce - Linux Mint 20.3
- Xfce - MX Linux 22.1 ... ↩
[3] ... Android: Droid Sans, Droid Serif, Droid Sans Mono, Roboto, Lato, Montserrat, Source Sans Pro, Raleway, Merriweather, Nunito Sans, and Poppins. [source 1 | [source 2] ... ↩
[4] ... iOS: New York, SF Pro Text, SF Pro Display, SF Pro, SF Compact, SF Mono, SF Arabic, SF Armenian, SF Georgian, and SF Hebrew. [source 1 | source 2], and many pre-installed fonts that overlap with MacOS system and downloadable font families [source] ... ↩
[5] ... If gfx.font_rendering.graphite.enabled is ever set to false in about:config in Firefox, then Graphite will not be enabled and graphite-enabled fonts will not render properly. To access this setting in Firefox Configuration Editor:
- Type about:config in your address bar and press Enter.
- Click on the "I'll be careful, I promise" button.
- Type "graphite" in your search bar to look for gfx.font_rendering.graphite.enabled.
- Double-click on the preference name line to toggle the value between false and true. A bold line indicates a setting that is set to true. ... ↩
[6] ... Closely followed logic in Detect Whether a Font is Installed, then after implementation found fontexist.js. Uncertain of the original source. ... ↩
[7] ... Additional references:
- JavaScript/CSS Font Detector by Lalit Patel
- Additional reference links are available in the Alternatives section of https://github.com/rwoodr/fontcheck
- Consider also the following search strings to look for further information:
- Detect Font
- Font Detect
- Font Detector
- Font Check
- Font Checker
- Available Fonts
- Is Font Available ... ↩
[8] ... While fonts technically can be requested without quotes, that calls for escaping special characters. See Unquoted font family names in CSS. ... ↩
[9] ... serif. sans-serif, cursive, fantasy, system-ui, monospace, ui-serif, ui-sans-serif, ui-monospace, ui-rounded, math, emoji, and fangsong, as in: font-family: monospace;
,.... For explanations and examples, see the <generic=name>
section of this font-family CSS property documentation. ... ↩
[10] ... inherit, initial, revert, revert-layer, and unset, as in: font-family: inherit;
... ↩
[11] ... BlinkMacSystemFont, -apple-system, -apple-system-body, -apple-system-headline, -apple-system-subheadline, -apple-system-caption1, -apple-system-caption2, -apple-system-footnote, -apple-system-short-body, -apple-system-short-headline, -apple-system-short-subheadline, -apple-system-short-caption1, -apple-system-short-footnote, and -apple-system-tall-body", as in font-family: -apple-system;
... ↩
[12] ... On Windows 11, Brave Version 1.64.113 (Chromium: 123.0.6312.86 (Official Build) (64-bit)) recognizes the following fonts on pages served locally, but not when served over the Internet (tested via CodeSandbox and Netlify). On the other hand, Firefox 124.0.1 (64-bit) renders these properly in each case: Aldhabi, Andalus, Arabic Typesetting, Leelawadee, Microsoft Uighur, Noto Sans, Sakkal Majalla, Simplified Arabic, Traditional Arabic, and Urdu Typesetting. There may be others, and Brave/Chromium may improve this over time. ... ↩