Full Code of lvgl/lv_font_conv for AI

master 626bd649f3b8 cached
58 files
1.2 MB
521.6k tokens
249 symbols
1 requests
Download .txt
Showing preview only (1,233K chars total). Download the full file or copy to clipboard to get everything.
Repository: lvgl/lv_font_conv
Branch: master
Commit: 626bd649f3b8
Files: 58
Total size: 1.2 MB

Directory structure:
gitextract_jsukcq61/

├── .editorconfig
├── .eslintrc.yml
├── .github/
│   ├── auto-comment.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .node-version
├── .nvmrc
├── .posthtmlrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc/
│   └── font_spec.md
├── lib/
│   ├── app_error.js
│   ├── cli.js
│   ├── collect_font_data.js
│   ├── convert.js
│   ├── font/
│   │   ├── cmap_build_subtables.js
│   │   ├── compress.js
│   │   ├── font.js
│   │   ├── table_cmap.js
│   │   ├── table_glyf.js
│   │   ├── table_head.js
│   │   ├── table_kern.js
│   │   └── table_loca.js
│   ├── freetype/
│   │   ├── build/
│   │   │   └── ft_render.js
│   │   ├── index.js
│   │   └── render.c
│   ├── ranger.js
│   ├── utils.js
│   └── writers/
│       ├── bin.js
│       ├── dump.js
│       └── lvgl/
│           ├── index.js
│           ├── lv_font.js
│           ├── lv_table_cmap.js
│           ├── lv_table_glyf.js
│           ├── lv_table_head.js
│           └── lv_table_kern.js
├── lv_font_conv.js
├── package.json
├── support/
│   ├── Dockerfile
│   ├── build.sh
│   └── build_web.js
├── test/
│   ├── .eslintrc.yml
│   ├── font/
│   │   ├── fixtures/
│   │   │   ├── font_info_AV.json
│   │   │   └── font_info_AV_size200.json
│   │   ├── test_cmap_build_subtables.js
│   │   ├── test_compress.js
│   │   └── test_font.js
│   ├── test_cli.js
│   ├── test_collect_font_data.js
│   ├── test_ranger.js
│   └── test_utils.js
└── web/
    ├── .eslintrc.yml
    ├── .htmlhintrc
    ├── content.html
    ├── convert_browser.js
    ├── index.html
    └── index.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true


================================================
FILE: .eslintrc.yml
================================================
env:
  node: true
  es6:  true

parserOptions:
  ecmaVersion: '2018'

ignorePatterns:
  - dist
  - lib/freetype/build

rules:
  accessor-pairs:         2
  array-bracket-spacing:  [ 2, "always", { "singleValue": true, "objectsInArrays": true, "arraysInArrays": true } ]
  block-scoped-var:       2
  block-spacing:          2
  brace-style:            [ 2, '1tbs', { "allowSingleLine": true } ]
  # Postponed
  #callback-return:        2
  comma-dangle:           2
  comma-spacing:          2
  comma-style:            2
  computed-property-spacing: [ 2, never ]
  # Postponed
  #consistent-return:      2
  consistent-this:        [ 2, self ]
  # ? change to multi
  curly:                  [ 2, 'multi-line' ]
  # Postponed
  # dot-notation:           [ 2, { allowKeywords: true } ]
  dot-location:           [ 2, 'property' ]
  eol-last:               2
  eqeqeq:                 2
  func-style:             [ 2, declaration ]
  # Postponed
  #global-require:         2
  guard-for-in:           2
  handle-callback-err:    2

  # Postponed
  indent:                 [ 2, 2, { VariableDeclarator: { var: 2, let: 2, const: 3 }, SwitchCase: 1 } ]

  # key-spacing:            [ 2, { "align": "value" } ]
  keyword-spacing:        2
  linebreak-style:        2
  max-depth:              [ 1, 3 ]
  max-nested-callbacks:   [ 1, 5 ]
  # string can exceed 80 chars, but should not overflow github website :)
  max-len:                [ 2, 120, 1000 ]
  new-cap:                0
  new-parens:             2
  # Postponed
  #newline-after-var:      2
  no-alert:               2
  no-array-constructor:   2
  no-caller:              2
  #no-case-declarations:   2
  no-catch-shadow:        2
  no-cond-assign:         2
  no-console:             1
  no-constant-condition:  2
  no-control-regex:       2
  no-debugger:            1
  no-delete-var:          2
  no-div-regex:           2
  no-dupe-args:           2
  no-dupe-keys:           2
  no-duplicate-case:      2
  no-else-return:         2
  # Tend to drop
  # no-empty:               1
  no-empty-character-class: 2
  no-empty-pattern:       2
  no-eq-null:             2
  no-eval:                2
  no-ex-assign:           2
  no-extend-native:       2
  no-extra-bind:          2
  no-extra-boolean-cast:  2
  no-extra-semi:          2
  no-fallthrough:         2
  no-floating-decimal:    2
  no-func-assign:         2
  # Postponed
  #no-implicit-coercion:   [2, { "boolean": true, "number": true, "string": true } ]
  no-implied-eval:        2
  no-inner-declarations:  2
  no-invalid-regexp:      2
  no-irregular-whitespace: 2
  no-iterator:            2
  no-label-var:           2
  no-labels:              2
  no-lone-blocks:         1
  no-lonely-if:           2
  no-loop-func:           2
  no-mixed-requires:      [ 1, { "grouping": true } ]
  no-mixed-spaces-and-tabs: 2
  # Postponed
  #no-native-reassign:     2
  no-negated-in-lhs:      2
  # Postponed
  #no-nested-ternary:      2
  no-new:                 2
  no-new-func:            2
  no-new-object:          2
  no-new-require:         2
  no-new-wrappers:        2
  no-obj-calls:           2
  no-octal:               2
  no-octal-escape:        2
  no-path-concat:         2
  no-proto:               2
  no-redeclare:           2
  # Postponed
  #no-regex-spaces:        2
  no-return-assign:       2
  no-self-compare:        2
  no-sequences:           2
  # Postponed
  #no-shadow:              2
  no-shadow-restricted-names: 2
  no-sparse-arrays:       2
  # Postponed
  #no-sync:                2
  no-trailing-spaces:     2
  no-undef:               2
  no-undef-init:          2
  no-unexpected-multiline: 2
  no-unreachable:         2
  no-unused-expressions:  2
  no-unused-vars:         2
  no-use-before-define:   2
  no-void:                2
  no-with:                2
  object-curly-spacing:   [ 2, always, { "objectsInObjects": true, "arraysInObjects": true } ]
  operator-assignment:    1
  # Postponed
  #operator-linebreak:     [ 2, after ]
  semi:                   2
  semi-spacing:           2
  space-before-function-paren: [ 2, { "anonymous": "always", "named": "never" } ]
  space-in-parens:        [ 2, never ]
  space-infix-ops:        2
  space-unary-ops:        2
  # Postponed
  #spaced-comment:         [ 1, always, { exceptions: [ '/', '=' ] } ]
  strict:                 [ 2, global ]
  quotes:                 [ 2, single, avoid-escape ]
  quote-props:            [ 1, 'as-needed' ]
  radix:                  2
  use-isnan:              2
  valid-typeof:           2
  yoda:                   [ 2, never, { "exceptRange": true } ]

  #
  # es6
  #
  arrow-body-style:       [ 1, "as-needed" ]
  arrow-parens:           [ 1, "as-needed" ]
  arrow-spacing:          2
  constructor-super:      2
  generator-star-spacing: [ 2, {"before": false, "after": true } ]
  no-class-assign:        2
  no-confusing-arrow:     [ 1, { allowParens: true } ]
  no-const-assign:        2
  #no-constant-condition:  2
  no-dupe-class-members:  2
  no-this-before-super:   2
  # Postponed
  #no-var:                 2
  object-shorthand:       1
  # Postponed
  #prefer-arrow-callback:  1
  # Postponed
  #prefer-const:           1
  #prefer-reflect
  #prefer-spread
  # Postponed
  #prefer-template:        1
  require-yield:          1


================================================
FILE: .github/auto-comment.yml
================================================
# Comment to a new issue.

pullRequestOpened: |
  Thank you for raising your pull request.
  
  To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin). 
  
  The text of DCO can be read here: https://developercertificate.org/
  For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site.
  
  By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO.
  
  No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment. 


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
  pull_request:
  schedule:
    - cron: '0 0 * * 3'

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [ '24.11.1' ]
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm install
    - run: npm test


================================================
FILE: .gitignore
================================================
node_modules
coverage
.nyc_output
dist
.parcel-cache
.cache
*.log
*.swp
.vscode


================================================
FILE: .node-version
================================================
24.11.1


================================================
FILE: .nvmrc
================================================
24.11.1


================================================
FILE: .posthtmlrc
================================================
{
  "plugins": {
    "posthtml-include": {
      "root": "./web"
    }
  }
}


================================================
FILE: CHANGELOG.md
================================================
1.5.2 / 2021-07-18
------------------

- Fixed lvgl version check for v8+, #64.


1.5.1 / 2021-04-06
------------------

- Fixed fail of CMAP generation for edge cases, #62.
- Dev deps bump.


1.5.0 / 2021-03-08
------------------

- More `const` in generated font (for v8+), #59.


1.4.1 / 2021-01-26
------------------

- Fix charcodes padding in comments, #54.


1.4.0 / 2021-01-03
------------------

- Added OTF fonts support.
- Added `--use-color-info` for limited multi-tone glyphs support.


1.3.1 / 2020-12-28
------------------

- Unify `lvgl.h` include.
- Updated repo refs (littlevgl => lvgl).
- Deps bump.
- Moved CI to github actions.


1.3.0 / 2020-10-25
------------------

- Drop `lodash` use.
- Deps bump.


1.2.1 / 2020-10-24
------------------

- Reduced npm package size (drop unneeded files before publish).


1.2.0 / 2020-10-24
------------------

- Bump FreeType to 2.10.4.
- Bundle dependencies to npm package.


1.1.3 / 2020-09-22
------------------

- lvgl: added `LV_FONT_FMT_TXT_LARGE` check or very large fonts.


1.1.2 / 2020-08-23
------------------

- Fix: skip `glyph.advanceWidth` for monospace fonts, #43.
- Spec fix: version size should be 4 bytes, #44.
- Spec fix: bbox x/y bits => unsigned, #45.
- Bump argparse.
- Cleanup help formatter.


1.1.1 / 2020-08-01
------------------

- `--version` should show number from `package.json`.


1.1.0 / 2020-07-27
------------------

- Added `post.underlinePosition` & `post.underlineThickness` info to font header.


1.0.0 / 2020-06-26
------------------

- Maintenance release.
- Set package version 1.x, to label package as stable.
- Deps bump.


0.4.3 / 2020-03-05
------------------

- Enabled `--bpp 8` mode.


0.4.2 / 2020-01-05
------------------

- Added `--lv_include` option to set alternate `lvgl.h` path.
- Added guards to hide `.subpx` property for lvgl 6.0 (supported from 6.1 only), #32.
- Dev deps bump


0.4.1 / 2019-12-09
------------------

- Allow memory growth for FreeType build, #29.
- Dev deps bump.
- Web build update.


0.4.0 / 2019-11-29
------------------

- Note, this release is for lvgl 6.1 and has potentially breaking changes
  (see below). If you have compatibility issues with lvgl 6.0 - use previous
  versions or update your code.
- Spec change: added subpixels info field to font header (header size increased).
- Updated `bin` & `lvgl` writers to match new spec.
- lvgl: fixed data type for kerning values (needs appropriate update
  in LittlevGL 6.1+).
- Fix errors display (disable emscripten error catcher).


0.3.1 / 2019-10-24
------------------

- Fixed "out of range" error for big `--size`.


0.3.0 / 2019-10-12
------------------

- Added beta options `--lcd` & `--lcd-v` for subpixel rendering (still need
  header info update).
- Added FreeType data properties to dump info.
- Fixed glyph width (missed fractional part after switch to FreeType).
- Fixed missed sigh for negative X/Y bitmap offsets.
- Deps bump.


0.2.0 / 2019-09-26
------------------

- Use FreeType renderer. Should solve all regressions, reported in 0.1.0.
- Enforced light autohinting (horizontal lines only).
- Use special hinter for monochrome output (improve quality).
- API changed to async.
- Fix: added missed `.bitmap_format` field to lvgl writer.
- Fix: changed struct fields init order to match declaration, #25.


0.1.0 / 2019-09-03
------------------

- First release.


================================================
FILE: LICENSE
================================================
Copyright (c) 2018 authors

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# lv_font_conv

