Introduction to hexfont

Table of Contents

Overview

This is an R data package that includes most “hex” font files from the GNU Unifont project compressed by xz. It includes a convenience function that loads several of them as a {bittermelon} bm_font() object. GNU Unifont is a duospaced bitmap font (8x16 and 16x16 glyphs) that pretty much covers all of the official Unicode glyphs plus several of the artificial scripts in the (Under-)ConScript Unicode Registry.

Included hex font files

{hexfont} includes most of the hex font files included in the GNU Unifont source code distribution. The version number is stripped from the file names in the precompiled directory and the hex fonts are all compressed by xz but other than that the hex fonts are otherwise unchanged. Due to CRAN size limitations we omit the “precompiled” unifont_all hex file (this is presumably the concatenation of the “precompiled” unifont and unifont_upper hex files).

hex_dir <- system.file("font", package = "hexfont")
list.files(hex_dir, pattern = ".hex.xz", recursive = TRUE)
##  [1] "plane00/alt/codepage-437.hex.xz"           
##  [2] "plane00/alt/izmg16-plane00-FFxx.hex.xz"    
##  [3] "plane00/alt/mongolian-vertical.hex.xz"     
##  [4] "plane00/alt/phags-pa-vertical.hex.xz"      
##  [5] "plane00/alt/quad-width.hex.xz"             
##  [6] "plane00/alt/reiwa-vertical.hex.xz"         
##  [7] "plane00/alt/uni0009-orig.hex.xz"           
##  [8] "plane00/copyleft.hex.xz"                   
##  [9] "plane00/custom00.hex.xz"                   
## [10] "plane00/hangul-syllables.hex.xz"           
## [11] "plane00/izmg16-plane00.hex.xz"             
## [12] "plane00/omit.hex.xz"                       
## [13] "plane00/plane00-nonprinting.hex.xz"        
## [14] "plane00/plane00-unassigned.hex.xz"         
## [15] "plane00/pua.hex.xz"                        
## [16] "plane00/spaces.hex.xz"                     
## [17] "plane00/unifont-base.hex.xz"               
## [18] "plane00/wqy.hex.xz"                        
## [19] "plane00csur/plane00csur-nonprinting.hex.xz"
## [20] "plane00csur/plane00csur-spaces.hex.xz"     
## [21] "plane00csur/plane00csur-unassigned.hex.xz" 
## [22] "plane00csur/plane00csur.hex.xz"            
## [23] "plane01/plane01-nonprinting.hex.xz"        
## [24] "plane01/plane01-noscript.hex.xz"           
## [25] "plane01/plane01-space.hex.xz"              
## [26] "plane01/plane01-unassigned.hex.xz"         
## [27] "plane01/plane01.hex.xz"                    
## [28] "plane01/space.hex.xz"                      
## [29] "plane02/izmg16-plane02.hex.xz"             
## [30] "plane02/zh-plane02.hex.xz"                 
## [31] "plane03/zh-plane03.hex.xz"                 
## [32] "plane0E/plane0E-nonprinting.hex.xz"        
## [33] "plane0E/plane0E-unassigned.hex.xz"         
## [34] "plane0E/plane0E.hex.xz"                    
## [35] "plane0Fcsur/plane0Fcsur-nonprinting.hex.xz"
## [36] "plane0Fcsur/plane0Fcsur.hex.xz"            
## [37] "precompiled/unifont_jp_sample.hex.xz"      
## [38] "precompiled/unifont_jp.hex.xz"             
## [39] "precompiled/unifont_sample.hex.xz"         
## [40] "precompiled/unifont_upper_sample.hex.xz"   
## [41] "precompiled/unifont_upper.hex.xz"          
## [42] "precompiled/unifont.hex.xz"

Examples

The main function unifont() loads in several GNU Unifont hex files at the same time as a {bittermelon} bm_font() object. Arguments:

Argument Meaning Default
upper Include glyphs above the Unicode Basic Multilingual plane TRUE
jp Use Japanese version of Chinese characters FALSE
csur Include (Under-)Conscript Unicode Registry glyphs TRUE
sample Add circle to “Combining” characters FALSE
ucp Character vector of Unicode Code Points to only load NULL
library("bittermelon") # remotes::install_github("trevorld/bittermelon")
## 
## Attaching package: 'bittermelon'
## The following object is masked from 'package:base':
## 
##     which
library("hexfont") # remotes::install_github("trevorld/hexfont")
system.time(font <- unifont()) # Unifont is a **big** font
##    user  system elapsed 
##  96.128   0.120  96.268
length(font) |> prettyNum(big.mark = ",") # number of glyphs
## [1] "123,234"
object.size(font) |> format(units = "MB") # memory used
## [1] "189 Mb"
# Faster to load from a cache
saveRDS(font, "unifont.rds")
system.time(font <- readRDS("unifont.rds"))
##    user  system elapsed 
##   0.643   0.000   0.644
# Or just load the subset of GNU Unifont you need
s <- "R很棒!"
system.time(font_s <- unifont(ucp = str2ucp(s)))
##    user  system elapsed 
##    0.61    0.00    0.61
# Mandarin Chinese
as_bm_bitmap(s, font = font_s) |>
    bm_compress("v")