[![CI](https://github.com/lvgl/lv_font_conv/workflows/CI/badge.svg?branch=master)](https://github.com/lvgl/lv_font_conv/actions)
[![NPM version](https://img.shields.io/npm/v/lv_font_conv.svg?style=flat)](https://www.npmjs.org/package/lv_font_conv)

Convert TTF/WOFF/OTF fonts into a [compact bitmap format](https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md) that fits small embedded systems. Key capabilities:

- Supports bitonal and anti-aliased glyphs (1-4 bits per pixel).
- Preserves kerning data.
- Built-in compression.
- Subset selection for only the glyphs you need.
- Merge multiple font sources.
- Simple CLI that plugs easily into build systems.

## Installation

Requires [Node.js](https://nodejs.org/en/download/) v14+.

Global install of the latest release:

```sh
# Install from npm
npm i lv_font_conv -g
# Install from GitHub (master branch)
npm i lvgl/lv_font_conv -g
```

Run via [npx](https://www.npmjs.com/package/npx) without installing:

```sh
# From npm
npx lv_font_conv -h
# From GitHub master
npx github:lvgl/lv_font_conv -h
```

`npx` downloads dependencies on first use, so the initial run can take a moment.

## CLI options

Common:

- `--bpp` - bits per pixel (antialiasing).
- `--size` - output font size (pixels).
- `-o`, `--output` - output path (file or directory, depending on format).
- `--format` - output format.
  - `--format dump` - export glyph images and font info for debugging.
  - `--format bin` - export a binary font (see the [spec](https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md)).
  - `--format lvgl` - export in [LVGL](https://github.com/lvgl/lvgl) format.
- `--force-fast-kern-format` - always use the faster kerning storage format at the cost of some size; if size differs, it is reported.
- `--lcd` - generate bitmaps with 3x horizontal resolution for subpixel smoothing.
- `--lcd-v` - generate bitmaps with 3x vertical resolution for subpixel smoothing.
- `--use-color-info` - try to use glyph color data to create grayscale icons. Gray tones are emulated via transparency, so contrasty backgrounds work best.
- `--lv-include` - with `--format lvgl`, set an alternate path for `lvgl.h`.
- `--no-compress` - disable built-in RLE compression.
- `--no-prefilter` - disable the XOR prefilter that improves compression ratio.
- `--byte-align` - pad bitmap lines to whole bytes (requires `--no-compress` and `--bpp != 3`).
- `--no-kerning` - drop kerning info to reduce size (not recommended).

Per-font:

- `--font` - path to a font file (ttf/woff/woff2/otf). May be used multiple times for merging.
- `-r`, `--range` - single glyph or range with optional mapping for the previously declared `--font`. Can be used multiple times. Examples:
  - `-r 0x1F450` - single value (dec or hex).
  - `-r 0x1F450-0x1F470` - range.
  - `-r '0x1F450=>0xF005'` - single glyph with mapping.
  - `-r '0x1F450-0x1F470=>0xF005'` - range with mapping.
  - `-r 0x1F450 -r 0x1F451-0x1F470` - two ranges.
  - `-r 0x1F450,0x1F451-0x1F470` - same as above with a single `-r`.
- `--symbols` - list of characters to copy (instead of numeric format in `-r`).
  - `--symbols 0123456789.,` - extract characters for numbers.
- `--autohint-off` - do not force autohinting ("light" is on by default).
- `--autohint-strong` - use stronger autohinting (will break kerning).

Debug:

- `--full-info` - do not shorten `font_info.json` (include pixel data).

## Examples

Merge English from Roboto Regular and icons from Font Awesome, and show debug info:

`env DEBUG=* lv_font_conv --font Roboto-Regular.ttf -r 0x20-0x7F --font FontAwesome.ttf -r 0xFE00=>0x81 --size 16 --format bin --bpp 3 --no-compress -o output.font`

Merge English and Russian from Roboto Regular, and show debug info:

`env DEBUG=* lv_font_conv --font Roboto-Regular.ttf -r 0x20-0x7F -r 0x401,0x410-0x44F,0x451 --size 16 --format bin --bpp 3 --no-compress -o output.font`

Dump all Roboto glyphs to inspect icons and font details:

`lv_font_conv --font Roboto-Regular.ttf -r 0x20-0x7F --size 16 --format dump --bpp 3 -o ./dump`

**Note:** `--no-compress` is temporary to avoid confusion until LVGL adds compression support.

## Technical notes

### Supported output formats

1. **bin** - universal binary format as described in https://github.com/lvgl/lv_font_conv/tree/master/doc.
2. **lvgl** - C file for LVGL. Slightly larger because C cannot easily define relative offsets in data blocks.
3. **dump** - folder with each glyph in a separate image plus JSON font data (debug-friendly).

### Merged font metrics

When multiple fonts are merged, sources can have different metrics. The result follows these rules:

1. No scaling. Glyphs keep the size intended by the font authors.
2. Baseline is shared.
3. `OS/2` metrics (`sTypoAscender`, `sTypoDescender`, `sTypoLineGap`) come from the first font in the list.
4. `hhea` metrics (`ascender`, `descender`), defined as the max/min point of all glyphs, are recalculated for the merged set.

## Development

The package includes a WebAssembly build of FreeType with helper functions. Docker wraps everything, so you do not need manual tool installs. See `package.json` for more commands; use these if you upgrade FreeType or helpers.

Build the Docker image with Emscripten and FreeType (usually once):

```sh
npm run build:dockerimage
```

Compile helpers and create the WebAssembly files:

```sh
npm run build:freetype
```

Local development notes:

- On Apple Silicon or other ARM hosts, Docker may pull `emscripten/emsdk:3.1.1` for `linux/amd64`. If you see a platform warning, either set `DOCKER_DEFAULT_PLATFORM=linux/amd64` or choose an ARM-compatible base image before running the Docker-based build scripts.
- To preview the web UI locally, run `npm start`. Parcel serves `web/index.html`, listens on `http://localhost:1234` by default (set `PORT` to override), and opens your browser automatically.
- Note: `package.json` omits the `main` field to keep Parcel’s development server running fine; CLI entry remains via the `bin` field (`lv_font_conv.js`).
- Browser bundle note: the web UI uses a browser-safe converter (`web/convert_browser.js`) that excludes Node-only writers. You can also run `npm run build` and open `dist/index.html` to verify the browser bundle works without Node APIs.


================================================
FILE: doc/font_spec.md
================================================
# Bitmap font format for embedded systems

Compact binary bitmap font format tailored for embedded targets with limited
memory. Highlights:

- Kerning support (missing in legacy BDF/PCF).
- Configurable bits per pixel (1-4) for bitonal or anti-aliased glyphs.
- Storage optimized for bounding boxes with built-in compression.

The format is based on the OpenType spec (https://docs.microsoft.com/en-us/typography/opentype/spec/) but simplified for bitmaps:

- No separate global header; everything lives in the `head` table.
- `advanceWidth` moves to the `glyf` table.
- Glyph count limited to 65536 (code points still up to 0x10FFFF).
- No vertical fonts or ligatures.

Unless noted otherwise, multi-byte numbers are little-endian.


## Table: `head` (font header)

[Initial Reference](https://docs.microsoft.com/en-us/typography/opentype/spec/head)

Global values.

Size (bytes) | Description
-------------|------------
4 | Record size (for quick skip)
4 | `head` (table marker)
4 | Version (reserved)
2 | Number of additional tables (2-byte align helper)
2 | Font size (px), as defined in converter params
2 | Ascent (uint16), from `Font.ascender` of `opentype.js` (usually HHead ascent)
2 | Descent (int16, negative), from `Font.descender` of `opentype.js` (usually HHead descent)
2 | typoAscent (uint16), typographic ascent
2 | typoDescent (int16), typographic descent
2 | typoLineGap (uint16), typographic line gap
2 | min Y (quick check for line intersections)
2 | max Y
2 | Default advanceWidth (uint16) if advanceWidth bits length = 0
2 | kerningScale, FP12.4 unsigned; scales kerning data to 1 byte
1 | indexToLocFormat in `loca` (`0` - Offset16, `1` - Offset32)
1 | glyphIdFormat (`0` - 1 byte, `1` - 2 bytes)
1 | advanceWidthFormat (`0` - uint, `1` - unsigned with 4 fractional bits)
1 | Bits per pixel (1, 2, 3, or 4)
1 | Glyph BBox x/y bits length (unsigned)
1 | Glyph BBox w/h bits length (unsigned)
1 | Glyph advanceWidth bits length (unsigned, may be FP4)
1 | Compression algorithm ID (0 - raw bits, 1 - RLE with XOR prefilter, 2 - RLE without prefilter)
1 | Subpixel rendering: `0` none, `1` horizontal x3, `2` vertical x3
1 | Reserved (align to 2x)
2 | Underline position (int16), scaled `post.underlinePosition`
2 | Underline thickness (uint16), scaled `post.underlineThickness`
x | Unused (align header length to 4x)

Note: `Ascent + abs(Descent)` may not equal font size.


## Table: `cmap`

[Initial Reference](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap)

Maps code points to internal IDs via optimized subtables for compact storage.

Differs from the original by using fixed subtable headers for faster lookup.
Only a subset of subtable formats is implemented.

Size (bytes) | Description
-------------|------------
4 | Record size (for quick skip)
4 | `cmap` (table marker)
4 | Subtables count (4 to simplify align)
16 | Subtable 1 header
16 | Subtable 2 header
...|...
? | Subtable 1 data (aligned to 4)
? | Subtable 2 data (aligned to 4)
...|...

All subtables are non-intersecting ranges. Headers and content are ordered by
codePoint for fast scan or binary search.

### Subtable header

Size (bytes) | Description
-------------|------------
4 | Data offset (or 0 if data segment does not exist)
4 | Range start (min codePoint)
2 | Range length (up to 65535)
2 | Glyph ID offset (for delta-coding)
2 | Data entries count (for sparse data)
1 | Format type (`0` => format 0, `1` => format sparse, `2` => format 0 tiny, `3` => format sparse tiny)
1 | - (align to 4)

### Subtable "format 0" data

[Initial Reference](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table)

`Array[uint8]` (continuous, delta-coded), or empty data.

- Index = codePoint - (Min codePoint)
- Map to Glyph ID as `Value + Glyph ID offset`.

bytes | description
------|------------
1 | delta-encoded Glyph ID for (range_start + 0) codePoint
1 | delta-encoded Glyph ID for (range_start + 1) codePoint
... | ...
1 | delta-encoded Glyph ID for (range_end) codePoint

"Missed" chars map to 0.


### Subtable "format sparse" data

For non-continuous sets (CJK subsets, for example). `Array[entries]` of
delta-coded code points + `Array[entries]` of delta-coded glyph IDs.

bytes | description
------|------------
2 | (codePoint1 - range_start)
2 | (codePoint2 - range_start)
...|...
2 | (last codepoint - range_start)
2 | delta-encoded Glyph1 ID
2 | delta-encoded Glyph2 ID
... | ...
2 | delta-encoded last glyph ID


### Subtable "format 0 tiny"

Special case of "format 0" without IDs index.

In most cases, glyph IDs are consecutive and have no gaps. Then we can
calculate ID value as `glyph ID offset + codepoint index`.

This format has only a header and no data.


### Subtable "format sparse tiny"

Exactly as "format sparse", but without glyph ID index at the end
(code points only).

See "format 0 tiny" for details.


## Table: `loca`

[Initial Reference](https://docs.microsoft.com/en-us/typography/opentype/spec/loca)

Data offsets in `glyf` for each glyph id. Can be `Offset16` or `Offset32`
(defined in `head`).

Size (bytes) | Description
-------------|------------
4 | Record size (for quick skip)
4 | `loca` (table marker)
4 | Entries count (4 to simplify align)
2 or 4 | id1 offset
2 or 4 | id2 offset
... | ...


## Table: `glyf`

[Initial Reference](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf)

Contains glyph bitmap data. Data offsets for each id are defined in `loca`.

Coordinate system is `(right, up)` - point `(0, 0)` located at (baseline, left)
corner, as in OpenType fonts. Glyph BBox `(x, y)` defines bottom-left corner.

Image inside the BBox is drawn from top-left corner, to the right and down.

Size (bytes) | Description
-------------|------------
4 | Record size (for quick skip)
4 | `glyf` (table marker)
?? | Glyph id1 data
?? | Glyph id2 data
...| ...

Note: Glyph ID 0 is reserved for "undefined". It is recommended to set it to
0xFFFE char image.

Glyph data is NOT aligned and should be loaded byte-by-byte.


### Glyph data

Stream of bits.

Bounding box is NOT tied to typographic area (height * advanceWidth) and can
shift. The real image can overflow typographic space.

Size (bits) | Description
------------|------------
NN | advanceWidth (length/format in font header, may have 4 fractional bits)
NN | BBox X (length in font header)
NN | BBox Y (length in font header)
NN | BBox Width (length in font header)
NN | BBox Height (length in font header)
?? | Compressed bitmap

If bitmaps are generated for subpixel rendering, then BBox Width or BBox Height
value will be 3x more than the "normal" one. They always contain real size of
content, not rendered size.


## Table `kern`

Initial References: [1](https://docs.microsoft.com/en-us/typography/opentype/spec/kern),
[2](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html)

Kerning info is optional. Only a small subset of `kern`/`GPOS` features is
supported:

- Horizontal kerning only.
- Two subtable formats for compact storage (sorted pairs and table of glyph classes).
- No feature stacking (combination of subtables). The `kern` table contains data
  in one of the supported formats.

Stored kerning values are always FP4.4 fixed point with sign. Multiply by
FP12.4 `kerningScale` from the font header. Seven-bit resolution covers common
cases, but kerning for fonts over 40px can exceed signed FP4.4. `kerningScale`
widens the usable range.

Data layout:

Size (bytes) | Description
-------------|------------
4 | Record size (for quick skip)
4 | `kern` (table marker)
1 | Format type (0 and 3 supported)
3 | - (align)
?? | Format content

### Format 0 (sorted pairs)

Sorted list of `(id_left, id_right, value)` where ids are combined into
`uint32_t` and binary searchable. Good for ASCII-size sets; inefficient for
multi-language.

Unlike the original, id pairs and values are stored separately for alignment.

Content:

Size (bytes) | Description
-------------|------------
4 | Entries (pairs) count
2 or 4 | Kerning pair 1 (glyph id left, glyph id right)
2 or 4 | Kerning pair 2
...|...
2 or 4 | Kerning pair last
1 | Value 1
1 | Value 2
... | ...
1 | Value last

Kerning pair size depends on `glyphIdFormat` from the header.

### Format 3 (array M*N of classes)

See Apple's [TrueType reference](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html).

Data format is very similar to the Apple suggestion, except kerning values are
stored directly (no index) because values are always 1 byte.

Content:

Size (bytes) | Description
-------------|------------
2 | The number of glyphs in this font (class mapping length). `M`.
1 | The number of left-hand classes (table rows width). `W`.
1 | The number of right-hand classes (table column height). `H`.
M | Left-hand classes mapping; index = glyph_id, value => class id.
M | Right-hand classes mapping.
W*H| Kerning values array.

Class id `0` is reserved and means "kerning does not exist" for this glyph. It is
NOT stored in the kerning array.

Resulting data index: `kerningArray[(leftClass-1)*rightClassesCount + (rightClass-1)]`

As noted in the original spec, this format is restricted to 256 classes. That is
enough for complex cases. For a full `Roboto Regular` font dump, size of
auto-restored table is about 80*100 (auto-restore means reverse-building from
pairs). For this reason `Format 2` support was not added to this spec.


## Compression

Glyph data uses modified RLE compression - [I3BN](https://thesai.org/Downloads/Volume7No7/Paper_34-New_modified_RLE_algorithms.pdf), with prefilter and tuned options.

Everything works with "pixels" (groups of 2, 3, 4, or 8 bits). That does not
work for bitonal fonts, but those are small enough.

Notable compression gain starts around 30px sizes because:

- Kerning table occupies fixed size, notable for small fonts.
- Input is already compacted by storing bounding box data only.

Decompression cost is negligible, so compression stays enabled except for 1-bpp
fonts.

### Pre-filter

Before compression, lines are XOR-ed with previous ones. That gives about 10%
extra gain. Since no advanced entropy encoding is used, XOR is sufficient and
often better than diff:

- XOR does not depend on pixel resolution/encoding.
- Can be optimized with word-wide operations if needed.

### Compression algorithm

1. At least 1 repeat is required to switch into RLE mode (first pixel passes as is).
   That helps to pass anti-aliasing pixels without size increase.
2. First 10 repeats are replaced with 1 bit (`0` - end).
3. Next (11th) is followed by 6-bit counter. If the counter overflows, max
   possible value is used and the process restarts from step 1.

See [I3BN](https://thesai.org/Downloads/Volume7No7/Paper_34-New_modified_RLE_algorithms.pdf)
for the initial idea and images.

Constants (repeats and counter size) were chosen by experimentation on different
font sizes and bpp. They do not affect results much (1-2%).

Also see:

- [Compressor sources](https://github.com/lvgl/lv_font_conv/blob/master/lib/font/compress.js).
- [Compressor tests](https://github.com/lvgl/lv_font_conv/blob/master/test/font/test_compress.js).

### Decompression

Everything is the reverse of compression. Data length is determined by bitmap size.

To improve performance, you may apply these hacks during decompression:

1. Align lines in decompressed images to 1 or 4 bytes to simplify later steps
   (for example, post-filter line XOR by words).
2. Return 3-bpp pixels as 4-bpp or 8-bpp to simplify composition.


================================================
FILE: lib/app_error.js
================================================
// Custom Error type to simplify error messaging
'use strict';

const AppError = require('make-error')('AppError');

module.exports = AppError;


================================================
FILE: lib/cli.js
================================================
// Parse input arguments and execute converter.

'use strict';

const argparse    = require('argparse');
const fs          = require('fs');
const mkdirp      = require('mkdirp');
const path        = require('path');
const convert     = require('./convert');

class ActionFontAdd extends argparse.Action {
  call(parser, namespace, value/*, option_string*/) {
    let items = (namespace[this.dest] || []).slice();
    items.push({ source_path: value, ranges: [] });
    namespace[this.dest] = items;
  }
}

// Add range or symbols to font; merge into one array so overrides work correctly.
class ActionFontRangeAdd extends argparse.Action {
  call(parser, namespace, value, option_string) {
    let fonts = namespace.font || [];

    if (fonts.length === 0) parser.error(`argument ${option_string}: Only allowed after --font`);

    let lastFont = fonts[fonts.length - 1];

    // { symbols: 'ABC' }, or { range: [ 65, 67, 65 ] }
    lastFont.ranges.push({ [this.dest]: value });
  }
}

// Add hinting option to font.
class ActionFontStoreTrue extends argparse.Action {
  constructor(options) {
    options = options || {};
    options.const = true;
    options.default = options.default !== null ? options.default : false;
    options.nargs = 0;
    super(options);
  }

  call(parser, namespace, _value, option_string) {
    let fonts = namespace.font || [];

    if (fonts.length === 0) {
      parser.error(`argument ${option_string}: Only allowed after --font`);
    }

    let lastFont = fonts[fonts.length - 1];

    lastFont[this.dest] = this.const;
  }
}

// Formatter with support of `\n` in Help texts.
class RawTextHelpFormatter2 extends argparse.RawDescriptionHelpFormatter {
  // Executes parent _split_lines for each line of the help, then flattens the result
  _split_lines(text, width) {
    return [].concat(...text.split('\n').map(line => super._split_lines(line, width)));
  }
}

// Parse decimal or hex code in unicode range.
function unicode_point(str) {
  let m = /^(?:(?:0x([0-9a-f]+))|([0-9]+))$/i.exec(str.trim());

  if (!m) throw new TypeError(`${str} is not a number`);

  let [ , hex, dec ] = m;

  let value = hex ? parseInt(hex, 16) : parseInt(dec, 10);

  if (value > 0x10FFFF) throw new TypeError(`${str} is out of unicode range`);

  return value;
}

// Parse a range string into numeric intervals.
function range(str) {
  let result = [];

  for (let s of str.split(',')) {
    let m = /^(.+?)(?:-(.+?))?(?:=>(.+?))?$/i.exec(s);

    let [ , start, end, mapped_start ] = m;

    if (!end) end = start;
    if (!mapped_start) mapped_start = start;

    start = unicode_point(start);
    end = unicode_point(end);

    if (start > end) throw new TypeError(`Invalid range: ${s}`);

    mapped_start = unicode_point(mapped_start);

    result.push(start, end, mapped_start);
  }

  return result;
}

// Exclude negative numbers and non-numbers.
function positive_int(str) {
  if (!/^\d+$/.test(str)) throw new TypeError(`${str} is not a valid number`);

  let n = parseInt(str, 10);

  if (n <= 0) throw new TypeError(`${str} is not a valid number`);

  return n;
}

module.exports.run = async function (argv, debug = false) {

  //
  // Configure CLI
  //

  let parser = new argparse.ArgumentParser({
    add_help: true,
    formatter_class: RawTextHelpFormatter2
  });

  if (debug) {
    parser.exit = function (status, message) {
      throw new Error(message);
    };
  }

  parser.add_argument('-v', '--version', {
    action: 'version',
    version: require('../package.json').version
  });

  parser.add_argument('--size', {
    metavar: 'PIXELS',
    type: positive_int,
    required: true,
    help: 'Output font size, pixels.'
  });

  parser.add_argument('-o', '--output', {
    metavar: '<path>',
    help: 'Output path.'
  });

  parser.add_argument('--bpp', {
    choices: [ 1, 2, 3, 4, 8 ],
    type: positive_int,
    required: true,
    help: 'Bits per pixel, for antialiasing.'
  });

  let lcd_group = parser.add_mutually_exclusive_group();

  lcd_group.add_argument('--lcd', {
    action: 'store_true',
    default: false,
    help: 'Enable subpixel rendering (horizontal pixel layout).'
  });

  lcd_group.add_argument('--lcd-v', {
    action: 'store_true',
    default: false,
    help: 'Enable subpixel rendering (vertical pixel layout).'
  });

  parser.add_argument('--use-color-info', {
    dest: 'use_color_info',
    action: 'store_true',
    default: false,
    help: 'Try to use glyph color info from font to create grayscale icons. ' +
          'Since gray tones are emulated via transparency, result will be good on contrast background only.'
  });

  parser.add_argument('--format', {
    choices: convert.formats,
    required: true,
    help: 'Output format.'
  });

  parser.add_argument('--font', {
    metavar: '<path>',
    action: ActionFontAdd,
    required: true,
    help: 'Source font path. Can be used multiple times to merge glyphs from different fonts.'
  });

  parser.add_argument('-r', '--range', {
    type: range,
    action: ActionFontRangeAdd,
    help: `
Range of glyphs to copy. Can be used multiple times, belongs to previously declared "--font". Examples:
  -r 0x1F450
  -r 0x20-0x7F
  -r 32-127
  -r 32-127,0x1F450
  -r '0x1F450=>0xF005'
  -r '0x1F450-0x1F470=>0xF005'
`
  });

  parser.add_argument('--symbols', {
    action: ActionFontRangeAdd,
    help: `
List of characters to copy, belongs to previously declared "--font". Examples:
  --symbols ,.0123456789
  --symbols abcdefghigklmnopqrstuvwxyz
`
  });

  parser.add_argument('--autohint-off', {
    type: range,
    action: ActionFontStoreTrue,
    help: 'Disable autohinting for previously declared "--font"'
  });

  parser.add_argument('--autohint-strong', {
    type: range,
    action: ActionFontStoreTrue,
    help: 'Use more strong autohinting for previously declared "--font" (will break kerning)'
  });

  parser.add_argument('--force-fast-kern-format', {
    dest: 'fast_kerning',
    action: 'store_true',
    default: false,
    help: 'Always use kern classes instead of pairs (might be larger but faster).'
  });

  parser.add_argument('--no-compress', {
    dest: 'no_compress',
    action: 'store_true',
    default: false,
    help: 'Disable built-in RLE compression.'
  });

  parser.add_argument('--no-prefilter', {
    dest: 'no_prefilter',
    action: 'store_true',
    default: false,
    help: 'Disable bitmap lines filter (XOR), used to improve compression ratio.'
  });

  parser.add_argument('--no-kerning', {
    dest: 'no_kerning',
    action: 'store_true',
    default: false,
    help: 'Drop kerning info to reduce size (not recommended).'
  });

  parser.add_argument('--byte-align', {
    dest: 'byte_align',
    action: 'store_true',
    default: false,
    help: 'Pad bitmap line endings to whole bytes.'
  });

  parser.add_argument('--stride', {
    choices: [ 0, 1, 4, 8, 16, 32, 64 ],
    type: 'int',
    default: 0,
    help: 'Align each glyph\'s stride to the specfied number of bytes.'
  });

  parser.add_argument('--align', {
    choices: [ 1, 4, 8, 16, 32, 64, 128, 256, 512, 1024 ],
    type: positive_int,
    default: 1,
    help: 'Align each glyph address to the specified number of bytes.'
  });

  parser.add_argument('--lv-include', {
    metavar: '<path>',
    help: 'Set alternate "lvgl.h" path (for --format lvgl).'
  });

  parser.add_argument('--lv-font-name', {
    help: 'Variable name of the lvgl font structure. Defaults to the output\'s basename.'
  });

  parser.add_argument('--full-info', {
    dest: 'full_info',
    action: 'store_true',
    default: false,
    help: 'Don\'t shorten "font_info.json" (include pixels data).'
  });

  parser.add_argument('--lv-fallback', {
    help: 'Variable name of the lvgl font structure to use as fallback for this font. Defaults to NULL.'
  });

  parser.add_argument('--relative-project-path', {
    help: 'Path to the project root for the file. If specified, it will be used to modify the paths ' +
      'shown in the comment at the top of each generated font file. This is for friendliness with version-control.'
  });

  //
  // Process CLI options
  //

  function removeFlagAndValue(flag, args_for_opts_string) {
    const index = args_for_opts_string.indexOf(flag);
    if (index > -1) args_for_opts_string.splice(index, 2);
  }

  let args = parser.parse_args(argv.length ? argv : [ '-h' ]);
  let args_for_opts_string = [ ...argv ];
  // For version-control friendliness, handle making paths in comments relative if specified
  if (args.relative_project_path) {
    const projectRoot = path.resolve(args.relative_project_path);

    removeFlagAndValue('--relative-project-path', args_for_opts_string);

    // make font a relative path
    if (args.output) {
      const index = args_for_opts_string.indexOf(args.output);
      if (index > -1) {
        // The addition of '/' makes it consistent with container usage
        args_for_opts_string[index] = '/' + path.relative(projectRoot, args_for_opts_string[index]);
      }
    }

    if (args.font) {
      for (const font of args.font) {
        const index = args_for_opts_string.indexOf(font.source_path);
        // eslint-disable-next-line max-depth
        if (index > -1) {
          // The addtion of '/' makes it consistent with container usage
          args_for_opts_string[index] = '/' + path.relative(projectRoot, args_for_opts_string[index]);
        }
      }
    }
  }
  args.opts_string = args_for_opts_string.join(' ');

  for (let font of args.font) {
    if (font.ranges.length === 0) {
      parser.error(`You need to specify either "--range" or "--symbols" for font "${font.source_path}"`);
    }

    try {
      font.source_bin = fs.readFileSync(font.source_path);
    } catch (err) {
      parser.error(`Cannot read file "${font.source_path}": ${err.message}`);
    }
  }

  if (args.byte_align) {
    parser.error('--byte-align is deprecated, use --stride 1 instead');
  }

  if (args.stride > 0) {
    if (args.no_compress === false) {
      parser.error('--stride requires --no-compress');
    }

    if (args.bpp === 3) {
      parser.error('--stride requires --bpp 1, 2, 4, or 8');
    }
  }

  //
  // Convert
  //

  let files = await convert(args);

  //
  // Store files
  //

  for (let [ filename, data ] of Object.entries(files)) {
    let dir = path.dirname(filename);

    mkdirp.sync(dir);

    fs.writeFileSync(filename, data);
  }

};

// Export for tests
module.exports._range = range;


================================================
FILE: lib/collect_font_data.js
================================================
'use strict';

const opentype  = require('opentype.js');
const ft_render = require('./freetype');
const AppError  = require('./app_error');
const Ranger    = require('./ranger');

module.exports = async function collect_font_data(args) {
  await ft_render.init();

  // Duplicate font options as key/value for quick access.
  const fonts_options = {};
  args.font.forEach(f => {
    fonts_options[f.source_path] = f;
  });

  // Read fonts once per path.
  const fonts_opentype = {};
  const fonts_freetype = {};

  for (let { source_path, source_bin } of args.font) {
    // Avoid reloading a font referenced multiple times in args.
    if (fonts_opentype[source_path]) continue;

    try {
      let b = source_bin;

      if (Buffer.isBuffer(b)) {
        // Node.js Buffer -> ArrayBuffer.
        b = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
      }

      fonts_opentype[source_path] = opentype.parse(b);
    } catch (err) {
      throw new AppError(`Cannot load font "${source_path}": ${err.message}`);
    }

    fonts_freetype[source_path] = ft_render.fontface_create(source_bin, args.size);
  }

  // Merge all ranges into a single mapping.
  const ranger = new Ranger();

  for (let { source_path, ranges } of args.font) {
    let font = fonts_freetype[source_path];

    for (let item of ranges) {
      /* eslint-disable max-depth */
      if (item.range) {
        for (let i = 0; i < item.range.length; i += 3) {
          let range = item.range.slice(i, i + 3);
          let chars = ranger.add_range(source_path, ...range);
          let is_empty = true;

          for (let code of chars) {
            if (ft_render.glyph_exists(font, code)) {
              is_empty = false;
              break;
            }
          }

          if (is_empty) {
            let a = '0x' + range[0].toString(16);
            let b = '0x' + range[1].toString(16);
            throw new AppError(`Font "${source_path}" doesn't have any characters included in range ${a}-${b}`);
          }
        }
      }

      if (item.symbols) {
        let chars = ranger.add_symbols(source_path, item.symbols);
        let is_empty = true;

        for (let code of chars) {
          if (ft_render.glyph_exists(font, code)) {
            is_empty = false;
            break;
          }
        }

        if (is_empty) {
          throw new AppError(`Font "${source_path}" doesn't have any characters included in "${item.symbols}"`);
        }
      }
    }
  }

  const mapping = ranger.get();
  const glyphs = [];
  const all_dst_charcodes = Object.keys(mapping).sort((a, b) => a - b).map(Number);

  for (let dst_code of all_dst_charcodes) {
    let src_code = mapping[dst_code].code;
    let src_font = mapping[dst_code].font;

    if (!ft_render.glyph_exists(fonts_freetype[src_font], src_code)) continue;

    let ft_result = ft_render.glyph_render(
      fonts_freetype[src_font],
      src_code,
      {
        autohint_off: fonts_options[src_font].autohint_off,
        autohint_strong: fonts_options[src_font].autohint_strong,
        lcd: args.lcd,
        lcd_v: args.lcd_v,
        mono: !args.lcd && !args.lcd_v && args.bpp === 1,
        use_color_info: args.use_color_info
      }
    );

    glyphs.push({
      code: dst_code,
      advanceWidth: ft_result.advance_x,
      bbox: {
        x: ft_result.x,
        y: ft_result.y - ft_result.height,
        width: ft_result.width,
        height: ft_result.height
      },
      kerning: {},
      freetype: ft_result.freetype,
      pixels: ft_result.pixels
    });
  }

  if (!args.no_kerning) {
    let existing_dst_charcodes = glyphs.map(g => g.code);

    for (let { code, kerning } of glyphs) {
      let src_code = mapping[code].code;
      let src_font = mapping[code].font;
      let font     = fonts_opentype[src_font];
      let glyph    = font.charToGlyph(String.fromCodePoint(src_code));

      for (let dst_code2 of existing_dst_charcodes) {
        // Cannot merge kerning values from two different fonts
        if (mapping[dst_code2].font !== src_font) continue;

        let src_code2 = mapping[dst_code2].code;
        let glyph2 = font.charToGlyph(String.fromCodePoint(src_code2));
        let krn_value = font.getKerningValue(glyph, glyph2);

        if (krn_value) kerning[dst_code2] = krn_value * args.size / font.unitsPerEm;

        //let krn_value = ft_render.get_kerning(font, src_code, src_code2).x;
        //if (krn_value) kerning[dst_code2] = krn_value;
      }
    }
  }

  const first_font = fonts_freetype[args.font[0].source_path];
  const first_font_scale = args.size / first_font.units_per_em;
  const os2_metrics = ft_render.fontface_os2_table(first_font);
  const post_table = fonts_opentype[args.font[0].source_path].tables.post;

  for (let font of Object.values(fonts_freetype)) ft_render.fontface_destroy(font);

  ft_render.destroy();

  return {
    ascent:      Math.max(...glyphs.map(g => g.bbox.y + g.bbox.height)),
    descent:     Math.min(...glyphs.map(g => g.bbox.y)),
    typoAscent:  Math.round(os2_metrics.typoAscent * first_font_scale),
    typoDescent: Math.round(os2_metrics.typoDescent * first_font_scale),
    typoLineGap: Math.round(os2_metrics.typoLineGap * first_font_scale),
    capHeight:   Math.round(os2_metrics.capHeight * first_font_scale),
    xHeight:     Math.round(os2_metrics.xHeight * first_font_scale),
    size:        args.size,
    glyphs,
    underlinePosition:  Math.round(post_table.underlinePosition * first_font_scale),
    underlineThickness: Math.round(post_table.underlineThickness * first_font_scale)
  };
};


================================================
FILE: lib/convert.js
================================================
// Internal API to convert input data into output font data
// Used by both CLI and Web wrappers.

'use strict';

const collect_font_data = require('./collect_font_data');

const writers = {
  dump: require('./writers/dump'),
  bin: require('./writers/bin'),
  lvgl: require('./writers/lvgl')
};

//
// Input:
// - args like from CLI (optionally extended with binary content of files)
//
// Output:
// - { name1: bin_data1, name2: bin_data2, ... }
//
// returns hash with files to write
//
async function convert(args) {
  const font_data = await collect_font_data(args);
  const files = writers[args.format](args, font_data);

  return files;
}

module.exports = convert;
module.exports.formats = Object.keys(writers);


================================================
FILE: lib/font/cmap_build_subtables.js
================================================
/**
 * Find an optimal configuration of cmap tables representing a set of codepoints,
 * using a simple breadth-first algorithm.
 *
 * Assumptions:
 *  - Codepoints have one-to-one correspondence to glyph IDs.
 *  - Glyph IDs increase with codepoints.
 *  - Glyph IDs are consecutive (1..N without gaps).
 *
 * With those assumptions we can omit glyph IDs from calculations entirely:
 * if codepoints fit in format0, glyph IDs will as well.
 *
 * Format6 is not considered; if glyph IDs can be delta-coded,
 * multiple format0 tables are guaranteed to be smaller than a single format6.
 *
 * Sparse format is not used because, with consecutive glyph IDs,
 * sparse_tiny will always be preferred.
 */

'use strict';

function estimate_format0_tiny_size(/*start_code, end_code*/) {
  return 16;
}

function estimate_format0_size(start_code, end_code) {
  return 16 + (end_code - start_code + 1);
}

// function estimate_sparse_size(count) {
//   return 16 + count * 4;
// }

function estimate_sparse_tiny_size(count) {
  return 16 + count * 2;
}

module.exports = function cmap_split(all_codepoints) {
  all_codepoints = all_codepoints.sort((a, b) => a - b);

  const min_paths = [];

  for (let i = 0; i < all_codepoints.length; i++) {
    let min = { dist: Infinity };

    for (let j = 0; j <= i; j++) {
      let prev_dist = (j - 1 >= 0) ? min_paths[j - 1].dist : 0;
      let s;

      if (all_codepoints[i] - all_codepoints[j] < 256) {
        s = estimate_format0_size(all_codepoints[j], all_codepoints[i]);

        /* eslint-disable max-depth */
        if (prev_dist + s < min.dist) {
          min = {
            dist: prev_dist + s,
            start: j,
            end: i,
            format: 'format0'
          };
        }
      }

      if (all_codepoints[i] - all_codepoints[j] < 256 && all_codepoints[i] - i === all_codepoints[j] - j) {
        s = estimate_format0_tiny_size(all_codepoints[j], all_codepoints[i]);

        /* eslint-disable max-depth */
        if (prev_dist + s < min.dist) {
          min = {
            dist: prev_dist + s,
            start: j,
            end: i,
            format: 'format0_tiny'
          };
        }
      }

      // Tiny sparse will always be preferred over full sparse because glyph ids are consecutive
      if (all_codepoints[i] - all_codepoints[j] < 65536) {
        s = estimate_sparse_tiny_size(i - j + 1);

        if (prev_dist + s < min.dist) {
          min = {
            dist: prev_dist + s,
            start: j,
            end: i,
            format: 'sparse_tiny'
          };
        }
      }
    }

    min_paths[i] = min;
  }

  const result = [];

  for (let i = all_codepoints.length - 1; i >= 0;) {
    let path = min_paths[i];
    result.unshift([ path.format, all_codepoints.slice(path.start, path.end + 1) ]);
    i = path.start - 1;
  }

  return result;
};


================================================
FILE: lib/font/compress.js
================================================
'use strict';

//const debug = require('debug')('compress');

function count_same(arr, offset) {
  let same = 1;
  let val = arr[offset];

  for (let i = offset + 1; i < arr.length; i++) {
    if (arr[i] !== val) break;
    same++;
  }

  return same;
}

//
// Compress pixels with RLE-like algorithm (modified I3BN)
//
// 1. Require minimal repeat count (1) to enter I3BN mode
// 2. Increased 1-bit-replaced repeat limit (2 => 10)
// 3. Length of direct repetition counter reduced (8 => 6 bits).
//
// pixels - flat array of pixels (one per entry)
// options.bpp - bits per pixels
//
module.exports = function compress(bitStream, pixels, options) {
  const opts = Object.assign({}, { repeat: 1 }, options);

  // Minimal repetitions count to enable RLE mode.
  const RLE_SKIP_COUNT = 1;
  // Number of repeats, when `1` used to replace data
  // If more - write as number
  const RLE_BIT_COLLAPSED_COUNT = 10;

  const RLE_COUNTER_BITS = 6; // (2^bits - 1) - max value
  const RLE_COUNTER_MAX = (1 << RLE_COUNTER_BITS) - 1;
  // Force flush if counter density exceeded.
  const RLE_MAX_REPEATS = RLE_COUNTER_MAX + RLE_BIT_COLLAPSED_COUNT + 1;

  //let bits_start_offset = bitStream.index;

  let offset = 0;

  while (offset < pixels.length) {
    const p = pixels[offset];

    let same = count_same(pixels, offset);

    // Clamp value because RLE counter density is limited
    if (same > RLE_MAX_REPEATS + RLE_SKIP_COUNT) {
      same = RLE_MAX_REPEATS + RLE_SKIP_COUNT;
    }

    //debug(`offset: ${offset}, count: ${same}, pixel: ${p}`);

    offset += same;

    // If not enough for RLE - write as is.
    if (same <= RLE_SKIP_COUNT) {
      for (let i = 0; i < same; i++) {
        bitStream.writeBits(p, opts.bpp);
        //debug(`==> ${opts.bpp} bits`);
      }
      continue;
    }

    // First, write "skipped" head as is.
    for (let i = 0; i < RLE_SKIP_COUNT; i++) {
      bitStream.writeBits(p, opts.bpp);
      //debug(`==> ${opts.bpp} bits`);
    }

    same -= RLE_SKIP_COUNT;

    // Not reached state to use counter => dump bit-extended
    if (same <= RLE_BIT_COLLAPSED_COUNT) {
      bitStream.writeBits(p, opts.bpp);
      //debug(`==> ${opts.bpp} bits (val)`);
      for (let i = 0; i < same; i++) {
        /*eslint-disable max-depth*/
        if (i < same - 1) {
          bitStream.writeBits(1, 1);
          //debug('==> 1 bit (rle repeat)');
        } else {
          bitStream.writeBits(0, 1);
          //debug('==> 1 bit (rle repeat last)');
        }
      }
      continue;
    }

    same -= RLE_BIT_COLLAPSED_COUNT + 1;

    bitStream.writeBits(p, opts.bpp);
    //debug(`==> ${opts.bpp} bits (val)`);

    for (let i = 0; i < RLE_BIT_COLLAPSED_COUNT + 1; i++) {
      bitStream.writeBits(1, 1);
      //debug('==> 1 bit (rle repeat)');
    }
    bitStream.writeBits(same, RLE_COUNTER_BITS);
    //debug(`==> 4 bits (rle repeat count ${same})`);
  }

  //debug(`output bits: ${bitStream.index - bits_start_offset}`);
};


================================================
FILE: lib/font/font.js
================================================
// Font class to generate tables
'use strict';

const u = require('../utils');
const debug = require('debug')('font');
const Head = require('./table_head');
const Cmap = require('./table_cmap');
const Glyf = require('./table_glyf');
const Loca = require('./table_loca');
const Kern = require('./table_kern');

class Font {
  constructor(fontData, options) {
    this.src = fontData;

    this.opts = options;

    // Map chars to IDs (zero is reserved)
    this.glyph_id = { 0: 0 };

    this.last_id = 1;
    this.createIDs();
    debug(`last_id: ${this.last_id}`);

    this.init_tables();

    this.minY = Math.min(...this.src.glyphs.map(g => g.bbox.y));
    debug(`minY: ${this.minY}`);
    this.maxY = Math.max(...this.src.glyphs.map(g => g.bbox.y + g.bbox.height));
    debug(`maxY: ${this.maxY}`);

    // 0 => 1 byte, 1 => 2 bytes
    this.glyphIdFormat = Math.max(...Object.values(this.glyph_id)) > 255 ? 1 : 0;
    debug(`glyphIdFormat: ${this.glyphIdFormat}`);

    // 1.0 by default, will be stored in font as FP12.4
    this.kerningScale = 1.0;
    let kerningMax = Math.max(...this.src.glyphs.map(g => Object.values(g.kerning).map(Math.abs)).flat());
    if (kerningMax >= 7.5) this.kerningScale = Math.ceil(kerningMax / 7.5 * 16) / 16;
    debug(`kerningScale: ${this.kerningScale}`);

    // 0 => int, 1 => FP4
    this.advanceWidthFormat = this.hasKerning() ? 1 : 0;
    debug(`advanceWidthFormat: ${this.advanceWidthFormat}`);

    this.xy_bits = Math.max(...this.src.glyphs.map(g => Math.max(
      u.signed_bits(g.bbox.x), u.signed_bits(g.bbox.y)
    )));
    debug(`xy_bits: ${this.xy_bits}`);

    this.wh_bits = Math.max(...this.src.glyphs.map(g => Math.max(
      u.unsigned_bits(g.bbox.width), u.unsigned_bits(g.bbox.height)
    )));
    debug(`wh_bits: ${this.wh_bits}`);

    this.advanceWidthBits = Math.max(...this.src.glyphs.map(
      g => u.signed_bits(this.widthToInt(g.advanceWidth))
    ));
    debug(`advanceWidthBits: ${this.advanceWidthBits}`);

    let glyphs = this.src.glyphs;

    this.monospaced = glyphs.every((v, i, arr) => v.advanceWidth === arr[0].advanceWidth);
    debug(`monospaced: ${this.monospaced}`);

    // This should stay in the end, because depends on previous variables
    // 0 => 2 bytes, 1 => 4 bytes
    this.indexToLocFormat = this.glyf.getSize() > 65535 ? 1 : 0;
    debug(`indexToLocFormat: ${this.indexToLocFormat}`);

    this.subpixels_mode = options.lcd ? 1 : (options.lcd_v ? 2 : 0);
    debug(`subpixels_mode: ${this.subpixels_mode}`);
  }

  init_tables() {
    this.head = new Head(this);
    this.glyf = new Glyf(this);
    this.cmap = new Cmap(this);
    this.loca = new Loca(this);
    this.kern = new Kern(this);
  }

  createIDs() {
    // Simplified, do not check duplicates here
    this.last_id = 1;

    for (let i = 0; i < this.src.glyphs.length; i++) {
      // Reserve zero for special cases
      this.glyph_id[this.src.glyphs[i].code] = this.last_id;
      this.last_id++;
    }
  }

  hasKerning() {
    if (this.opts.no_kerning) return false;

    for (let glyph of this.src.glyphs) {
      if (glyph.kerning && Object.keys(glyph.kerning).length) return true;
    }
    return false;
  }

  // Returns integer width, depending on format
  widthToInt(val) {
    if (this.advanceWidthFormat === 0) return Math.round(val);

    return Math.round(val * 16);
  }

  // Convert kerning to FP4.4, useable for writer. Apply `kerningScale`.
  kernToFP(val) {
    return Math.round(val / this.kerningScale * 16);
  }

  toBin() {
    const result = Buffer.concat([
      this.head.toBin(),
      this.cmap.toBin(),
      this.loca.toBin(),
      this.glyf.toBin(),
      this.kern.toBin()
    ]);

    debug(`font size: ${result.length}`);

    return result;
  }
}

module.exports = Font;


================================================
FILE: lib/font/table_cmap.js
================================================
'use strict';

const debug = require('debug')('font.table.cmap');

const build_subtables = require('./cmap_build_subtables');
const u = require('../utils');

const O_SIZE = 0;
const O_LABEL = O_SIZE + 4;
const O_COUNT = O_LABEL + 4;

const HEAD_LENGTH = O_COUNT + 4;

const SUB_FORMAT_0 = 0;
const SUB_FORMAT_0_TINY = 2;
const SUB_FORMAT_SPARSE = 1;
const SUB_FORMAT_SPARSE_TINY = 3;

class Cmap {
  constructor(font) {
    this.font = font;
    this.label = 'cmap';

    this.sub_heads = [];
    this.sub_data = [];

    this.compiled = false;
  }

  compile() {
    if (this.compiled) return;
    this.compiled = true;

    const f = this.font;

    let subtables_plan = build_subtables(f.src.glyphs.map(g => g.code));

    const count_format0 = subtables_plan.filter(s => s[0] === 'format0').length;
    const count_sparse = subtables_plan.length - count_format0;
    debug(`${subtables_plan.length} subtable(s): ${count_format0} "format 0", ${count_sparse} "sparse"`);

    for (let [ format, codepoints ] of subtables_plan) {
      const g = this.glyphByCode(codepoints[0]);
      let start_glyph_id = f.glyph_id[g.code];
      let min_code = codepoints[0];
      let max_code = codepoints[codepoints.length - 1];
      let entries_count = max_code - min_code + 1;
      let format_code = 0;

      if (format === 'format0_tiny') {
        format_code = SUB_FORMAT_0_TINY;
        this.sub_data.push(Buffer.alloc(0));
      } else if (format === 'format0') {
        format_code = SUB_FORMAT_0;
        this.sub_data.push(this.create_format0_data(min_code, max_code, start_glyph_id));
      } else if (format === 'sparse_tiny') {
        entries_count = codepoints.length;
        format_code = SUB_FORMAT_SPARSE_TINY;
        this.sub_data.push(this.create_sparse_tiny_data(codepoints, start_glyph_id));
      } else { // assume format === 'sparse'
        entries_count = codepoints.length;
        format_code = SUB_FORMAT_SPARSE;
        this.sub_data.push(this.create_sparse_data(codepoints, start_glyph_id));
      }

      this.sub_heads.push(this.createSubHeader(
        min_code,
        max_code - min_code + 1,
        start_glyph_id,
        entries_count,
        format_code
      ));
    }

    this.subHeaderUpdateAllOffsets();
  }

  createSubHeader(rangeStart, rangeLen, glyphIdOffset, total, type) {
    const buf = Buffer.alloc(16);

    // buf.writeUInt32LE(offset, 0); offset unknown at this moment
    buf.writeUInt32LE(rangeStart, 4);
    buf.writeUInt16LE(rangeLen, 8);
    buf.writeUInt16LE(glyphIdOffset, 10);
    buf.writeUInt16LE(total, 12);
    buf.writeUInt8(type, 14);

    return buf;
  }

  subHeaderUpdateOffset(header, val) {
    header.writeUInt32LE(val, 0);
  }

  subHeaderUpdateAllOffsets() {
    for (let i = 0; i < this.sub_heads.length; i++) {
      const offset = HEAD_LENGTH +
        u.sum(this.sub_heads.map(h => h.length)) +
        u.sum(this.sub_data.slice(0, i).map(d => d.length));

      this.subHeaderUpdateOffset(this.sub_heads[i], offset);
    }
  }

  glyphByCode(code) {
    return this.font.src.glyphs.find(g => g.code === code) || null;
  }

  collect_format0_data(min_code, max_code, start_glyph_id) {
    const data = [];

    for (let i = min_code; i <= max_code; i++) {
      const g = this.glyphByCode(i);

      if (!g) {
        data.push(0);
        continue;
      }

      const id_delta = this.font.glyph_id[g.code] - start_glyph_id;

      if (id_delta < 0 || id_delta > 255) throw new Error('Glyph ID delta out of Format 0 range');

      data.push(id_delta);
    }

    return data;
  }

  create_format0_data(min_code, max_code, start_glyph_id) {
    const data = this.collect_format0_data(min_code, max_code, start_glyph_id);

    return u.balign4(Buffer.from(data));
  }

  collect_sparse_data(codepoints, start_glyph_id) {
    const codepoints_list = [];
    const ids_list = [];

    for (let code of codepoints) {
      const g = this.glyphByCode(code);
      const id = this.font.glyph_id[g.code];

      let code_delta = code - codepoints[0];
      let id_delta   = id - start_glyph_id;

      if (code_delta < 0 || code_delta > 65535) throw new Error('Codepoint delta out of range');
      if (id_delta < 0 || id_delta > 65535) throw new Error('Glyph ID delta out of range');

      codepoints_list.push(code_delta);
      ids_list.push(id_delta);
    }

    return {
      codes: codepoints_list,
      ids: ids_list
    };
  }

  create_sparse_data(codepoints, start_glyph_id) {
    const data = this.collect_sparse_data(codepoints, start_glyph_id);

    return u.balign4(Buffer.concat([
      u.bFromA16(data.codes),
      u.bFromA16(data.ids)
    ]));
  }

  create_sparse_tiny_data(codepoints, start_glyph_id) {
    const data = this.collect_sparse_data(codepoints, start_glyph_id);

    return u.balign4(u.bFromA16(data.codes));
  }

  toBin() {
    if (!this.compiled) this.compile();

    const buf = Buffer.concat([
      Buffer.alloc(HEAD_LENGTH),
      Buffer.concat(this.sub_heads),
      Buffer.concat(this.sub_data)
    ]);
    debug(`table size = ${buf.length}`);

    buf.writeUInt32LE(buf.length, O_SIZE);
    buf.write(this.label, O_LABEL);
    buf.writeUInt32LE(this.sub_heads.length, O_COUNT);

    return buf;
  }
}

module.exports = Cmap;


================================================
FILE: lib/font/table_glyf.js
================================================
'use strict';

const { BitStream } = require('bit-buffer');
const debug = require('debug')('font.table.glyf');

const u = require('../utils');
const compress = require('./compress');

const O_SIZE = 0;
const O_LABEL = O_SIZE + 4;

const HEAD_LENGTH = O_LABEL + 4;

class Glyf {
  constructor(font) {
    this.font = font;
    this.label = 'glyf';

    this.compiled = false;

    this.binData = [];
  }

  // Convert 8-bit opacity to bpp-bit.
  pixelsToBpp(pixels) {
    const bpp = this.font.opts.bpp;
    return pixels.map(line => line.map(p => (p >>> (8 - bpp))));
  }

  widthToStride(width) {
    const stride = this.font.opts.stride;
    if (stride > 0) {
      const byte_count = Math.ceil((width * this.font.opts.bpp) / 8);
      const final_length =  Math.ceil(byte_count / stride) * stride;
      return final_length;
    }
    return Math.ceil((width * this.font.opts.bpp) / 8);
  }

  // Return a binary stream (Buffer) of compiled glyph data.
  compileGlyph(glyph) {
    // Allocate memory, enough for every storage formats
    let bufSize = 100 + (this.widthToStride(glyph.bbox.width) * glyph.bbox.height) *
                  this.font.opts.bpp + this.font.opts.align;

    if (isNaN(bufSize) || bufSize <= 0) bufSize = 128 * 1024; // Fallback for empty glyphs
    let buf  = Buffer.alloc(bufSize);

    const bs = new BitStream(buf);
    bs.bigEndian = true;
    const f = this.font;

    // Store Width
    if (!f.monospaced) {
      let w = f.widthToInt(glyph.advanceWidth);
      bs.writeBits(w, f.advanceWidthBits);
    }

    // Store X, Y
    bs.writeBits(glyph.bbox.x, f.xy_bits);
    bs.writeBits(glyph.bbox.y, f.xy_bits);
    bs.writeBits(glyph.bbox.width, f.wh_bits);
    bs.writeBits(glyph.bbox.height, f.wh_bits);

    const pixels = this.pixelsToBpp(glyph.pixels);

    this.storePixels(bs, pixels);

    // Shrink size
    let result;

    if (this.font.opts.align && this.font.opts.align !== 1) {
      result = Buffer.alloc(Math.ceil(bs.byteIndex / this.font.opts.align) * this.font.opts.align);
    } else {
      result = Buffer.alloc(bs.byteIndex);
    }

    buf.copy(result, 0, 0, bs.byteIndex);

    return result;
  }

  storePixels(bitStream, pixels) {
    if (this.getCompressionCode() === 0 || this.getCompressionCode() === 3) this.storePixelsRaw(bitStream, pixels);
    else this.storePixelsCompressed(bitStream, pixels);
  }

  addPadding(bitStream, pad) {
    const bpp = this.font.opts.bpp;
    for (let x = 0; x < pad; x++) {
      bitStream.writeBits(0, bpp);
    }
  }

  storePixelsRaw(bitStream, pixels) {
    if (pixels.length === 0) return;

    const bpp = this.font.opts.bpp;
    let bit_pad_line = 0;
    if (this.font.opts.stride > 0) {
      const bit_count = pixels[0].length * bpp;
      const aligned_bit_count = this.widthToStride(pixels[0].length) * 8;
      bit_pad_line = aligned_bit_count - bit_count;
    }

    for (let y = 0; y < pixels.length; y++) {
      const line = pixels[y];
      for (let x = 0; x < line.length; x++) {
        bitStream.writeBits(line[x], bpp);
      }
      if (bit_pad_line) {
        this.addPadding(bitStream, bit_pad_line / bpp);
      }
    }
  }

  storePixelsCompressed(bitStream, pixels) {
    let p;

    if (this.font.opts.no_prefilter) p = pixels.flat();
    else p = u.prefilter(pixels).flat();

    compress(bitStream, p, this.font.opts);
  }

  // Create internal struct with binary data for each glyph
  // Needed to calculate offsets & build final result
  compile() {
    this.compiled = true;

    this.binData = [
      Buffer.alloc(0) // Reserve id 0
    ];

    const f = this.font;

    f.src.glyphs.forEach(g => {
      const id = f.glyph_id[g.code];

      this.binData[id] = this.compileGlyph(g);
    });
  }

  toBin() {
    if (!this.compiled) this.compile();

    const buf = u.balign4(Buffer.concat([
      Buffer.alloc(HEAD_LENGTH),
      Buffer.concat(this.binData)
    ]));

    buf.writeUInt32LE(buf.length, O_SIZE);
    buf.write(this.label, O_LABEL);

    debug(`table size = ${buf.length}`);

    return buf;
  }

  getSize() {
    if (!this.compiled) this.compile();

    return u.align4(HEAD_LENGTH + u.sum(this.binData.map(b => b.length)));
  }

  getOffset(id) {
    if (!this.compiled) this.compile();

    let offset = HEAD_LENGTH;

    for (let i = 0; i < id; i++) offset += this.binData[i].length;

    return offset;
  }

  getCompressionCode() {
    if (this.font.opts.no_compress) return 0;
    if (this.font.opts.bpp === 1) return 0;
    if (this.font.opts.no_prefilter) return 2;
    return 1;
  }
}

module.exports = Glyf;


================================================
FILE: lib/font/table_head.js
================================================
'use strict';

const debug = require('debug')('font.table.head');

const u = require('../utils');

const O_SIZE = 0;
const O_LABEL = O_SIZE + 4;
const O_VERSION = O_LABEL + 4;
const O_TABLES = O_VERSION + 4;
const O_FONT_SIZE = O_TABLES + 2;
const O_ASCENT = O_FONT_SIZE + 2;
const O_DESCENT = O_ASCENT + 2;
const O_TYPO_ASCENT = O_DESCENT + 2;
const O_TYPO_DESCENT = O_TYPO_ASCENT + 2;
const O_TYPO_LINE_GAP = O_TYPO_DESCENT + 2;
const O_MIN_Y = O_TYPO_LINE_GAP + 2;
const O_MAX_Y = O_MIN_Y + 2;
const O_DEF_ADVANCE_WIDTH = O_MAX_Y + 2;
const O_KERNING_SCALE = O_DEF_ADVANCE_WIDTH + 2;
const O_INDEX_TO_LOC_FORMAT = O_KERNING_SCALE + 2;
const O_GLYPH_ID_FORMAT = O_INDEX_TO_LOC_FORMAT + 1;
const O_ADVANCE_WIDTH_FORMAT = O_GLYPH_ID_FORMAT + 1;
const O_BITS_PER_PIXEL = O_ADVANCE_WIDTH_FORMAT + 1;
const O_XY_BITS = O_BITS_PER_PIXEL + 1;
const O_WH_BITS = O_XY_BITS + 1;
const O_ADVANCE_WIDTH_BITS = O_WH_BITS + 1;
const O_COMPRESSION_ID = O_ADVANCE_WIDTH_BITS + 1;
const O_SUBPIXELS_MODE = O_COMPRESSION_ID + 1;
const O_TMP_RESERVED1 = O_SUBPIXELS_MODE + 1;
const O_UNDERLINE_POSITION = O_TMP_RESERVED1 + 1;
const O_UNDERLINE_THICKNESS = O_UNDERLINE_POSITION + 2;
const HEAD_LENGTH = u.align4(O_UNDERLINE_THICKNESS + 2);

class Head {
  constructor(font) {
    this.font = font;
    this.label = 'head';
    this.version = 1;
  }

  toBin() {
    const buf = Buffer.alloc(HEAD_LENGTH);
    debug(`table size = ${buf.length}`);

    buf.writeUInt32LE(HEAD_LENGTH, O_SIZE);
    buf.write(this.label, O_LABEL);
    buf.writeUInt32LE(this.version, O_VERSION);

    const f = this.font;

    const tables_count = f.hasKerning() ? 4 : 3;

    buf.writeUInt16LE(tables_count, O_TABLES);

    buf.writeUInt16LE(f.src.size, O_FONT_SIZE);
    buf.writeUInt16LE(f.src.ascent, O_ASCENT);
    buf.writeInt16LE(f.src.descent, O_DESCENT);

    buf.writeUInt16LE(f.src.typoAscent, O_TYPO_ASCENT);
    buf.writeInt16LE(f.src.typoDescent, O_TYPO_DESCENT);
    buf.writeUInt16LE(f.src.typoLineGap, O_TYPO_LINE_GAP);

    buf.writeInt16LE(f.minY, O_MIN_Y);
    buf.writeInt16LE(f.maxY, O_MAX_Y);

    if (f.monospaced) {
      buf.writeUInt16LE(f.widthToInt(f.src.glyphs[0].advanceWidth), O_DEF_ADVANCE_WIDTH);
    } else {
      buf.writeUInt16LE(0, O_DEF_ADVANCE_WIDTH);
    }

    buf.writeUInt16LE(Math.round(f.kerningScale * 16), O_KERNING_SCALE); // FP12.4

    buf.writeUInt8(f.indexToLocFormat, O_INDEX_TO_LOC_FORMAT);
    buf.writeUInt8(f.glyphIdFormat, O_GLYPH_ID_FORMAT);
    buf.writeUInt8(f.advanceWidthFormat, O_ADVANCE_WIDTH_FORMAT);

    buf.writeUInt8(f.opts.bpp, O_BITS_PER_PIXEL);
    buf.writeUInt8(f.xy_bits, O_XY_BITS);
    buf.writeUInt8(f.wh_bits, O_WH_BITS);

    if (f.monospaced) buf.writeUInt8(0, O_ADVANCE_WIDTH_BITS);
    else buf.writeUInt8(f.advanceWidthBits, O_ADVANCE_WIDTH_BITS);

    buf.writeUInt8(f.glyf.getCompressionCode(), O_COMPRESSION_ID);

    buf.writeUInt8(f.subpixels_mode, O_SUBPIXELS_MODE);

    buf.writeInt16LE(f.src.underlinePosition, O_UNDERLINE_POSITION);
    buf.writeUInt16LE(f.src.underlineThickness, O_UNDERLINE_THICKNESS);

    return buf;
  }
}

module.exports = Head;


================================================
FILE: lib/font/table_kern.js
================================================
'use strict';

const debug = require('debug')('font.table.kern');

const u = require('../utils');

const O_SIZE = 0;
const O_LABEL = O_SIZE + 4;
const O_FORMAT = O_LABEL + 4;

const HEAD_LENGTH = u.align4(O_FORMAT + 1);

class Kern {
  constructor(font) {
    this.font = font;
    this.label = 'kern';
    this.format3_forced = false;
  }

  collect_format0_data() {
    const f = this.font;
    const glyphs = u.sort_by(this.font.src.glyphs, g => f.glyph_id[g.code]);
    const kernSorted = [];

    for (let g of glyphs) {
      if (!g.kerning || !Object.keys(g.kerning).length) continue;

      const glyph_id = f.glyph_id[g.code];
      const paired = u.sort_by(Object.keys(g.kerning), code => f.glyph_id[code]);

      for (let code of paired) {
        const glyph_id2 = f.glyph_id[code];
        kernSorted.push([ glyph_id, glyph_id2, g.kerning[code] ]);
      }
    }

    return kernSorted;
  }

  create_format0_data() {
    const f = this.font;
    const glyphs = this.font.src.glyphs;
    const kernSorted = this.collect_format0_data();

    const count = kernSorted.length;

    const kerned_glyphs = glyphs.filter(g => Object.keys(g.kerning).length).length;
    const kerning_list_max = Math.max(...glyphs.map(g => Object.keys(g.kerning).length));
    debug(`${kerned_glyphs} kerned glyphs of ${glyphs.length}, ${kerning_list_max} max list, ${count} total pairs`);

    const subheader = Buffer.alloc(4);

    subheader.writeUInt32LE(count, 0);

    const pairs_buf = Buffer.alloc((f.glyphIdFormat ? 4 : 2) * count);

    // Write kerning pairs
    for (let i = 0; i < count; i++) {
      if (f.glyphIdFormat === 0) {
        pairs_buf.writeUInt8(kernSorted[i][0], 2 * i);
        pairs_buf.writeUInt8(kernSorted[i][1], 2 * i + 1);
      } else {
        pairs_buf.writeUInt16LE(kernSorted[i][0], 4 * i);
        pairs_buf.writeUInt16LE(kernSorted[i][1], 4 * i + 2);
      }
    }

    const values_buf = Buffer.alloc(count);

    // Write kerning values
    for (let i = 0; i < count; i++) {
      values_buf.writeInt8(f.kernToFP(kernSorted[i][2]), i); // FP4.4
    }

    let buf = Buffer.concat([
      subheader,
      pairs_buf,
      values_buf
    ]);

    let buf_aligned = u.balign4(buf);

    debug(`table format0 size = ${buf_aligned.length}`);
    return buf_aligned;
  }

  collect_format3_data() {
    const f = this.font;
    const glyphs = u.sort_by(this.font.src.glyphs, g => f.glyph_id[g.code]);

    // Extract kerning pairs for each character.
    // Left kernings are kerning values based on the left char (already there),
    // right kernings are kerning values based on the right char (extracted from left).
    const left_kernings = {};
    const right_kernings = {};

    for (let g of glyphs) {
      if (!g.kerning || !Object.keys(g.kerning).length) continue;

      const paired = Object.keys(g.kerning);

      left_kernings[g.code] = g.kerning;

      for (let code of paired) {
        right_kernings[code] = right_kernings[code] || {};
        right_kernings[code][g.code] = g.kerning[code];
      }
    }

    // Input:
    //  - kernings, char => { hash: String, [char1]: Number, [char2]: Number, ... }
    //
    // Returns:
    //  - array of [ char1, char2, ... ]
    //
    function build_classes(kernings) {
      const classes = [];

      for (let code of Object.keys(kernings)) {
        // for each kerning table calculate unique value representing it;
        // keys needs to be sorted for this (but we're using numeric keys, so
        // sorting happens automatically and can't be changed)
        const hash = JSON.stringify(kernings[code]);

        classes[hash] = classes[hash] || [];
        classes[hash].push(Number(code));
      }

      return Object.values(classes);
    }

    const left_classes = build_classes(left_kernings);
    debug(`unique left classes: ${left_classes.length}`);

    const right_classes = build_classes(right_kernings);
    debug(`unique right classes: ${right_classes.length}`);

    if (left_classes.length >= 255 || right_classes.length >= 255) {
      debug('too many classes for format3 subtable');
      return null;
    }

    function kern_class_mapping(classes) {
      const arr = Array(f.last_id).fill(0);

      classes.forEach((members, idx) => {
        for (let code of members) {
          arr[f.glyph_id[code]] = idx + 1;
        }
      });

      return arr;
    }

    function kern_class_values() {
      const arr = [];

      for (let left_class of left_classes) {
        for (let right_class of right_classes) {
          let code1 = left_class[0];
          let code2 = right_class[0];
          arr.push(left_kernings[code1][code2] || 0);
        }
      }

      return arr;
    }

    return {
      left_classes:  left_classes.length,
      right_classes: right_classes.length,
      left_mapping:  kern_class_mapping(left_classes),
      right_mapping: kern_class_mapping(right_classes),
      values:        kern_class_values()
    };
  }

  create_format3_data() {
    const f = this.font;
    const {
      left_classes,
      right_classes,
      left_mapping,
      right_mapping,
      values
    } = this.collect_format3_data();

    const subheader = Buffer.alloc(4);
    subheader.writeUInt16LE(f.last_id);
    subheader.writeUInt8(left_classes, 2);
    subheader.writeUInt8(right_classes, 3);

    let buf = Buffer.concat([
      subheader,
      Buffer.from(left_mapping),
      Buffer.from(right_mapping),
      Buffer.from(values.map(v => f.kernToFP(v)))
    ]);

    let buf_aligned = u.balign4(buf);

    debug(`table format3 size = ${buf_aligned.length}`);
    return buf_aligned;
  }

  should_use_format3() {
    if (!this.font.hasKerning()) return false;

    const format0_data = this.create_format0_data();
    const format3_data = this.create_format3_data();

    if (format3_data && format3_data.length <= format0_data.length) return true;

    if (this.font.opts.fast_kerning && format3_data) {
      this.format3_forced = true;
      return true;
    }

    return false;
  }

  toBin() {
    if (!this.font.hasKerning()) return Buffer.alloc(0);

    const format0_data = this.create_format0_data();
    const format3_data = this.create_format3_data();

    let header = Buffer.alloc(HEAD_LENGTH);

    let data = format0_data;
    header.writeUInt8(0, O_FORMAT);

    /* eslint-disable no-console */

    if (this.should_use_format3()) {
      data = format3_data;
      header.writeUInt8(3, O_FORMAT);

      if (this.format3_forced) {
        let diff = format3_data.length - format0_data.length;
        console.log(`Forced faster kerning format (via classes). Size increase is ${diff} bytes.`);
      }
    } else if (this.font.opts.fast_kerning) {
      console.log('Forced faster kerning format (via classes), but data exceeds it\'s limits. Continue use pairs.');
    }

    header.writeUInt32LE(header.length + data.length, O_SIZE);
    header.write(this.label, O_LABEL);

    return Buffer.concat([ header, data ]);
  }
}

module.exports = Kern;


================================================
FILE: lib/font/table_loca.js
================================================
'use strict';

const debug = require('debug')('font.table.loca');

const u = require('../utils');

const O_SIZE = 0;
const O_LABEL = O_SIZE + 4;
const O_COUNT = O_LABEL + 4;

const HEAD_LENGTH = O_COUNT + 4;

class Loca {
  constructor(font) {
    this.font = font;
    this.label = 'loca';
  }

  toBin() {
    const f = this.font;

    const offsets = [ ...Array(f.last_id).keys() ].map(i => f.glyf.getOffset(i));

    const buf = u.balign4(Buffer.concat([
      Buffer.alloc(HEAD_LENGTH),
      f.indexToLocFormat ? u.bFromA32(offsets) : u.bFromA16(offsets)
    ]));

    buf.writeUInt32LE(buf.length, O_SIZE);
    buf.write(this.label, O_LABEL);
    buf.writeUInt32LE(f.last_id, O_COUNT);

    debug(`table size = ${buf.length}`);

    return buf;
  }
}

module.exports = Loca;


================================================
FILE: lib/freetype/build/ft_render.js
================================================

var Module = (() => {
  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
  if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
  return (
function(Module) {
  Module = Module || {};

var Module=typeof Module!=="undefined"?Module:{};var objAssign=Object.assign;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=objAssign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toLog=e;err("exiting due to exception: "+toLog)}var fs;var nodePath;var requireNodeFS;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}requireNodeFS=function(){if(!nodePath){fs=require("fs");nodePath=require("path")}};read_=function shell_read(filename,binary){var ret=tryParseAsDataURI(filename);if(ret){return binary?ret:ret.toString()}requireNodeFS();filename=nodePath["normalize"](filename);return fs.readFileSync(filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=function readAsync(filename,onload,onerror){var ret=tryParseAsDataURI(filename);if(ret){onload(ret)}requireNodeFS();filename=nodePath["normalize"](filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);quit_=((status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}logExceptionOnExit(toThrow);process["exit"](status)});Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText}catch(err){var data=tryParseAsDataURI(url);if(data){return intArrayToString(data)}throw err}};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}catch(err){var data=tryParseAsDataURI(url);if(data){return data}throw err}}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}var data=tryParseAsDataURI(url);if(data){onload(data.buffer);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=(title=>document.title=title)}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);objAssign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var getTempRet0=function(){return tempRet0};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return Number(HEAPF64[ptr>>3]);default:abort("invalid type for getValue: "+type)}return null}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret}function cwrap(ident,returnType,argTypes,opts){argTypes=argTypes||[];var numericArgs=argTypes.every(function(type){return type==="number"});var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="data:application/octet-stream;base64,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KAKQWyAAKAKUWyAAKAKYWyAAKAKcW0EAEGoLIAAgAjYCyFsgACABNgLEWwsgA0EwaiQAC4ABACAAEMgBIABB2NsAaiACNgIAIAAgATYCxFsgACABNgLUWyAAQcjbAGogAjYCACAAQQE6AI9bIAAoAphbIQECQCAAQQhqIgItAAwEQCABLQAFRQ0BCyACIAAoApBbIAAoApRbIAEgACgCnFtBABBqCyAAQaQeaiACQZwe/AoAAAseACAAQgA3AgQgACABNgIAIABCADcCFCAAQgA3AgwLjQEBBX8gAC0AACEEAkADQCAEIAJBAnRB4NUCaigCACIDLQAARgRAIAJByQAgAkHJAEobIQYDQCADIAAgARBWRQRAIAIPC0HLACEFIAIgBkYNAyACQQFqIgJBAnRB4NUCaigCACIDLQAAIARGDQALDAILIAJByQBJIQMgAkEBaiECIAMNAAtBywAhBQsgBQtRAQR/IABFIAFFckUEQCABKAIIIQIgASgCDCEDIAAgACgCACIEIAEoAgAQFSAAKAIEIgUgASgCBBAVajYCACAAIAQgAhAVIAUgAxAVajYCBAsLqwMBBH8jAEEQayIDJAAgAUIANwIAIAFBADYCCCAAEEQgAyAAKAIAIgI2AgwgACgCCCIFIAJLBEACQAJAAkACQAJAAkACQCACLQAAIgRB+wBHBEAgBEHbAEYNASAEQShHDQIgASACNgIAIAFBAjYCCCADQQxqIAUQzgENAwwECyABIAI2AgAgAUEDNgIIIANBDGogBRDRAkUNAwwCCyABIAI2AgAgAUEDNgIIQQEhBCAAIAJBAWo2AgAgABBEAkAgACgCACICIAVPDQADQCAAKAIMDQECQAJAAkAgAi0AAEHbAGsOAwECAAILIARBAUoEQCAEQQFrIQQMAgsgAyACQQFqIgI2AgwgASACNgIEDAkLIARBAWohBAsgABDPASAAEEQgACgCACICIAVJDQALCyADIAI2AgwMAQsgASACNgIAIAFBBEEBIAItAABBL0YbNgIIIAAQzwEgAyAAKAIAIgI2AgwgACgCDEUNAgsgASgCBCECDAILIAMoAgwhAgsgASACNgIECyACDQAgAUEANgIIIAFBADYCAAsgACADKAIMNgIACyADQRBqJAALhAEBBX8jAEEQayICJAAgAiAAKAIAIgQ2AgwgAkEMaiAB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QYGChAhrcUGAgYKEeHENASAEIAU2AgAgBEEEaiEEIAFBBGohASADQQRrIgNBA0sNAAsLIANFDQADQCAEIAEtAAAiBToAACAFRQ0CIARBAWohBCABQQFqIQEgA0EBayIDDQALC0EAIQMLIARBACADEHwgACAIakEAOgAAIAdBAWohAQwBCyAAQQA6AAALIAAgAhDZAiABENkCIQMLIAZBEGokACADCxkAIAAgARA5IgBFBEBBAA8LIAAoAgAoAhQLNgECfwJAIABFDQAgACgCXCIDRQ0AIAMgASADKAIMKAIMEQAAIgFBACABIAAoAhBJGyECCyACC3UBBX8gAARAIAAgAC4BOCICIAAvARRqOwEUIAAgAC8BFiIDIAAvATpqOwEWIAAgACgCMCAAKAJUajYCMCACQQBKBEAgACgCRCEEA0AgBCABQQF0aiIFIAUvAQAgA2o7AQAgAUEBaiIBIAJHDQALCyAAEKECCwsKACAAKAIAQQBHCw0AIAAtAABBCnFBAEcLtQIBBH8gAEIANwIAIABBADYCECAAQgA3AggCfwJAIAEgAhBbIggoAggiASAIKAIEIglrIgpBgICwf0cEQCAKQYCArH9HDQEgBkUEQEEBDAMLIAAgATYCCEEBIQdBAAwCC0EBIAYNARogACAJNgIIQQIhB0EADAELAkACQCAKQQBIBEAgBgRAIAAgATYCCAwDCyAAIAk2AggMAQsgBgRAIAAgCTYCCAwCCyAAIAE2AggLQQghB0EADAELQQQhB0EACyEBIAAgBzYCACAAKAIIIQcgABCGAQRAIAMoAugBQQF0IAdqIQcLIAAgBTYCECAAIAI2AgQgACAEIAdqIgI2AggCQCABDQAgCC0AAEUNACAAIAhBEEEMIAAQhgEbaigCADYCDCAAEMMBDwsgACACIAUQFTYCDAsjACAAQQA2AhQgAEIANwIMIAAoAgAgACgCGBAUIABBADYCGAs5AQF/IABBAEGcHvwLACABLQC4ASEFIAAgBDYCECAAIAU6AA0gACADNgIIIAAgAjYCBCAAIAE2AgALNgAgABAoIAFJBEAgACgCBEGCARAxDwsgAUEDdCIBIAAoAghqIAI2AgAgACgCCCABakEANgIEC70DAQd/IwBBQGoiByQAIAcgASgCACIJNgIAIAcgAigCADYCBEEKQQkgBC0ACSIKGyELA0AgCEECdCAHaiIMQQhqIAk2AgAgBCAIai0AAARAIAwgACAGEBsgCWo2AgggBkEBaiEGCyALIAhBAWoiCEcEQCAHIAhBAnRqKAIAIQkMAQsLIApFBEAgByACKAIANgIsCyAHAn8CQCAFBEAgAigCACEJIAcoAiwhBCABKAIAIQogBygCKCEFIAAgBhAbIQggBSAKayIGIAZBH3UiBmogBnMgBCAJayIGIAZBH3UiBmogBnNKBEAgByAFIAhqIgU2AjAMAgsgByABKAIAIgU2AjAgBCAIagwCCyAHAn8gBC0ACgRAIAZBAWohCCAHKAIoIAAgBhAbagwBCyAGIQggASgCAAsiBTYCMCAELQALRQ0AIAcoAiwgACAIEBtqDAELIAIoAgALIgY2AjRBACEIQQEhCQNAIAMgCEECdCAHaiIEKAIIIAQoAgwgBCgCECAEKAIUIAQoAhggBCgCHBBQIAlBAXEhBEEGIQhBACEJIAQNAAsgABBcIAEgBTYCACACIAY2AgAgB0FAayQAC7gBAQN/IwBBIGsiBiQAIAEQKCIIQQFxIQcCQCAALQAIIAdFcg0AIAQtAAANACADIAFBABAbIAAoArABELgCajYCAAsgACgCsAEtAKQERQRAIAhBAk8EQANAIAYgASAHEBsgBWoiADYCDCABIAdBAWoQGyEDIAZCADcCFCAGQQA6AAggBiAAIANqIgU2AhAgAiAGQQhqEK4CIAdBAmoiByAISQ0ACwsgARBcCyAEQQE6AAAgBkEgaiQACyUAIABCADcCDCAAIAM2AgggACACNgIEIAAgATYCACAAQgA3AhQLWgEDfyAAKAIUIQQgAC0ALQRAIAQoAgghACAEKAIEIAQuAQIiBUEDdGoiBiACQQp1NgIEIAYgAUEKdTYCACAAIAVqQQFBAiADGzoAAAsgBCAELwECQQFqOwECCysBAX8gACgCDCIALgEWIAFqIAAuATpqIAAoAgRLBH8gACABQQAQRQUgAgsLGgAgAEENdCAAcyIAQRF2IABzIgBBBXQgAHML6wcBDH8jAEEQayIEJABBASEDIAAoAkhB7OjV+wZGBEAgAEHsAGohAyACBH8gAigCBCEFIAIoAgAFQQALIQIgAyAEEGYgBCAFQT9xIgMgBCgCDCIGQT9xaiIINgIMIAQgAkE/cSIJIAQoAggiB0E/cWoiDDYCCCAEIAMgBCgCBCIKQT9xaiINNgIEIAQgBCgCACIDQT9xIAlqIg42AgAgBUEGdSIFIAZBBnVqIQkgAkEGdSICIAdBBnVqIQsgCkEGdSAFaiEHIANBBnUgAmohCkECIQNBBSECAkACfwJAAkACQAJAAkAgAUECaw4DAAIBAwsCfyAOQR9qIgJBBnYgCmoiASAMQSBqIgNBBnYgC2oiBkYEQCACQT9xIANBP3FqQR9rQR9MBEAgASEGIAFBAWsMAgsgAUEBaiEGCyABCyEBIAcgDUEfaiIFQQZ2aiIDIAkgCEEgaiIHQQZ2aiICRw0DIAVBP3EgB0E/cWpBH2tBH0wEQCADIgJBAWsMBQsgA0EBaiECDAMLQQQhAUEGIQILIAAoAgAhAwJAAkACQCABQQNrDgIAAQILIAQgBCgCACADKAK0ASIBIAMoArwBIgUgASAFShsiCCADKALEASIGIAYgCEgbazYCACAEIAQoAgggASAFIAEgBUgbIgEgBiABIAZIG2s2AgggBCAEKAIEIAMoArgBIgEgAygCwAEiBSABIAVKGyIGIAMoAsgBIgMgAyAGSBtrNgIEIAQgBCgCDCABIAUgASAFSBsiASADIAEgA0gbazYCDAwBCyAEIAQoAgAgAygCuAEiASADKALAASIFIAEgBUobIgggAygCyAEiBiAGIAhIG2s2AgAgBCAEKAIIIAEgBSABIAVIGyIBIAYgASAGSBtrNgIIIAQgBCgCBCADKAK0ASIBIAMoArwBIgUgASAFSBsiBiADKALEASIDIAMgBkobajYCBCAEIAQoAgwgASAFIAEgBUobIgEgAyABIANKG2o2AgwLIAIhAwsgBCgCDEE/akEGdSAJaiICIAQoAgRBBnUgB2oiCGshByAEKAIIQT9qQQZ1IAtqIgYgBCgCAEEGdSAKaiIBayIFIQkCQAJAIANBBWsOAgABBAsgBUEDbCIFQQNqQXxxIQlBBSEDDAMLIAdBA2whB0EGIQMgBSEJDAILIAMLIQggAiAIayEHIAYgAWsiBUEPakEDdUF+cSEJQQEhAwsgACACNgJoIAAgATYCZCAAIAc2AkwgACADOgBeIABBgAI7AVwgACAFNgJQIAAgCTYCVCABQYCAfkggBkH//wFKciAIQYCAfkhyIAJB//8BSnIhAwsgBEEQaiQAIAMLQQECfyMAQRBrIgIkACACQQM2AghBoAEhAyAAIAJBCGpBARBRQQFGBEAgASACKAIMNgIAQQAhAwsgAkEQaiQAIAML9wEBBX8CQAJAIAAoAhQiAEUNAAJAAkAgAC8BACIBwSIDQQJOBEAgACgCDCABQQF0akEEay4BAEEBaiECDAELIAMNACAALgECIQEMAQsgAiAALgECIgFHDQAMAgsCQCABQQJIDQAgACgCBCIEIAJBA3RqIgUoAgAgBCABQQN0akEIayIEKAIARw0AIAUoAgQgBCgCBEcNACAAKAIIIAFqQQFrLQAAQQFHDQAgACABQQFrIgE7AQILIANBAEwNACACIAHBQQFrIgJGBEAgACABQQFrOwECDAILIAAoAgwgA0EBdGpBAmsgAjsBAAsPCyAAIANBAWs7AQALMwEBfwJAIAFFDQAgACgCDCIALgEWIAFqIAAuATpqIAAoAgRNDQAgACABQQAQRSECCyACCzEBAX8gACgCCCIBBEAgASAAKAIQIgApAgA3AmwgASAAKAIQNgJ8IAEgACkCCDcCdAsLvAEBBH8CQCAAKAIAIgFFDQADQCABIAEoAggiAygCADYCACABIAEoAhBBAWs2AhAgASADQQRBfCABLwEMQQhxG2o2AgggASgCBCIBDQALIAAoAgAiAUUNACABKAIEIgJFDQAgAUEEaiEEIAAhAwNAAn8gASgCACACKAIATARAIAIhASAEDAELIAMgAjYCACAEIAIoAgQ2AgAgAiABNgIEIAAoAgAhASAACyEDIAFBBGohBCABKAIEIgINAAsLCwsAIAAoAgAgABAUCwQAQQALPAEDfyMAQRBrIgIkACAAQQQgAkEMahAiIQMgAigCDCIERQRAIAMgADYCAAsgASADNgIAIAJBEGokACAEC94BAQN/IAAgBCAFEOEBIgQEfyAEBSMAQRBrIgQkAAJAIABBDGogBSAEQQxqEOYCIgYNACAEKAIMIgAgAyAFEOABIgYNACAAIAM2AgBBACEGIANFDQAgASACQQN2aiEFQYABIAJBB3F2IQEgACgCCCECQYABIQADQCACIAAgAi0AACIHciAHIABBf3NxIAEgBS0AAHEbOgAAQYABIABBAXUgAEECSSIHGyEAQYABIAFBAXUgAUECSSIIGyEBIAIgB2ohAiAFIAhqIQUgA0EBayIDDQALCyAEQRBqJAAgBgsLUAEB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
Download .txt
gitextract_jsukcq61/

├── .editorconfig
├── .eslintrc.yml
├── .github/
│   ├── auto-comment.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .node-version
├── .nvmrc
├── .posthtmlrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc/
│   └── font_spec.md
├── lib/
│   ├── app_error.js
│   ├── cli.js
│   ├── collect_font_data.js
│   ├── convert.js
│   ├── font/
│   │   ├── cmap_build_subtables.js
│   │   ├── compress.js
│   │   ├── font.js
│   │   ├── table_cmap.js
│   │   ├── table_glyf.js
│   │   ├── table_head.js
│   │   ├── table_kern.js
│   │   └── table_loca.js
│   ├── freetype/
│   │   ├── build/
│   │   │   └── ft_render.js
│   │   ├── index.js
│   │   └── render.c
│   ├── ranger.js
│   ├── utils.js
│   └── writers/
│       ├── bin.js
│       ├── dump.js
│       └── lvgl/
│           ├── index.js
│           ├── lv_font.js
│           ├── lv_table_cmap.js
│           ├── lv_table_glyf.js
│           ├── lv_table_head.js
│           └── lv_table_kern.js
├── lv_font_conv.js
├── package.json
├── support/
│   ├── Dockerfile
│   ├── build.sh
│   └── build_web.js
├── test/
│   ├── .eslintrc.yml
│   ├── font/
│   │   ├── fixtures/
│   │   │   ├── font_info_AV.json
│   │   │   └── font_info_AV_size200.json
│   │   ├── test_cmap_build_subtables.js
│   │   ├── test_compress.js
│   │   └── test_font.js
│   ├── test_cli.js
│   ├── test_collect_font_data.js
│   ├── test_ranger.js
│   └── test_utils.js
└── web/
    ├── .eslintrc.yml
    ├── .htmlhintrc
    ├── content.html
    ├── convert_browser.js
    ├── index.html
    └── index.js
Download .txt
SYMBOL INDEX (249 symbols across 26 files)

FILE: lib/cli.js
  class ActionFontAdd (line 11) | class ActionFontAdd extends argparse.Action {
    method call (line 12) | call(parser, namespace, value/*, option_string*/) {
  class ActionFontRangeAdd (line 20) | class ActionFontRangeAdd extends argparse.Action {
    method call (line 21) | call(parser, namespace, value, option_string) {
  class ActionFontStoreTrue (line 34) | class ActionFontStoreTrue extends argparse.Action {
    method constructor (line 35) | constructor(options) {
    method call (line 43) | call(parser, namespace, _value, option_string) {
  class RawTextHelpFormatter2 (line 57) | class RawTextHelpFormatter2 extends argparse.RawDescriptionHelpFormatter {
    method _split_lines (line 59) | _split_lines(text, width) {
  function unicode_point (line 65) | function unicode_point(str) {
  function range (line 80) | function range(str) {
  function positive_int (line 105) | function positive_int(str) {
  function removeFlagAndValue (line 304) | function removeFlagAndValue(flag, args_for_opts_string) {

FILE: lib/convert.js
  function convert (line 23) | async function convert(args) {

FILE: lib/font/cmap_build_subtables.js
  function estimate_format0_tiny_size (line 22) | function estimate_format0_tiny_size(/*start_code, end_code*/) {
  function estimate_format0_size (line 26) | function estimate_format0_size(start_code, end_code) {
  function estimate_sparse_tiny_size (line 34) | function estimate_sparse_tiny_size(count) {

FILE: lib/font/compress.js
  function count_same (line 5) | function count_same(arr, offset) {

FILE: lib/font/font.js
  class Font (line 12) | class Font {
    method constructor (line 13) | constructor(fontData, options) {
    method init_tables (line 75) | init_tables() {
    method createIDs (line 83) | createIDs() {
    method hasKerning (line 94) | hasKerning() {
    method widthToInt (line 104) | widthToInt(val) {
    method kernToFP (line 111) | kernToFP(val) {
    method toBin (line 115) | toBin() {

FILE: lib/font/table_cmap.js
  constant O_SIZE (line 8) | const O_SIZE = 0;
  constant O_LABEL (line 9) | const O_LABEL = O_SIZE + 4;
  constant O_COUNT (line 10) | const O_COUNT = O_LABEL + 4;
  constant HEAD_LENGTH (line 12) | const HEAD_LENGTH = O_COUNT + 4;
  constant SUB_FORMAT_0 (line 14) | const SUB_FORMAT_0 = 0;
  constant SUB_FORMAT_0_TINY (line 15) | const SUB_FORMAT_0_TINY = 2;
  constant SUB_FORMAT_SPARSE (line 16) | const SUB_FORMAT_SPARSE = 1;
  constant SUB_FORMAT_SPARSE_TINY (line 17) | const SUB_FORMAT_SPARSE_TINY = 3;
  class Cmap (line 19) | class Cmap {
    method constructor (line 20) | constructor(font) {
    method compile (line 30) | compile() {
    method createSubHeader (line 78) | createSubHeader(rangeStart, rangeLen, glyphIdOffset, total, type) {
    method subHeaderUpdateOffset (line 91) | subHeaderUpdateOffset(header, val) {
    method subHeaderUpdateAllOffsets (line 95) | subHeaderUpdateAllOffsets() {
    method glyphByCode (line 105) | glyphByCode(code) {
    method collect_format0_data (line 109) | collect_format0_data(min_code, max_code, start_glyph_id) {
    method create_format0_data (line 130) | create_format0_data(min_code, max_code, start_glyph_id) {
    method collect_sparse_data (line 136) | collect_sparse_data(codepoints, start_glyph_id) {
    method create_sparse_data (line 160) | create_sparse_data(codepoints, start_glyph_id) {
    method create_sparse_tiny_data (line 169) | create_sparse_tiny_data(codepoints, start_glyph_id) {
    method toBin (line 175) | toBin() {

FILE: lib/font/table_glyf.js
  constant O_SIZE (line 9) | const O_SIZE = 0;
  constant O_LABEL (line 10) | const O_LABEL = O_SIZE + 4;
  constant HEAD_LENGTH (line 12) | const HEAD_LENGTH = O_LABEL + 4;
  class Glyf (line 14) | class Glyf {
    method constructor (line 15) | constructor(font) {
    method pixelsToBpp (line 25) | pixelsToBpp(pixels) {
    method widthToStride (line 30) | widthToStride(width) {
    method compileGlyph (line 41) | compileGlyph(glyph) {
    method storePixels (line 83) | storePixels(bitStream, pixels) {
    method addPadding (line 88) | addPadding(bitStream, pad) {
    method storePixelsRaw (line 95) | storePixelsRaw(bitStream, pixels) {
    method storePixelsCompressed (line 117) | storePixelsCompressed(bitStream, pixels) {
    method compile (line 128) | compile() {
    method toBin (line 144) | toBin() {
    method getSize (line 160) | getSize() {
    method getOffset (line 166) | getOffset(id) {
    method getCompressionCode (line 176) | getCompressionCode() {

FILE: lib/font/table_head.js
  constant O_SIZE (line 7) | const O_SIZE = 0;
  constant O_LABEL (line 8) | const O_LABEL = O_SIZE + 4;
  constant O_VERSION (line 9) | const O_VERSION = O_LABEL + 4;
  constant O_TABLES (line 10) | const O_TABLES = O_VERSION + 4;
  constant O_FONT_SIZE (line 11) | const O_FONT_SIZE = O_TABLES + 2;
  constant O_ASCENT (line 12) | const O_ASCENT = O_FONT_SIZE + 2;
  constant O_DESCENT (line 13) | const O_DESCENT = O_ASCENT + 2;
  constant O_TYPO_ASCENT (line 14) | const O_TYPO_ASCENT = O_DESCENT + 2;
  constant O_TYPO_DESCENT (line 15) | const O_TYPO_DESCENT = O_TYPO_ASCENT + 2;
  constant O_TYPO_LINE_GAP (line 16) | const O_TYPO_LINE_GAP = O_TYPO_DESCENT + 2;
  constant O_MIN_Y (line 17) | const O_MIN_Y = O_TYPO_LINE_GAP + 2;
  constant O_MAX_Y (line 18) | const O_MAX_Y = O_MIN_Y + 2;
  constant O_DEF_ADVANCE_WIDTH (line 19) | const O_DEF_ADVANCE_WIDTH = O_MAX_Y + 2;
  constant O_KERNING_SCALE (line 20) | const O_KERNING_SCALE = O_DEF_ADVANCE_WIDTH + 2;
  constant O_INDEX_TO_LOC_FORMAT (line 21) | const O_INDEX_TO_LOC_FORMAT = O_KERNING_SCALE + 2;
  constant O_GLYPH_ID_FORMAT (line 22) | const O_GLYPH_ID_FORMAT = O_INDEX_TO_LOC_FORMAT + 1;
  constant O_ADVANCE_WIDTH_FORMAT (line 23) | const O_ADVANCE_WIDTH_FORMAT = O_GLYPH_ID_FORMAT + 1;
  constant O_BITS_PER_PIXEL (line 24) | const O_BITS_PER_PIXEL = O_ADVANCE_WIDTH_FORMAT + 1;
  constant O_XY_BITS (line 25) | const O_XY_BITS = O_BITS_PER_PIXEL + 1;
  constant O_WH_BITS (line 26) | const O_WH_BITS = O_XY_BITS + 1;
  constant O_ADVANCE_WIDTH_BITS (line 27) | const O_ADVANCE_WIDTH_BITS = O_WH_BITS + 1;
  constant O_COMPRESSION_ID (line 28) | const O_COMPRESSION_ID = O_ADVANCE_WIDTH_BITS + 1;
  constant O_SUBPIXELS_MODE (line 29) | const O_SUBPIXELS_MODE = O_COMPRESSION_ID + 1;
  constant O_TMP_RESERVED1 (line 30) | const O_TMP_RESERVED1 = O_SUBPIXELS_MODE + 1;
  constant O_UNDERLINE_POSITION (line 31) | const O_UNDERLINE_POSITION = O_TMP_RESERVED1 + 1;
  constant O_UNDERLINE_THICKNESS (line 32) | const O_UNDERLINE_THICKNESS = O_UNDERLINE_POSITION + 2;
  constant HEAD_LENGTH (line 33) | const HEAD_LENGTH = u.align4(O_UNDERLINE_THICKNESS + 2);
  class Head (line 35) | class Head {
    method constructor (line 36) | constructor(font) {
    method toBin (line 42) | toBin() {

FILE: lib/font/table_kern.js
  constant O_SIZE (line 7) | const O_SIZE = 0;
  constant O_LABEL (line 8) | const O_LABEL = O_SIZE + 4;
  constant O_FORMAT (line 9) | const O_FORMAT = O_LABEL + 4;
  constant HEAD_LENGTH (line 11) | const HEAD_LENGTH = u.align4(O_FORMAT + 1);
  class Kern (line 13) | class Kern {
    method constructor (line 14) | constructor(font) {
    method collect_format0_data (line 20) | collect_format0_data() {
    method create_format0_data (line 40) | create_format0_data() {
    method collect_format3_data (line 87) | collect_format3_data() {
    method create_format3_data (line 178) | create_format3_data() {
    method should_use_format3 (line 206) | should_use_format3() {
    method toBin (line 222) | toBin() {

FILE: lib/font/table_loca.js
  constant O_SIZE (line 7) | const O_SIZE = 0;
  constant O_LABEL (line 8) | const O_LABEL = O_SIZE + 4;
  constant O_COUNT (line 9) | const O_COUNT = O_LABEL + 4;
  constant HEAD_LENGTH (line 11) | const HEAD_LENGTH = O_COUNT + 4;
  class Loca (line 13) | class Loca {
    method constructor (line 14) | constructor(font) {
    method toBin (line 19) | toBin() {

FILE: lib/freetype/build/ft_render.js
  function locateFile (line 9) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
  function logExceptionOnExit (line 9) | function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toL...
  function getValue (line 9) | function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.l...
  function assert (line 9) | function assert(condition,text){if(!condition){abort(text)}}
  function getCFunc (line 9) | function getCFunc(ident){var func=Module["_"+ident];return func}
  function ccall (line 9) | function ccall(ident,returnType,argTypes,args,opts){var toC={"string":fu...
  function cwrap (line 9) | function cwrap(ident,returnType,argTypes,opts){argTypes=argTypes||[];var...
  function UTF8ArrayToString (line 9) | function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBy...
  function UTF8ToString (line 9) | function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(H...
  function stringToUTF8Array (line 9) | function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxByte...
  function stringToUTF8 (line 9) | function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Arr...
  function lengthBytesUTF8 (line 9) | function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){va...
  function UTF16ToString (line 9) | function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr...
  function stringToUTF16 (line 9) | function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===...
  function lengthBytesUTF16 (line 9) | function lengthBytesUTF16(str){return str.length*2}
  function UTF32ToString (line 9) | function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>...
  function stringToUTF32 (line 9) | function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===...
  function lengthBytesUTF32 (line 9) | function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){v...
  function writeArrayToMemory (line 9) | function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}
  function writeAsciiToMemory (line 9) | function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.le...
  function alignUp (line 9) | function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}ret...
  function updateGlobalBufferAndViews (line 9) | function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP...
  function keepRuntimeAlive (line 9) | function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounte...
  function preRun (line 9) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
  function initRuntime (line 9) | function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__AT...
  function postRun (line 9) | function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="f...
  function addOnPreRun (line 9) | function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}
  function addOnInit (line 9) | function addOnInit(cb){__ATINIT__.unshift(cb)}
  function addOnPostRun (line 9) | function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}
  function addRunDependency (line 9) | function addRunDependency(id){runDependencies++;if(Module["monitorRunDep...
  function removeRunDependency (line 9) | function removeRunDependency(id){runDependencies--;if(Module["monitorRun...
  function abort (line 9) | function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}wha...
  function isDataURI (line 9) | function isDataURI(filename){return filename.startsWith(dataURIPrefix)}
  function isFileURI (line 9) | function isFileURI(filename){return filename.startsWith("file://")}
  function getBinary (line 9) | function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return...
  function getBinaryPromise (line 9) | function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRON...
  function createWasm (line 9) | function createWasm(){var info={"a":asmLibraryArg};function receiveInsta...
  function callRuntimeCallbacks (line 9) | function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var c...
  function getWasmTableEntry (line 9) | function getWasmTableEntry(funcPtr){return wasmTable.get(funcPtr)}
  function __embind_register_bigint (line 9) | function __embind_register_bigint(primitiveType,name,size,minRange,maxRa...
  function getShiftFromSize (line 9) | function getShiftFromSize(size){switch(size){case 1:return 0;case 2:retu...
  function embind_init_charCodes (line 9) | function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<...
  function readLatin1String (line 9) | function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret...
  function makeLegalFunctionName (line 9) | function makeLegalFunctionName(name){if(undefined===name){return"_unknow...
  function createNamedFunction (line 9) | function createNamedFunction(name,body){name=makeLegalFunctionName(name)...
  function extendError (line 9) | function extendError(baseErrorType,errorName){var errorClass=createNamed...
  function throwBindingError (line 9) | function throwBindingError(message){throw new BindingError(message)}
  function registerType (line 9) | function registerType(rawType,registeredInstance,options){options=option...
  function __embind_register_bool (line 9) | function __embind_register_bool(rawType,name,size,trueValue,falseValue){...
  function __emval_decref (line 9) | function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[ha...
  function count_emval_handles (line 9) | function count_emval_handles(){var count=0;for(var i=5;i<emval_handle_ar...
  function get_first_emval (line 9) | function get_first_emval(){for(var i=5;i<emval_handle_array.length;++i){...
  function init_emval (line 9) | function init_emval(){Module["count_emval_handles"]=count_emval_handles;...
  function simpleReadValueFromPointer (line 9) | function simpleReadValueFromPointer(pointer){return this["fromWireType"]...
  function __embind_register_emval (line 9) | function __embind_register_emval(rawType,name){name=readLatin1String(nam...
  function floatReadValueFromPointer (line 9) | function floatReadValueFromPointer(name,shift){switch(shift){case 2:retu...
  function __embind_register_float (line 9) | function __embind_register_float(rawType,name,size){var shift=getShiftFr...
  function integerReadValueFromPointer (line 9) | function integerReadValueFromPointer(name,shift,signed){switch(shift){ca...
  function __embind_register_integer (line 9) | function __embind_register_integer(primitiveType,name,size,minRange,maxR...
  function __embind_register_memory_view (line 9) | function __embind_register_memory_view(rawType,dataTypeIndex,name){var t...
  function __embind_register_std_string (line 9) | function __embind_register_std_string(rawType,name){name=readLatin1Strin...
  function __embind_register_std_wstring (line 9) | function __embind_register_std_wstring(rawType,charSize,name){name=readL...
  function __embind_register_void (line 9) | function __embind_register_void(rawType,name){name=readLatin1String(name...
  function __emscripten_throw_longjmp (line 9) | function __emscripten_throw_longjmp(){throw"longjmp"}
  function _emscripten_memcpy_big (line 9) | function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src...
  function emscripten_realloc_buffer (line 9) | function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer...
  function _emscripten_resize_heap (line 9) | function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.lengt...
  function _emscripten_run_script (line 9) | function _emscripten_run_script(ptr){eval(UTF8ToString(ptr))}
  function getExecutableName (line 9) | function getExecutableName(){return thisProgram||"./this.program"}
  function getEnvStrings (line 9) | function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof nav...
  function _environ_get (line 9) | function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings...
  function _environ_sizes_get (line 9) | function _environ_sizes_get(penviron_count,penviron_buf_size){var string...
  function _getTempRet0 (line 9) | function _getTempRet0(){return getTempRet0()}
  function _setTempRet0 (line 9) | function _setTempRet0(val){setTempRet0(val)}
  function intArrayToString (line 9) | function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i...
  function intArrayFromBase64 (line 9) | function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE==="boolean"...
  function tryParseAsDataURI (line 9) | function tryParseAsDataURI(filename){if(!isDataURI(filename)){return}ret...
  function invoke_iii (line 9) | function invoke_iii(index,a1,a2){var sp=stackSave();try{return getWasmTa...
  function invoke_iiiii (line 9) | function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return g...
  function invoke_iiii (line 9) | function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWa...
  function ExitStatus (line 9) | function ExitStatus(status){this.name="ExitStatus";this.message="Program...
  function run (line 9) | function run(args){args=args||arguments_;if(runDependencies>0){return}pr...

FILE: lib/freetype/index.js
  function from_16_16 (line 16) | function from_16_16(fixed_point) {
  function from_26_6 (line 20) | function from_26_6(fixed_point) {
  function int8_to_uint8 (line 24) | function int8_to_uint8(value) {

FILE: lib/freetype/render.c
  function set_js_variable (line 6) | static void set_js_variable(char* name, int value) {
  function init_constants (line 13) | void init_constants()

FILE: lib/ranger.js
  class Ranger (line 6) | class Ranger {
    method constructor (line 7) | constructor() {
    method add_range (line 16) | add_range(font, start, end, mapped_start) {
    method add_symbols (line 29) | add_symbols(font, str) {
    method _set_char (line 41) | _set_char(font, code, mapped_to) {
    method get (line 45) | get() {

FILE: lib/utils.js
  function set_byte_depth (line 3) | function set_byte_depth(depth) {
  function count_bits (line 24) | function count_bits(val) {
  function align4 (line 47) | function align4(size) {
  function chunk (line 89) | function chunk(arr, size) {

FILE: lib/writers/lvgl/lv_font.js
  class LvFont (line 12) | class LvFont extends Font {
    method constructor (line 13) | constructor(fontData, options) {
    method init_tables (line 38) | init_tables() {
    method stride_guard (line 45) | stride_guard() {
    method large_format_guard (line 55) | large_format_guard() {
    method toLVGL (line 82) | toLVGL() {

FILE: lib/writers/lvgl/lv_table_cmap.js
  class LvCmap (line 7) | class LvCmap extends Cmap {
    method constructor (line 8) | constructor(font) {
    method lv_format2enum (line 15) | lv_format2enum(name) {
    method lv_compile (line 25) | lv_compile() {
    method toLVGL (line 103) | toLVGL() {

FILE: lib/writers/lvgl/lv_table_glyf.js
  class LvGlyf (line 7) | class LvGlyf extends Glyf {
    method constructor (line 8) | constructor(font) {
    method lv_bitmap (line 15) | lv_bitmap(glyph) {
    method lv_compile (line 41) | lv_compile() {
    method to_lv_bitmaps (line 62) | to_lv_bitmaps() {
    method to_lv_glyph_dsc (line 88) | to_lv_glyph_dsc() {
    method toLVGL (line 108) | toLVGL() {

FILE: lib/writers/lvgl/lv_table_head.js
  class LvHead (line 5) | class LvHead extends Head {
    method constructor (line 6) | constructor(font) {
    method kern_ref (line 10) | kern_ref() {
    method get_stride_align (line 36) | get_stride_align() {
    method toLVGL (line 43) | toLVGL() {

FILE: lib/writers/lvgl/lv_table_kern.js
  class LvKern (line 6) | class LvKern extends Kern {
    method constructor (line 7) | constructor(font) {
    method to_lv_format0 (line 11) | to_lv_format0() {
    method to_lv_format3 (line 45) | to_lv_format3() {
    method toLVGL (line 91) | toLVGL() {

FILE: support/build_web.js
  constant OUT_DIR (line 8) | const OUT_DIR = 'dist';

FILE: test/font/test_cmap_build_subtables.js
  function range (line 6) | function range(from, to) {

FILE: test/font/test_compress.js
  function c (line 8) | function c(data, opts) {

FILE: test/font/test_font.js
  function isSimilar (line 179) | function isSimilar(a, b, epsilon) {

FILE: web/convert_browser.js
  function convertBrowser (line 10) | async function convertBrowser(args) {

FILE: web/index.js
  function handleFiles (line 7) | function handleFiles() {
  function addFontFileChangeHandlers (line 32) | function addFontFileChangeHandlers() {
  function resetInput (line 37) | function resetInput($e) {
  function addFont (line 42) | function addFont() {
  function generate_range (line 59) | function generate_range(start, end, transpose) {
  function generate_opts_string (line 69) | function generate_opts_string(args) {
Condensed preview — 58 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,270K chars).
[
  {
    "path": ".editorconfig",
    "chars": 131,
    "preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newl"
  },
  {
    "path": ".eslintrc.yml",
    "chars": 5293,
    "preview": "env:\n  node: true\n  es6:  true\n\nparserOptions:\n  ecmaVersion: '2018'\n\nignorePatterns:\n  - dist\n  - lib/freetype/build\n\nr"
  },
  {
    "path": ".github/auto-comment.yml",
    "chars": 737,
    "preview": "# Comment to a new issue.\n\npullRequestOpened: |\n  Thank you for raising your pull request.\n  \n  To ensure that all licen"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 361,
    "preview": "name: CI\n\non:\n  push:\n  pull_request:\n  schedule:\n    - cron: '0 0 * * 3'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    "
  },
  {
    "path": ".gitignore",
    "chars": 80,
    "preview": "node_modules\ncoverage\n.nyc_output\ndist\n.parcel-cache\n.cache\n*.log\n*.swp\n.vscode\n"
  },
  {
    "path": ".node-version",
    "chars": 8,
    "preview": "24.11.1\n"
  },
  {
    "path": ".nvmrc",
    "chars": 8,
    "preview": "24.11.1\n"
  },
  {
    "path": ".posthtmlrc",
    "chars": 77,
    "preview": "{\n  \"plugins\": {\n    \"posthtml-include\": {\n      \"root\": \"./web\"\n    }\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 3382,
    "preview": "1.5.2 / 2021-07-18\n------------------\n\n- Fixed lvgl version check for v8+, #64.\n\n\n1.5.1 / 2021-04-06\n------------------\n"
  },
  {
    "path": "LICENSE",
    "chars": 1051,
    "preview": "Copyright (c) 2018 authors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this softwar"
  },
  {
    "path": "README.md",
    "chars": 6284,
    "preview": "# lv_font_conv\n\n[![CI](https://github.com/lvgl/lv_font_conv/workflows/CI/badge.svg?branch=master)](https://github.com/lv"
  },
  {
    "path": "doc/font_spec.md",
    "chars": 11543,
    "preview": "# Bitmap font format for embedded systems\n\nCompact binary bitmap font format tailored for embedded targets with limited\n"
  },
  {
    "path": "lib/app_error.js",
    "chars": 144,
    "preview": "// Custom Error type to simplify error messaging\n'use strict';\n\nconst AppError = require('make-error')('AppError');\n\nmod"
  },
  {
    "path": "lib/cli.js",
    "chars": 10449,
    "preview": "// Parse input arguments and execute converter.\n\n'use strict';\n\nconst argparse    = require('argparse');\nconst fs       "
  },
  {
    "path": "lib/collect_font_data.js",
    "chars": 5580,
    "preview": "'use strict';\n\nconst opentype  = require('opentype.js');\nconst ft_render = require('./freetype');\nconst AppError  = requ"
  },
  {
    "path": "lib/convert.js",
    "chars": 720,
    "preview": "// Internal API to convert input data into output font data\n// Used by both CLI and Web wrappers.\n\n'use strict';\n\nconst "
  },
  {
    "path": "lib/font/cmap_build_subtables.js",
    "chars": 2853,
    "preview": "/**\n * Find an optimal configuration of cmap tables representing a set of codepoints,\n * using a simple breadth-first al"
  },
  {
    "path": "lib/font/compress.js",
    "chars": 2964,
    "preview": "'use strict';\n\n//const debug = require('debug')('compress');\n\nfunction count_same(arr, offset) {\n  let same = 1;\n  let v"
  },
  {
    "path": "lib/font/font.js",
    "chars": 3771,
    "preview": "// Font class to generate tables\n'use strict';\n\nconst u = require('../utils');\nconst debug = require('debug')('font');\nc"
  },
  {
    "path": "lib/font/table_cmap.js",
    "chars": 5250,
    "preview": "'use strict';\n\nconst debug = require('debug')('font.table.cmap');\n\nconst build_subtables = require('./cmap_build_subtabl"
  },
  {
    "path": "lib/font/table_glyf.js",
    "chars": 4568,
    "preview": "'use strict';\n\nconst { BitStream } = require('bit-buffer');\nconst debug = require('debug')('font.table.glyf');\n\nconst u "
  },
  {
    "path": "lib/font/table_head.js",
    "chars": 3110,
    "preview": "'use strict';\n\nconst debug = require('debug')('font.table.head');\n\nconst u = require('../utils');\n\nconst O_SIZE = 0;\ncon"
  },
  {
    "path": "lib/font/table_kern.js",
    "chars": 7009,
    "preview": "'use strict';\n\nconst debug = require('debug')('font.table.kern');\n\nconst u = require('../utils');\n\nconst O_SIZE = 0;\ncon"
  },
  {
    "path": "lib/font/table_loca.js",
    "chars": 782,
    "preview": "'use strict';\n\nconst debug = require('debug')('font.table.loca');\n\nconst u = require('../utils');\n\nconst O_SIZE = 0;\ncon"
  },
  {
    "path": "lib/freetype/build/ft_render.js",
    "chars": 571582,
    "preview": "\nvar Module = (() => {\n  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentSc"
  },
  {
    "path": "lib/freetype/index.js",
    "chars": 10183,
    "preview": "'use strict';\n\nconst ft_render_fabric = require('./build/ft_render');\n\nlet m = null;     // Compiled module instance\nlet"
  },
  {
    "path": "lib/freetype/render.c",
    "chars": 5427,
    "preview": "#include <emscripten.h>\n#include <ft2build.h>\n#include FT_FREETYPE_H\n#include FT_TRUETYPE_TABLES_H\n\nstatic void set_js_v"
  },
  {
    "path": "lib/ranger.js",
    "chars": 986,
    "preview": "'use strict';\n\n/**\n * Merge font ranges into a single mapping.\n */\nclass Ranger {\n  constructor() {\n    this.data = {};\n"
  },
  {
    "path": "lib/utils.js",
    "chars": 3226,
    "preview": "'use strict';\n\nfunction set_byte_depth(depth) {\n  return function (byte) {\n    // Calculate significant bits; for depth="
  },
  {
    "path": "lib/writers/bin.js",
    "chars": 361,
    "preview": "// Write font in binary format\n'use strict';\n\nconst AppError = require('../app_error');\nconst Font     = require('../fon"
  },
  {
    "path": "lib/writers/dump.js",
    "chars": 1931,
    "preview": "// Write font data into png images\n\n'use strict';\n\nconst path     = require('path');\nconst { PNG }  = require('pngjs');\n"
  },
  {
    "path": "lib/writers/lvgl/index.js",
    "chars": 361,
    "preview": "// Write font in LVGL format\n'use strict';\n\nconst AppError = require('../../app_error');\nconst Font     = require('./lv_"
  },
  {
    "path": "lib/writers/lvgl/lv_font.js",
    "chars": 3033,
    "preview": "'use strict';\n\nconst path = require('path');\n\nconst Font = require('../../font/font');\nconst Head = require('./lv_table_"
  },
  {
    "path": "lib/writers/lvgl/lv_table_cmap.js",
    "chars": 3251,
    "preview": "'use strict';\n\nconst u = require('../../utils');\nconst build_subtables = require('../../font/cmap_build_subtables');\ncon"
  },
  {
    "path": "lib/writers/lvgl/lv_table_glyf.js",
    "chars": 3162,
    "preview": "'use strict';\n\nconst { BitStream } = require('bit-buffer');\nconst u = require('../../utils');\nconst Glyf = require('../."
  },
  {
    "path": "lib/writers/lvgl/lv_table_head.js",
    "chars": 3308,
    "preview": "'use strict';\n\nconst Head = require('../../font/table_head');\n\nclass LvHead extends Head {\n  constructor(font) {\n    sup"
  },
  {
    "path": "lib/writers/lvgl/lv_table_kern.js",
    "chars": 2678,
    "preview": "'use strict';\n\nconst u = require('../../utils');\nconst Kern = require('../../font/table_kern');\n\nclass LvKern extends Ke"
  },
  {
    "path": "lv_font_conv.js",
    "chars": 299,
    "preview": "#!/usr/bin/env node\n\n'use strict';\n\nconst AppError = require('./lib/app_error');\n\nrequire('./lib/cli').run(process.argv."
  },
  {
    "path": "package.json",
    "chars": 1915,
    "preview": "{\n  \"name\": \"lv_font_conv\",\n  \"version\": \"1.5.3\",\n  \"description\": \"Rasterize vector fonts for embedded use. Supports su"
  },
  {
    "path": "support/Dockerfile",
    "chars": 726,
    "preview": "FROM emscripten/emsdk:3.1.1\n\nRUN wget --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetyp"
  },
  {
    "path": "support/build.sh",
    "chars": 862,
    "preview": "#!/bin/sh\n\nmkdir -p /src/lv_font_conv/lib/freetype/build\n\nemcc --bind \\\n  -o /src/lv_font_conv/lib/freetype/build/ft_ren"
  },
  {
    "path": "support/build_web.js",
    "chars": 483,
    "preview": "#!/usr/bin/env node\n\n'use strict';\n\nconst fs = require('fs');\nconst shell = require('shelljs');\n\nconst OUT_DIR = 'dist';"
  },
  {
    "path": "test/.eslintrc.yml",
    "chars": 19,
    "preview": "env:\n  mocha: true\n"
  },
  {
    "path": "test/font/fixtures/font_info_AV.json",
    "chars": 2476,
    "preview": "{\n  \"ascent\": 9,\n  \"descent\": -2,\n  \"typoAscent\": 8,\n  \"typoDescent\": -2,\n  \"typoLineGap\": 0,\n  \"size\": 10,\n  \"glyphs\": "
  },
  {
    "path": "test/font/fixtures/font_info_AV_size200.json",
    "chars": 488358,
    "preview": "{\n  \"ascent\": 186,\n  \"descent\": -49,\n  \"typoAscent\": 150,\n  \"typoDescent\": -50,\n  \"typoLineGap\": 10,\n  \"size\": 200,\n  \"g"
  },
  {
    "path": "test/font/test_cmap_build_subtables.js",
    "chars": 1975,
    "preview": "'use strict';\n\nconst assert     = require('assert');\nconst cmap_split = require('../../lib/font/cmap_build_subtables');\n"
  },
  {
    "path": "test/font/test_compress.js",
    "chars": 1810,
    "preview": "'use strict';\n\nconst assert = require('assert');\nconst { BitStream } = require('bit-buffer');\n\nconst compress = require("
  },
  {
    "path": "test/font/test_font.js",
    "chars": 9205,
    "preview": "'use strict';\n\nconst assert = require('assert');\nconst Font   = require('../../lib/font/font');\nconst { BitStream } = re"
  },
  {
    "path": "test/test_cli.js",
    "chars": 4102,
    "preview": "'use strict';\n\nconst assert            = require('assert');\nconst { execFileSync }  = require('child_process');\nconst fs"
  },
  {
    "path": "test/test_collect_font_data.js",
    "chars": 4595,
    "preview": "'use strict';\n\nconst assert            = require('assert');\nconst collect_font_data = require('../lib/collect_font_data'"
  },
  {
    "path": "test/test_ranger.js",
    "chars": 1156,
    "preview": "'use strict';\n\nconst assert = require('assert');\nconst Ranger = require('../lib/ranger');\n\ndescribe('Ranger', function ("
  },
  {
    "path": "test/test_utils.js",
    "chars": 2002,
    "preview": "'use strict';\n\nconst assert    = require('assert');\nconst set_depth = require('../lib/utils').set_depth;\n\ndescribe('Util"
  },
  {
    "path": "web/.eslintrc.yml",
    "chars": 57,
    "preview": "env:\n  browser: true\nparserOptions:\n  sourceType: module\n"
  },
  {
    "path": "web/.htmlhintrc",
    "chars": 30,
    "preview": "{\n    \"doctype-first\": false\n}"
  },
  {
    "path": "web/content.html",
    "chars": 10000,
    "preview": "<div class=\"row\" style=\"margin-bottom:48px;\">\n\t<div class=\"col-md-8 col-md-offset-2 text-center\">\n\t\t<h1 style=\"margin-bo"
  },
  {
    "path": "web/convert_browser.js",
    "chars": 467,
    "preview": "const collect_font_data = require('../lib/collect_font_data');\nconst binWriter = require('../lib/writers/bin');\nconst lv"
  },
  {
    "path": "web/index.html",
    "chars": 1759,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-wid"
  },
  {
    "path": "web/index.js",
    "chars": 5494,
    "preview": "const convert = require('./convert_browser');\nconst FileSaver = require('file-saver');\n\n/*eslint-env jquery*/\n\n\nfunction"
  }
]

About this extraction

This page contains the full source code of the lvgl/lv_font_conv GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 58 files (1.2 MB), approximately 521.6k tokens, and a symbol index with 249 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!