##                     █ ▄▄▄▄▄▄▄      █      █                     
##    ▄▄▄▄▄▄▄        ▄▀  █     █      █  ▀▀▀▀█▀▀▀▀      ▄█▄        
##     █     ▀▄     ▀  █ █▀▀▀▀▀█   ▀▀▀█▀▀ ▀▀█▀▀▀▀       ███        
##     █     ▄▀      ▄█  █▄▄▄▄▄█     ██▄ ▀▀█▀▀▀█▀▀      ▀█▀        
##     █▀▀▀█▀      ▄▀ █  █  █  ▄▀   █ █ ▀▄▀  █  ▀▄       █         
##     █    ▀▄        █  █   █▀    ▀  █    ▀▀█▀▀                   
##    ▄█▄    ▄█▄      █  █ ▄  ▀▄      █  ▀▀▀▀█▀▀▀▀       █         
##                    █  █▀     ▀▀    █      █
# Emoji
as_bm_bitmap("🐭🐲🐵", font = font) |>
    bm_compress("v")
##   ▄▄       ▄▄           ▄▄▄            ▄▄       
## ▄▀  ▀▄▄▄▄▄▀  ▀▄       ▄█▀           ▄█▀██▀█▄    
## █    ▀   ▀    █      ▄████       ▄▀█ ▄▄  ▄▄ █▀▄ 
## ▄█   ▀   ▀   █▄   ▄▄██▄█████     ▀▄█ ▀▀  ▀▀ █▄▀ 
## ▄█▀    ▄    ▀█▄ ▄█▄███████████     ▄▀      ▀▄   
##   ▀▄  ▀▀▀  ▄▀   ▀▀▀▀▀███▀▀█████    █ ▀▄▄▄▄▀ █   
##     ▀▀▄▄▄▀▀        ▄███   ████▀     ▀▀▄▄▄▄▀▀    
##                   ▀▀▀     ▀▀▀
# Klingon
as_bm_list("", font = font) |>
    bm_pad(type = "trim", left = 1L, right = 1L) |>
    bm_call(cbind) |>
    bm_compress("v")
##                                                                               
##     ▄█▄ ▄▄██▀▀  ▀▀████████               ▄▀       ▄█▄    ▄█▀  ▀█▄    ▄▄       
##  ▄▄██████▀            ▀██ ▀            ▄█▀       ███▀▀  ███    ██   ▀████████ 
##   ▀██  ██             ▄███    ▄█      ▄██       ██▀      ▀██▄▄█▀      ██▀ ▀██ 
##    ▀    █▄           ███      ███▄▄▄▄▄██      ▄███        ▀███▀      ▄█▀   █▀ 
##          █▄          ▀█▄      ██▀▀▀▀▀▀███    ▄██████▄       ▀█▄     ▄█▀   █▀  
##           ▀▄           ▀▀▄   ▄▀        ▀█▄         ▀▀▄        ▀▀▄  ▄▀    ▀    
## 
# Tengwar with combining glyphs
bml <- as_bm_list("", font = font)
to_raise <- which(names(bml) %in% c("U+E04A", "U+E04E"))
bml[to_raise] <- bm_shift(bml[to_raise], top = 1L)
bml |> bm_compose(pua_combining = unifont_combining()) |>
    bm_pad(type = "trim", left = 1L, right = 1L) |>
    bm_call(cbind) |>
    bm_compress("v")
##                  ▄                    ██       ▄      ▄ ▄   
##                 █ ▀                 ▄▄  ▄▄    █ ▀    █ █ ▀  
##                 ▀                   ▀▀  ▀▀    ▀      ▀ ▀    
##  █▄▀▀█▄▄▀▀█▄  █▄▀▀█▄  █▄▀▀█▄▄▀▀█▄   █▄▀▀█▄ ▀▀▀█▀▀▀▀ ▀██▀▀▀█ 
##  █    █    █  █    █  █   ▄█   ▄█   █    █   █       █▄  ▄█ 
##  █  ▀▀   ▀▀   ▀  ▀▀   █▀▀▀▀▀▀▀▀▀▀▀  █  ▀▀   ▄▀        ▀▀▀ █ 
##  █                    █             █       █             █ 
##  █                    █             █       ▀█▄▄▄▀        █

License

The overall license for this package is GPL (>=2) but the bundled hex font files are also available under more permissive terms. Excerpt from font/COPYING

License for font/plane00/jiskan16-plane00.hex and font/plane02/jiskan16-plane02.hex:

 These two files are in the Public Domain.  They were created
 from Public Domain BDF font files jiskan16-2004-1.bdf and
 jiskan16-2000-2.bdf.

License for font files except the jiskan16 files mentioned above are dual-licensed under the SIL Open Font License version 1.1, and under this GNU license:

 All glyphs are released under the GNU General Public License
 (GPL) version 2 or (at your option) a later version, with the
 GNU font embedding exception:

      ** GPL v2.0 license with font embedding exception:

      As a special exception, if you create a document which
      uses this font, and embed this font or unaltered portions
      of this font into the document, this font does not by
      itself cause the resulting document to be covered by
      the GNU General Public License. This exception does not
      however invalidate any other reasons why the document
      might be covered by the GNU General Public License.
      If you modify this font, you may extend this exception
      to your version of the font, but you are not obligated
      to do so. If you do not wish to do so, delete this
      exception statement from your version.