Compare commits
82 Commits
main
...
terminal-w
Author | SHA1 | Date | |
---|---|---|---|
675b9d0245 | |||
|
d69cfcfb13 | ||
|
b8c51abe69 | ||
|
2105a7b63d | ||
|
79ee886904 | ||
|
b1d70ae2ed | ||
|
a77a3dcb8b | ||
|
8aefa3b9a6 | ||
|
6c7eb6630e | ||
|
4dd0d60eeb | ||
|
a2ced5659d | ||
|
5ea9c5537e | ||
|
f7c87a700d | ||
|
e247bd7019 | ||
|
29ad09f4ef | ||
|
afeded0126 | ||
|
57b6db8b2a | ||
|
0076962588 | ||
|
e6ee548536 | ||
|
1808634f0e | ||
|
cfaad261dc | ||
|
f1651c8000 | ||
|
8a2ee437f5 | ||
|
06b721a71f | ||
|
771008495e | ||
|
f032847ae1 | ||
|
97ba39988b | ||
|
879bdccd92 | ||
|
8598142c27 | ||
|
a2356f2f4a | ||
|
3db4e012ce | ||
|
a0cd439efc | ||
|
997e4cee8c | ||
|
ad3bf49c7b | ||
|
7ca0418c82 | ||
|
c3d05901a0 | ||
|
b3756e45fa | ||
|
a266202831 | ||
|
c8236afbef | ||
|
5040733a97 | ||
|
fd019c7aad | ||
|
975bfc5420 | ||
|
2625ed39e5 | ||
|
a3dbcd62f6 | ||
|
4fddf93114 | ||
|
83922fb3de | ||
|
95917c65a5 | ||
|
3a0d673df4 | ||
|
53dc9dafe7 | ||
|
a407902b06 | ||
|
3e8accde69 | ||
|
2bb611db8e | ||
|
ef88e8165c | ||
|
da9ab4a7b4 | ||
|
0bcd7e0009 | ||
|
bf69e0dcc5 | ||
|
947c4f5067 | ||
|
0960d67001 | ||
|
5385f7e275 | ||
|
e884b053d3 | ||
|
85a2181b64 | ||
|
3dca742b65 | ||
|
20ac7e8df3 | ||
|
f8f8993fac | ||
|
fdc3b8badb | ||
|
f9a16feeaf | ||
|
4930c0cab7 | ||
|
a449b272f7 | ||
|
9e406c70f9 | ||
|
0c87bc27b2 | ||
|
0dcfb2edb7 | ||
|
06c6935315 | ||
|
47c104643d | ||
|
7b1110187e | ||
|
7e460d3c80 | ||
|
7a9211587a | ||
|
24e6a2f8ab | ||
|
9a7ba405e1 | ||
|
940cd3459f | ||
|
869bec8f88 | ||
|
ee925200c3 | ||
|
079e676baf |
18
.github/workflows/main.yml
vendored
@ -46,20 +46,30 @@ jobs:
|
||||
# Unzip the package because Upload Artifact will zip up the files
|
||||
- name: Unzip DFU package
|
||||
run: unzip ./build/output/pinetime-mcuboot-app-dfu-*.zip -d ./build/output/pinetime-mcuboot-app-dfu
|
||||
- name: Set ref_name, but replace slashes with dashes.
|
||||
shell: bash
|
||||
env:
|
||||
ref_name: ${{ github.head_ref || github.ref_name }}
|
||||
run: echo "REF_NAME=${ref_name//\//-}" >> $GITHUB_ENV
|
||||
- name: Upload DFU artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: InfiniTime DFU ${{ github.head_ref }}
|
||||
name: InfiniTime DFU ${{ env.REF_NAME }}
|
||||
path: ./build/output/pinetime-mcuboot-app-dfu/*
|
||||
- name: Upload MCUBoot image artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: InfiniTime MCUBoot image ${{ github.head_ref }}
|
||||
name: InfiniTime MCUBoot image ${{ env.REF_NAME }}
|
||||
path: ./build/output/pinetime-mcuboot-app-image-*.bin
|
||||
- name: Upload standalone ELF artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: InfiniTime image ${{ env.REF_NAME }}
|
||||
path: ./build/output/src/pinetime-app-*.out
|
||||
- name: Upload resources artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: InfiniTime resources ${{ github.head_ref }}
|
||||
name: InfiniTime resources ${{ env.REF_NAME }}
|
||||
path: ./build/output/infinitime-resources-*.zip
|
||||
|
||||
build-simulator:
|
||||
@ -100,7 +110,7 @@ jobs:
|
||||
- name: Upload simulator executable
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: infinisim-${{ github.head_ref }}
|
||||
name: infinisim-${{ env.REF_NAME }}
|
||||
path: build_lv_sim/infinisim
|
||||
|
||||
get-base-ref-size:
|
||||
|
2
.gitignore
vendored
@ -11,7 +11,7 @@ cmake_install.cmake
|
||||
Makefile
|
||||
build
|
||||
tools
|
||||
node_modules/
|
||||
|
||||
# Resulting binary files
|
||||
*.a
|
||||
*.so
|
||||
|
3
.gitmodules
vendored
@ -4,9 +4,6 @@
|
||||
[submodule "src/libs/littlefs"]
|
||||
path = src/libs/littlefs
|
||||
url = https://github.com/littlefs-project/littlefs.git
|
||||
[submodule "src/libs/QCBOR"]
|
||||
path = src/libs/QCBOR
|
||||
url = https://github.com/laurencelundblade/QCBOR.git
|
||||
[submodule "src/libs/arduinoFFT"]
|
||||
path = src/libs/arduinoFFT
|
||||
url = https://github.com/kosme/arduinoFFT.git
|
||||
|
47
.idea/codeStyles/Project.xml
generated
@ -1,7 +1,54 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C>
|
||||
<option name="INDENT_NAMESPACE_MEMBERS" value="2" />
|
||||
<option name="INDENT_C_STRUCT_MEMBERS" value="2" />
|
||||
<option name="INDENT_CLASS_MEMBERS" value="2" />
|
||||
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" />
|
||||
<option name="INDENT_DIRECTIVE_AS_CODE" value="true" />
|
||||
<option name="SPACE_BEFORE_TEMPLATE_DECLARATION_LT" value="true" />
|
||||
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
||||
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
||||
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||
</Objective-C>
|
||||
<Objective-C-extensions>
|
||||
<rules>
|
||||
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
||||
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
</rules>
|
||||
</Objective-C-extensions>
|
||||
<clangFormatSettings>
|
||||
<option name="ENABLED" value="true" />
|
||||
</clangFormatSettings>
|
||||
<codeStyleSettings language="ObjectiveC">
|
||||
<option name="RIGHT_MARGIN" value="140" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_ON_TYPING" value="1" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="true" />
|
||||
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release")
|
||||
|
||||
project(pinetime VERSION 1.14.0 LANGUAGES C CXX ASM)
|
||||
project(pinetime VERSION 1.15.0 LANGUAGES C CXX ASM)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
39
README.md
@ -1,27 +1,50 @@
|
||||
# [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
|
||||
<div align="center">
|
||||
|
||||
![InfiniTime logo](doc/logo/infinitime-logo-small.jpg "InfiniTime Logo")
|
||||
![Header Image](doc/logo/watchface_collage.png)
|
||||
|
||||
Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devices/pinetime/) with many features, written in modern C++.
|
||||
<br>
|
||||
|
||||
[![GitHub tag](https://img.shields.io/github/tag/InfiniTimeOrg/InfiniTime?include_prereleases=&sort=semver&color=blue)](https://github.com/InfiniTimeOrg/InfiniTime/releases)
|
||||
[![GitHub License](https://img.shields.io/github/license/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniLink/blob/main/LICENSE)
|
||||
[![Issues - InfiniTime](https://img.shields.io/github/issues/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniTime/issues)
|
||||
[![Pull Requests - InfiniTime](https://img.shields.io/github/issues-pr/InfiniTimeOrg/InfiniTime)](https://github.com/InfiniTimeOrg/InfiniTime/pulls)
|
||||
[![Downloads - InfiniTime](https://img.shields.io/github/downloads/InfiniTimeOrg/InfiniTime/total)](https://github.com/InfiniTimeOrg/InfiniTime)
|
||||
[![Stars - InfiniTime](https://img.shields.io/github/stars/InfiniTimeOrg/InfiniTime?style=social)](https://github.com/InfiniTimeOrg/InfiniTime/stargazers)
|
||||
[![Forks - InfiniTime](https://img.shields.io/github/forks/InfiniTimeOrg/InfiniTime?style=social)](https://github.com/InfiniTimeOrg/InfiniTime/network/members)
|
||||
|
||||
# InfiniTime
|
||||
|
||||
*Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devices/pinetime/) with many features, written in modern C++.*
|
||||
|
||||
<br>
|
||||
|
||||
</div>
|
||||
|
||||
## New to InfiniTime?
|
||||
|
||||
- [Getting started with InfiniTime](doc/gettingStarted/gettingStarted-1.0.md)
|
||||
- [Updating the software](doc/gettingStarted/updating-software.md)
|
||||
- [About the firmware and bootloader](doc/gettingStarted/about-software.md)
|
||||
- [PineTimeStyle Watch face](https://wiki.pine64.org/wiki/PineTimeStyle)
|
||||
- [Weather integration](https://wiki.pine64.org/wiki/Infinitime-Weather)
|
||||
- [Available apps](doc/gettingStarted/Applications.md)
|
||||
- [Available watch faces](/doc/gettingStarted/Watchfaces.md)
|
||||
- [PineTimeStyle Watch face](https://pine64.org/documentation/PineTime/Watchfaces/PineTimeStyle)
|
||||
- [Weather integration](https://pine64.org/documentation/PineTime/Software/InfiniTime_weather/)
|
||||
|
||||
### Companion apps
|
||||
|
||||
- [Gadgetbridge](https://gadgetbridge.org/) (Android)
|
||||
- [AmazFish](https://openrepos.net/content/piggz/amazfish/) (SailfishOS)
|
||||
- [Amazfish](https://github.com/piggz/harbour-amazfish/) ([SailfishOS](https://sailfishos-chum.github.io/apps/harbour-amazfish/), [Ubuntu Touch](https://open-store.io/app/uk.co.piggz.amazfish), [Flatpak](https://flathub.org/apps/uk.co.piggz.amazfish))
|
||||
- [Siglo](https://github.com/alexr4535/siglo) (Linux)
|
||||
- [InfiniLink](https://github.com/InfiniTimeOrg/InfiniLink) (iOS)
|
||||
- [ITD](https://gitea.elara.ws/Elara6331/itd) (Linux)
|
||||
- [WatchMate](https://github.com/azymohliad/watchmate) (Linux)
|
||||
- [InfiniTimeExplorer](https://infinitimeexplorer.netlify.app) (Web)
|
||||
|
||||
***Note**: We removed mentions to NRFConnect as this app is closed source and recent versions do not work anymore with InfiniTime (the last version known to work is 4.24.3). If you used NRFConnect in the past, we recommend you switch to [Gadgetbridge](https://gadgetbridge.org/).*
|
||||
<br>
|
||||
|
||||
> *InfiniTimeExplorer is only compatible with web browsers that support Web BLE. Current fully supported browsers include Chrome and Microsoft Edge.*
|
||||
>
|
||||
> *We removed mentions to NRFConnect as this app is closed source and recent versions do not work anymore with InfiniTime (the last version known to work is 4.24.3). If you used NRFConnect in the past, we recommend you switch to [Gadgetbridge](https://gadgetbridge.org/).*
|
||||
|
||||
## Development
|
||||
|
||||
@ -35,7 +58,7 @@ Fast open-source firmware for the [PineTime smartwatch](https://pine64.org/devic
|
||||
|
||||
### Contributing
|
||||
|
||||
- [How to contribute?](CONTRIBUTING.md)
|
||||
- [How to contribute](CONTRIBUTING.md)
|
||||
- [Coding conventions](doc/coding-convention.md)
|
||||
|
||||
### Build, flash and debug
|
||||
|
99
doc/gettingStarted/Applications.md
Normal file
@ -0,0 +1,99 @@
|
||||
# Applications
|
||||
|
||||
InfiniTime has 13 apps on the `main` branch at the time of writing.
|
||||
|
||||
## List of apps
|
||||
- Stopwatch
|
||||
- Alarm
|
||||
- Timer
|
||||
- Steps
|
||||
- Heartrate
|
||||
- Music
|
||||
- InfiniPaint
|
||||
- Paddle
|
||||
- 2
|
||||
- InfiniDice
|
||||
- Metronome
|
||||
- Maps
|
||||
- Weather
|
||||
|
||||
### Stopwatch
|
||||
![Stopwatch UI](/doc/gettingStarted/AppsScreenshots/stopwatch.png)
|
||||
- Press the Start button (bottom right) to start or stop the timer.
|
||||
- You can also press the side button while the timer is running to pause the timer.
|
||||
- Press the Flag button (bottom left) to add a lap.
|
||||
- The stopwatch will not yet continue counting time while the app is closed.
|
||||
|
||||
### Alarm
|
||||
![Alarm UI](/doc/gettingStarted/AppsScreenshots/alarm.png)
|
||||
- Ajust the time with the time picker.
|
||||
- Press the Info button in the top middle to see time remaning.
|
||||
- Use the toggle in the bottom left to turn the alarm on/off.
|
||||
- Use the button in the bottom right to change the alarm frequency.
|
||||
- You can choose between once, daily, or Monday - Friday.
|
||||
|
||||
### Timer
|
||||
![Timer UI](/doc/gettingStarted/AppsScreenshots/timer.png)
|
||||
- Ajust how long the timer should go for with the time picker.
|
||||
- Press the Start button at the bottom to start/stop the timer.
|
||||
|
||||
### Steps
|
||||
![Steps UI](/doc/gettingStarted/AppsScreenshots/steps.png)
|
||||
- The total count of steps for the current display will show in the middle of the screen.
|
||||
- The Reset button in the bottom middle resets the Trip counter. (Total of all steps taken.)
|
||||
- The progress circle shows the percentage of your daily goal completed.
|
||||
|
||||
### Heartrate
|
||||
![Heartrate UI](/doc/gettingStarted/AppsScreenshots/Heartrate.png)
|
||||
- Press Start to start measuring your heartrate.
|
||||
- It may take a bit to get the first measurement.
|
||||
|
||||
### Music
|
||||
![Music UI](/doc/gettingStarted/AppsScreenshots/Music.png)
|
||||
- This app shows currently playing music.
|
||||
- Please note that this app is not very useful without a device connected.
|
||||
- Press the button in the center to play/pause, and the buttons on the left and right to go to the previous and next tracks, respectively.
|
||||
- Swipe up to get to volume controls.
|
||||
|
||||
### InfiniPaint
|
||||
![InfiniPaint UI](/doc/gettingStarted/AppsScreenshots/Paint.png)
|
||||
- This app does not allow you to swipe from the top to exit, use the side button instead.
|
||||
- Draw on the screen to add lines.
|
||||
- Hold down in one spot to change paint colors.
|
||||
|
||||
### Paddle
|
||||
![Paddle UI](/doc/gettingStarted/AppsScreenshots/Pong.png)
|
||||
- This app does not allow you to swipe from the top to exit, use the side button instead.
|
||||
- Drag your finger to move the paddle.
|
||||
- Goal: Don't let the ball go off the left side of the screen.
|
||||
|
||||
### 2
|
||||
![2 UI](/doc/gettingStarted/AppsScreenshots/2048.png)
|
||||
- This app does not allow you to swipe from the top to exit, use the side button instead.
|
||||
- Play a game of 2048.
|
||||
- Swipe up, down, left, or right tomove the tiles.
|
||||
- When two tiles with the same number run into each other, they will add together.
|
||||
- Goal: Don't let the screen fill up with tiles, and get to the 2048 tile to win.
|
||||
|
||||
### InfiniDice
|
||||
![InfiniDice UI](/doc/gettingStarted/AppsScreenshots/Dice.png)
|
||||
- Ajust the count to change the number of dice.
|
||||
- Ajust the sides to change the number of sides.
|
||||
- Press the button at the bottom to roll.
|
||||
- The result will be on the right side of the screen.
|
||||
|
||||
### Metronome
|
||||
![Metronome UI](/doc/gettingStarted/AppsScreenshots/Metronome.png)
|
||||
- Ajust the BPM with the circular slider.
|
||||
- A bug currently makes it always snap to 98 BPM.
|
||||
- Use the button in the bottom left to start the metronome.
|
||||
|
||||
### Maps
|
||||
![Maps UI](/doc/gettingStarted/AppsScreenshots/Maps.png)
|
||||
- This app shows info from a navigation app.
|
||||
- Please note that this app is not very useful without a device connected.
|
||||
|
||||
### Weather
|
||||
![Weather UI](/doc/gettingStarted/AppsScreenshots/Weather.png)
|
||||
- This app shows weather info.
|
||||
- Please note that this app is not very useful without a device connected.
|
BIN
doc/gettingStarted/AppsScreenshots/2048.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Dice.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Heartrate.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Maps.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Metronome.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Music.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Paint.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Pong.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
doc/gettingStarted/AppsScreenshots/Weather.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
doc/gettingStarted/AppsScreenshots/alarm.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
doc/gettingStarted/AppsScreenshots/steps.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
doc/gettingStarted/AppsScreenshots/stopwatch.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
doc/gettingStarted/AppsScreenshots/timer.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
31
doc/gettingStarted/Watchfaces.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Watchfaces
|
||||
|
||||
InfiniTime has 6 apps on the `main` branch at the time of writing.
|
||||
|
||||
## List of apps
|
||||
- Digital
|
||||
- Analog
|
||||
- PineTimeStyle
|
||||
- Terminal
|
||||
- Infinineat
|
||||
- Casio G7710
|
||||
|
||||
### Digital
|
||||
![Digital face](/doc/gettingStarted/Watchfaces/Digital.png)
|
||||
|
||||
### Analog
|
||||
![Analog face](/doc/gettingStarted/Watchfaces/Analog.png)
|
||||
|
||||
### PineTimeStyle
|
||||
![PineTimeStyle face](/doc/gettingStarted/Watchfaces/PineTimeStyle.png)
|
||||
- You can long-press on the display to change colors, step style, and weather.
|
||||
|
||||
### Terminal
|
||||
![Terminal face](/doc/gettingStarted/Watchfaces/Terminal.png)
|
||||
|
||||
### Infinineat
|
||||
![Infinineat face](/doc/gettingStarted/Watchfaces/Infinineat.png)
|
||||
- You can long-press on the display to change colors.
|
||||
|
||||
### Casio G7710
|
||||
![Casio G7710 face](/doc/gettingStarted/Watchfaces/CasioG7710.png)
|
BIN
doc/gettingStarted/Watchfaces/Analog.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
doc/gettingStarted/Watchfaces/CasioG7710.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
doc/gettingStarted/Watchfaces/Digital.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
doc/gettingStarted/Watchfaces/Infinineat.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
doc/gettingStarted/Watchfaces/PineTimeStyle.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
doc/gettingStarted/Watchfaces/Terminal.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 256 KiB |
@ -14,7 +14,7 @@ You can sync the time using companion apps.
|
||||
|
||||
- Gadgetbridge automatically synchronizes the time when you connect it to your watch. More information on Gadgetbridge [here](/doc/gettingStarted/ota-gadgetbridge.md)
|
||||
- [Sync the time with NRFConnect](/doc/gettingStarted/time-nrfconnect.md)
|
||||
- Sync the time with your browser https://hubmartin.github.io/WebBLEWatch/
|
||||
- [Sync the time with your browser](https://hubmartin.github.io/WebBLEWatch/)
|
||||
|
||||
You can also set the time in the settings without a companion app. (version >1.7.0)
|
||||
|
||||
@ -46,7 +46,7 @@ On the bottom right, you can see how many steps you have taken today.
|
||||
![Settings](ui/settings.jpg)
|
||||
|
||||
- Swipe **up** to display the application menus. Apps (stopwatch, music, step, games,...) can be started from this menu.
|
||||
- Swipe **down** to display the notification panel. Notification sent by your companion app will be displayed here.
|
||||
- Swipe **down** to display the notification panel. Notifications sent by your companion app will be displayed here.
|
||||
- Swipe **right** to display the Quick Actions menu. This menu allows you to
|
||||
- Set the brightness of the display
|
||||
- Start the **flashlight** app
|
||||
|
@ -1,29 +1,35 @@
|
||||
# Connecting to Gadgetbridge
|
||||
|
||||
Launch Gadgetbridge and tap on the **"+"** button on the bottom right to add a new device:
|
||||
Launch Gadgetbridge and tap on the menu button in the top left:
|
||||
|
||||
![Gadgetbridge 0](gadgetbridge0.jpg)
|
||||
|
||||
Wait for the scan to complete, your PineTime should be detected:
|
||||
Press the "Connect new device" button:
|
||||
|
||||
![Gadgetbridge 1](gadgetbridge1.jpg)
|
||||
|
||||
Your PineTime should appear on the list. Tap on it.
|
||||
|
||||
Tap on it. Gadgdetbridge will pair and connect to your device:
|
||||
|
||||
![Gadgetbridge 2](gadgetbridge2.jpg)
|
||||
|
||||
# Updating with Gadgetbridge
|
||||
|
||||
Now that Gadgetbridge is connected to your PineTime, use a file browser application and find the DFU file (`pinetime-mcuboot-app-dfu-x.x.x.zip`) you downloaded previously. Tap on it and open it using the Gadgetbridge application/firmware installer:
|
||||
Now that Gadgetbridge is connected to your PineTime, press the three dots on the device card:
|
||||
|
||||
![Gadgetbridge 3](gadgetbridge3.jpg)
|
||||
|
||||
Read the warning carefully and tap **Install**:
|
||||
Now press the "File Installer" button:
|
||||
|
||||
![Gadgetbridge 4](gadgetbridge4.jpg)
|
||||
|
||||
Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime!
|
||||
|
||||
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used.
|
||||
Select the firmware you downloaded (`pinetime-mcuboot-app-dfu-x.x.x.zip`) from the [Releases tab](https://github.com/InfiniTimeOrg/InfiniTime/releases/latest):
|
||||
|
||||
![Gadgetbridge 5](gadgetbridge5.jpg)
|
||||
|
||||
Wait for the transfer to finish. There will be a progress bar on both the watch and the phone. Your PineTime should reboot with the new version of InfiniTime!
|
||||
|
||||
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and scroll to the Firmware option and click **validate**. Otherwise, after reboot the previous firmware will be used.
|
||||
|
||||
![Validate](validate.png)
|
||||
|
@ -6,7 +6,7 @@ If you just want to flash or upgrade InfiniTime on your PineTime, this page is f
|
||||
|
||||
You can check the InfiniTime version by first swiping right on the watch face to open quick settings, tapping the cogwheel to open settings, swipe up until you find an entry named "About" and tap on it.
|
||||
|
||||
![InfiniTime 1.0 version](version-1.0.jpg)
|
||||
![InfiniTime 1.14 version](version.png)
|
||||
|
||||
PineTimes shipped after June 2021 will ship with the latest version of [the bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader/releases/tag/1.0.0) and [recovery firmware](https://github.com/InfiniTimeOrg/InfiniTime/releases/tag/0.14.1)
|
||||
|
||||
@ -49,7 +49,7 @@ Since those resources are not part of the firmware, they need to be flashed and
|
||||
Resources are packaged into a single .zip file named `infinitime-resources-x.y.z.zip` (where `x`, `y` and `z` are the version numbers of InfiniTime).
|
||||
You can use the companion app of your choice to flash the resources.
|
||||
|
||||
**Note : at the time of writing this page, [Amazfish](https://github.com/piggz/harbour-amazfish) and [ITD](https://gitea.arsenm.dev/Arsen6331/itd) have already integrated this functionality. Other companion apps will hopefully implement it soon!*
|
||||
**Note: at the time of writing this page, [Amazfish](https://github.com/piggz/harbour-amazfish) and [ITD](https://gitea.arsenm.dev/Arsen6331/itd) have already integrated this functionality. Other companion apps will hopefully implement it soon!*
|
||||
|
||||
## Amazfish
|
||||
Use the `Download file` functionality of Amazfish.
|
||||
|
BIN
doc/gettingStarted/validate.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
doc/gettingStarted/version.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
doc/logo/watchface_collage.png
Normal file
After Width: | Height: | Size: 846 KiB |
@ -65,5 +65,8 @@ RUN bash -c "source /opt/build.sh; GetMcuBoot;"
|
||||
# Add the infinitime user for connecting devcontainer
|
||||
RUN adduser infinitime
|
||||
|
||||
# Configure Git to accept the /sources directory as safe
|
||||
RUN git config --global --add safe.directory /sources
|
||||
|
||||
ENV SOURCES_DIR /sources
|
||||
CMD ["/opt/build.sh"]
|
||||
|
113
node_modules/.package-lock.json
generated
vendored
@ -1,113 +0,0 @@
|
||||
{
|
||||
"name": "InfiniTime",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/lv_font_conv": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/lv_font_conv/-/lv_font_conv-1.5.2.tgz",
|
||||
"integrity": "sha512-0UapRSTkVP/pnB8Z4r2HDHx5p2dJx/xUG1+14u/WXo59mwuC7BahR+Bnx/66jKoDrG1wFQwn9ZzoyMxRHOD9bg==",
|
||||
"bundleDependencies": [
|
||||
"argparse",
|
||||
"bit-buffer",
|
||||
"debug",
|
||||
"make-error",
|
||||
"mkdirp",
|
||||
"opentype.js",
|
||||
"pngjs"
|
||||
],
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.0",
|
||||
"bit-buffer": "^0.2.5",
|
||||
"debug": "^4.1.1",
|
||||
"make-error": "^1.3.5",
|
||||
"mkdirp": "^1.0.4",
|
||||
"opentype.js": "^1.1.0",
|
||||
"pngjs": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"lv_font_conv": "lv_font_conv.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"inBundle": true,
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/bit-buffer": {
|
||||
"version": "0.2.5",
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/debug": {
|
||||
"version": "4.3.1",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"inBundle": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/opentype.js": {
|
||||
"version": "1.3.3",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"string.prototype.codepointat": "^0.2.1",
|
||||
"tiny-inflate": "^1.0.3"
|
||||
},
|
||||
"bin": {
|
||||
"ot": "bin/ot"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/pngjs": {
|
||||
"version": "6.0.0",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/string.prototype.codepointat": {
|
||||
"version": "0.2.1",
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lv_font_conv/node_modules/tiny-inflate": {
|
||||
"version": "1.0.3",
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
164
node_modules/lv_font_conv/CHANGELOG.md
generated
vendored
@ -1,164 +0,0 @@
|
||||
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.
|
22
node_modules/lv_font_conv/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
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.
|
150
node_modules/lv_font_conv/README.md
generated
vendored
@ -1,150 +0,0 @@
|
||||
lv_font_conv - font convertor to compact bitmap format
|
||||
======================================================
|
||||
|
||||
[![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)
|
||||
|
||||
Converts TTF/WOFF/OTF fonts to __[compact format](https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md)__, suitable for small embedded systems. Main features are:
|
||||
|
||||
- Allows bitonal and anti-aliased glyphs (1-4 bits per pixel).
|
||||
- Preserves kerning info.
|
||||
- Compression.
|
||||
- Users can select required glyphs only (subsetting).
|
||||
- Multiple font sources can be merged.
|
||||
- Simple CLI interface, easy to integrate into external build systems.
|
||||
|
||||
|
||||
## Install the script
|
||||
|
||||
[node.js](https://nodejs.org/en/download/) v10+ required.
|
||||
|
||||
Global install of the last version, execute as "lv_font_conv"
|
||||
|
||||
```sh
|
||||
# install release from npm registry
|
||||
npm i lv_font_conv -g
|
||||
# install from github's repo, master branch
|
||||
npm i lvgl/lv_font_conv -g
|
||||
```
|
||||
|
||||
**run via [npx](https://www.npmjs.com/package/npx) without install**
|
||||
|
||||
```sh
|
||||
# run from npm registry
|
||||
npx lv_font_conv -h
|
||||
# run from github master
|
||||
npx github:lvgl/lv_font_conv -h
|
||||
```
|
||||
|
||||
Note, runing via `npx` may take some time until modules installed, be patient.
|
||||
|
||||
|
||||
## CLI params
|
||||
|
||||
Common:
|
||||
|
||||
- `--bpp` - bits per pixel (antialiasing).
|
||||
- `--size` - output font size (pixels).
|
||||
- `-o`, `--output` - output path (file or directory, depends on format).
|
||||
- `--format` - output format.
|
||||
- `--format dump` - dump glyph images and font info, useful for debug.
|
||||
- `--format bin` - dump font in binary form (as described in [spec](https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md)).
|
||||
- `--format lvgl` - dump font in [LittlevGL](https://github.com/lvgl/lvgl) format.
|
||||
- `--force-fast-kern-format` - always use more fast kering storage format,
|
||||
at cost of some size. If size difference appears, it will be displayed.
|
||||
- `--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 info from font to create
|
||||
grayscale icons. Since gray tones are emulated via transparency, result
|
||||
will be good on contrast background only.
|
||||
- `--lv-include` - only with `--format lvgl`, set alternate path for `lvgl.h`.
|
||||
|
||||
Per font:
|
||||
|
||||
- `--font` - path to font file (ttf/woff/woff2/otf). May be used multiple time for
|
||||
merge.
|
||||
- `-r`, `--range` - single glyph or range + optional mapping, belongs to
|
||||
previously declared `--font`. Can be used multiple times. Examples:
|
||||
- `-r 0x1F450` - single value, dec or hex format.
|
||||
- `-r 0x1F450-0x1F470` - range.
|
||||
- `-r '0x1F450=>0xF005'` - single glyph with mapping.
|
||||
- `-r '0x1F450-0x1F470=>0xF005'` - range with mapping.
|
||||
- `-r 0x1F450 -r 0x1F451-0x1F470` - 2 ranges.
|
||||
- `-r 0x1F450,0x1F451-0x1F470` - the same as above, but defined with single `-r`.
|
||||
- `--symbols` - list of characters to copy (instead of numeric format in `-r`).
|
||||
- `--symbols 0123456789.,` - extract chars to display numbers.
|
||||
- `--autohint-off` - do not force autohinting ("light" is on by default).
|
||||
- `--autohint-strong` - use more strong autohinting (will break kerning).
|
||||
|
||||
Additional debug options:
|
||||
|
||||
- `--no-compress` - disable built-in RLE compression.
|
||||
- `--no-prefilter` - disable bitmap lines filter (XOR), used to improve
|
||||
compression ratio.
|
||||
- `--no-kerning` - drop kerning info to reduce size (not recommended).
|
||||
- `--full-info` - don't shorten 'font_info.json' (include pixels 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 & 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**. Option `--no-compress` exists 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** - format for LittlevGL, C file. Has minor limitations and a bit
|
||||
bigger size, because C does not allow to effectively define relative offsets
|
||||
in data blocks.
|
||||
3. **dump** - create folder with each glyph in separate image, and other font
|
||||
data as `json`. Useful for debug.
|
||||
|
||||
### Merged font metrics
|
||||
|
||||
When multiple fonts merged into one, sources can have different metrics. Result
|
||||
will follow principles below:
|
||||
|
||||
1. No scaling. Glyphs will have exactly the same size, as intended by font authors.
|
||||
2. The same baseline.
|
||||
3. `OS/2` metrics (`sTypoAscender`, `sTypoDescender`, `sTypoLineGap`) will be
|
||||
used from the first font in list.
|
||||
4. `hhea` metrics (`ascender`, `descender`), defined as max/min point of all
|
||||
font glyphs, are recalculated, according to new glyphs set.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Current package includes WebAssembly build of FreeType with some helper
|
||||
functions. Everything is wrapped into Docker and requires zero knowledge about
|
||||
additional tools install. See `package.json` for additional commands. You may
|
||||
need those if decide to upgrade FreeType or update helpers.
|
||||
|
||||
This builds image with emscripten & freetype, usually should be done only once:
|
||||
|
||||
```
|
||||
npm run build:dockerimage
|
||||
```
|
||||
|
||||
This compiles helpers and creates WebAssembly files:
|
||||
|
||||
```
|
||||
npm run build:freetype
|
||||
```
|
9
node_modules/lv_font_conv/lib/app_error.js
generated
vendored
@ -1,9 +0,0 @@
|
||||
// Custom Error type to simplify error messaging
|
||||
//
|
||||
'use strict';
|
||||
|
||||
|
||||
//const ExtendableError = require('es6-error');
|
||||
//module.exports = class AppError extends ExtendableError {};
|
||||
|
||||
module.exports = require('make-error')('AppError');
|
318
node_modules/lv_font_conv/lib/cli.js
generated
vendored
@ -1,318 +0,0 @@
|
||||
// Parse input arguments and execute convertor
|
||||
|
||||
'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;
|
||||
// need to merge them into one array here 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 range
|
||||
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('--lv-include', {
|
||||
metavar: '<path>',
|
||||
help: 'Set alternate "lvgl.h" path (for --format lvgl).'
|
||||
});
|
||||
|
||||
parser.add_argument('--full-info', {
|
||||
dest: 'full_info',
|
||||
action: 'store_true',
|
||||
default: false,
|
||||
help: 'Don\'t shorten "font_info.json" (include pixels data).'
|
||||
});
|
||||
|
||||
//
|
||||
// Process CLI options
|
||||
//
|
||||
|
||||
let args = parser.parse_args(argv.length ? argv : [ '-h' ]);
|
||||
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
173
node_modules/lv_font_conv/lib/collect_font_data.js
generated
vendored
@ -1,173 +0,0 @@
|
||||
// Read fonts
|
||||
|
||||
'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 k/v for quick access
|
||||
let fonts_options = {};
|
||||
args.font.forEach(f => { fonts_options[f.source_path] = f; });
|
||||
|
||||
// read fonts
|
||||
let fonts_opentype = {};
|
||||
let fonts_freetype = {};
|
||||
|
||||
for (let { source_path, source_bin } of args.font) {
|
||||
// don't load font again if it's specified 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
|
||||
let 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}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mapping = ranger.get();
|
||||
let glyphs = [];
|
||||
let 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) {
|
||||
// can't merge kerning values from 2 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let first_font = fonts_freetype[args.font[0].source_path];
|
||||
let first_font_scale = args.size / first_font.units_per_em;
|
||||
let os2_metrics = ft_render.fontface_os2_table(first_font);
|
||||
let 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),
|
||||
size: args.size,
|
||||
glyphs,
|
||||
underlinePosition: Math.round(post_table.underlinePosition * first_font_scale),
|
||||
underlineThickness: Math.round(post_table.underlineThickness * first_font_scale)
|
||||
};
|
||||
};
|
30
node_modules/lv_font_conv/lib/convert.js
generated
vendored
@ -1,30 +0,0 @@
|
||||
// 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');
|
||||
|
||||
let 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
|
||||
//
|
||||
module.exports = async function convert(args) {
|
||||
let font_data = await collect_font_data(args);
|
||||
let files = writers[args.format](args, font_data);
|
||||
|
||||
return files;
|
||||
};
|
||||
|
||||
module.exports.formats = Object.keys(writers);
|
105
node_modules/lv_font_conv/lib/font/cmap_build_subtables.js
generated
vendored
@ -1,105 +0,0 @@
|
||||
// Find an optimal configuration of cmap tables representing set of codepoints,
|
||||
// using simple breadth-first algorithm
|
||||
//
|
||||
// Assume that:
|
||||
// - codepoints have one-to-one correspondence to glyph ids
|
||||
// - glyph ids are always bigger for bigger codepoints
|
||||
// - glyph ids are always consecutive (1..N without gaps)
|
||||
//
|
||||
// This way we can omit glyph ids from all calculations entirely: if codepoints
|
||||
// fit in format0, then glyph ids also will.
|
||||
//
|
||||
// format6 is not considered, because 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 as long as glyph ids are consecutive,
|
||||
// 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);
|
||||
|
||||
let 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;
|
||||
}
|
||||
|
||||
let 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;
|
||||
};
|
107
node_modules/lv_font_conv/lib/font/compress.js
generated
vendored
@ -1,107 +0,0 @@
|
||||
'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 algorythm (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 dencity 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}`);
|
||||
};
|
131
node_modules/lv_font_conv/lib/font/font.js
generated
vendored
@ -1,131 +0,0 @@
|
||||
// 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, don't check dupes
|
||||
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;
|
201
node_modules/lv_font_conv/lib/font/table_cmap.js
generated
vendored
@ -1,201 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const build_subtables = require('./cmap_build_subtables');
|
||||
const u = require('../utils');
|
||||
const debug = require('debug')('font.table.cmap');
|
||||
|
||||
|
||||
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) {
|
||||
let 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) {
|
||||
for (let g of this.font.src.glyphs) {
|
||||
if (g.code === code) return g;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
collect_format0_data(min_code, max_code, start_glyph_id) {
|
||||
let 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) {
|
||||
let codepoints_list = [];
|
||||
let ids_list = [];
|
||||
|
||||
for (let code of codepoints) {
|
||||
let g = this.glyphByCode(code);
|
||||
let 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;
|
147
node_modules/lv_font_conv/lib/font/table_glyf.js
generated
vendored
@ -1,147 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const u = require('../utils');
|
||||
const { BitStream } = require('bit-buffer');
|
||||
const debug = require('debug')('font.table.glyf');
|
||||
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))));
|
||||
}
|
||||
|
||||
// Returns "binary stream" (Buffer) of compiled glyph data
|
||||
compileGlyph(glyph) {
|
||||
// Allocate memory, enough for eny storage formats
|
||||
const buf = Buffer.alloc(100 + glyph.bbox.width * glyph.bbox.height * 4);
|
||||
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
|
||||
const result = Buffer.alloc(bs.byteIndex);
|
||||
buf.copy(result, 0, 0, bs.byteIndex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
storePixels(bitStream, pixels) {
|
||||
if (this.getCompressionCode() === 0) this.storePixelsRaw(bitStream, pixels);
|
||||
else this.storePixelsCompressed(bitStream, pixels);
|
||||
}
|
||||
|
||||
storePixelsRaw(bitStream, pixels) {
|
||||
const bpp = this.font.opts.bpp;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
99
node_modules/lv_font_conv/lib/font/table_head.js
generated
vendored
@ -1,99 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const u = require('../utils');
|
||||
const debug = require('debug')('font.table.head');
|
||||
|
||||
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_POSITION);
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = Head;
|
256
node_modules/lv_font_conv/lib/font/table_kern.js
generated
vendored
@ -1,256 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const u = require('../utils');
|
||||
const debug = require('debug')('font.table.kern');
|
||||
|
||||
|
||||
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 left char (already there),
|
||||
// right kernings are kerning values based on 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;
|
42
node_modules/lv_font_conv/lib/font/table_loca.js
generated
vendored
@ -1,42 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const u = require('../utils');
|
||||
const debug = require('debug')('font.table.loca');
|
||||
|
||||
|
||||
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;
|
317
node_modules/lv_font_conv/lib/freetype/index.js
generated
vendored
@ -1,317 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const ft_render_fabric = require('./build/ft_render');
|
||||
|
||||
let m = null; // compiled module instance
|
||||
let library = 0; // pointer to library struct in wasm memory
|
||||
|
||||
|
||||
// workaround because of bug in emscripten:
|
||||
// https://github.com/emscripten-core/emscripten/issues/5820
|
||||
const runtime_initialized = new Promise(resolve => {
|
||||
ft_render_fabric().then(module_instance => {
|
||||
m = module_instance;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
function from_16_16(fixed_point) {
|
||||
return fixed_point / (1 << 16);
|
||||
}
|
||||
|
||||
function from_26_6(fixed_point) {
|
||||
return fixed_point / (1 << 6);
|
||||
}
|
||||
|
||||
function int8_to_uint8(value) {
|
||||
return value >= 0 ? value : value + 0x100;
|
||||
}
|
||||
|
||||
let FT_New_Memory_Face,
|
||||
FT_Set_Char_Size,
|
||||
FT_Set_Pixel_Sizes,
|
||||
FT_Get_Char_Index,
|
||||
FT_Load_Glyph,
|
||||
FT_Get_Sfnt_Table,
|
||||
FT_Get_Kerning,
|
||||
FT_Done_Face;
|
||||
|
||||
module.exports.init = async function () {
|
||||
await runtime_initialized;
|
||||
m._init_constants();
|
||||
|
||||
FT_New_Memory_Face = module.exports.FT_New_Memory_Face =
|
||||
m.cwrap('FT_New_Memory_Face', 'number', [ 'number', 'number', 'number', 'number', 'number' ]);
|
||||
|
||||
FT_Set_Char_Size = module.exports.FT_Set_Char_Size =
|
||||
m.cwrap('FT_Set_Char_Size', 'number', [ 'number', 'number', 'number', 'number', 'number' ]);
|
||||
|
||||
FT_Set_Pixel_Sizes = module.exports.FT_Set_Pixel_Sizes =
|
||||
m.cwrap('FT_Set_Pixel_Sizes', 'number', [ 'number', 'number', 'number' ]);
|
||||
|
||||
FT_Get_Char_Index = module.exports.FT_Get_Char_Index =
|
||||
m.cwrap('FT_Get_Char_Index', 'number', [ 'number', 'number' ]);
|
||||
|
||||
FT_Load_Glyph = module.exports.FT_Load_Glyph =
|
||||
m.cwrap('FT_Load_Glyph', 'number', [ 'number', 'number', 'number' ]);
|
||||
|
||||
FT_Get_Sfnt_Table = module.exports.FT_Get_Sfnt_Table =
|
||||
m.cwrap('FT_Get_Sfnt_Table', 'number', [ 'number', 'number' ]);
|
||||
|
||||
FT_Get_Kerning = module.exports.FT_Get_Kerning =
|
||||
m.cwrap('FT_Get_Kerning', 'number', [ 'number', 'number', 'number', 'number', 'number' ]);
|
||||
|
||||
FT_Done_Face = module.exports.FT_Done_Face =
|
||||
m.cwrap('FT_Done_Face', 'number', [ 'number' ]);
|
||||
|
||||
if (!library) {
|
||||
let ptr = m._malloc(4);
|
||||
|
||||
try {
|
||||
let error = m.ccall('FT_Init_FreeType', 'number', [ 'number' ], [ ptr ]);
|
||||
|
||||
if (error) throw new Error(`error in FT_Init_FreeType: ${error}`);
|
||||
|
||||
library = m.getValue(ptr, 'i32');
|
||||
} finally {
|
||||
m._free(ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports.fontface_create = function (source, size) {
|
||||
let error;
|
||||
let face = {
|
||||
ptr: 0,
|
||||
font: m._malloc(source.length)
|
||||
};
|
||||
|
||||
m.writeArrayToMemory(source, face.font);
|
||||
|
||||
let ptr = m._malloc(4);
|
||||
|
||||
try {
|
||||
error = FT_New_Memory_Face(library, face.font, source.length, 0, ptr);
|
||||
|
||||
if (error) throw new Error(`error in FT_New_Memory_Face: ${error}`);
|
||||
|
||||
face.ptr = m.getValue(ptr, 'i32');
|
||||
} finally {
|
||||
m._free(ptr);
|
||||
}
|
||||
|
||||
error = FT_Set_Char_Size(face.ptr, 0, size * 64, 300, 300);
|
||||
|
||||
if (error) throw new Error(`error in FT_Set_Char_Size: ${error}`);
|
||||
|
||||
error = FT_Set_Pixel_Sizes(face.ptr, 0, size);
|
||||
|
||||
if (error) throw new Error(`error in FT_Set_Pixel_Sizes: ${error}`);
|
||||
|
||||
let units_per_em = m.getValue(face.ptr + m.OFFSET_FACE_UNITS_PER_EM, 'i16');
|
||||
let ascender = m.getValue(face.ptr + m.OFFSET_FACE_ASCENDER, 'i16');
|
||||
let descender = m.getValue(face.ptr + m.OFFSET_FACE_DESCENDER, 'i16');
|
||||
let height = m.getValue(face.ptr + m.OFFSET_FACE_HEIGHT, 'i16');
|
||||
|
||||
return Object.assign(face, {
|
||||
units_per_em,
|
||||
ascender,
|
||||
descender,
|
||||
height
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
module.exports.fontface_os2_table = function (face) {
|
||||
let sfnt_ptr = FT_Get_Sfnt_Table(face.ptr, m.FT_SFNT_OS2);
|
||||
|
||||
if (!sfnt_ptr) throw new Error('os/2 table not found for this font');
|
||||
|
||||
let typoAscent = m.getValue(sfnt_ptr + m.OFFSET_TT_OS2_ASCENDER, 'i16');
|
||||
let typoDescent = m.getValue(sfnt_ptr + m.OFFSET_TT_OS2_DESCENDER, 'i16');
|
||||
let typoLineGap = m.getValue(sfnt_ptr + m.OFFSET_TT_OS2_LINEGAP, 'i16');
|
||||
|
||||
return {
|
||||
typoAscent,
|
||||
typoDescent,
|
||||
typoLineGap
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.get_kerning = function (face, code1, code2) {
|
||||
let glyph1 = FT_Get_Char_Index(face.ptr, code1);
|
||||
let glyph2 = FT_Get_Char_Index(face.ptr, code2);
|
||||
let ptr = m._malloc(4 * 2);
|
||||
|
||||
try {
|
||||
let error = FT_Get_Kerning(face.ptr, glyph1, glyph2, m.FT_KERNING_DEFAULT, ptr);
|
||||
|
||||
if (error) throw new Error(`error in FT_Get_Kerning: ${error}`);
|
||||
} finally {
|
||||
m._free(ptr);
|
||||
}
|
||||
|
||||
return {
|
||||
x: from_26_6(m.getValue(ptr, 'i32')),
|
||||
y: from_26_6(m.getValue(ptr + 4, 'i32'))
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.glyph_exists = function (face, code) {
|
||||
let glyph_index = FT_Get_Char_Index(face.ptr, code);
|
||||
|
||||
return glyph_index !== 0;
|
||||
};
|
||||
|
||||
|
||||
module.exports.glyph_render = function (face, code, opts = {}) {
|
||||
let glyph_index = FT_Get_Char_Index(face.ptr, code);
|
||||
|
||||
if (glyph_index === 0) throw new Error(`glyph does not exist for codepoint ${code}`);
|
||||
|
||||
let load_flags = m.FT_LOAD_RENDER;
|
||||
|
||||
if (opts.mono) {
|
||||
load_flags |= m.FT_LOAD_TARGET_MONO;
|
||||
|
||||
} else if (opts.lcd) {
|
||||
load_flags |= m.FT_LOAD_TARGET_LCD;
|
||||
|
||||
} else if (opts.lcd_v) {
|
||||
load_flags |= m.FT_LOAD_TARGET_LCD_V;
|
||||
|
||||
} else {
|
||||
/* eslint-disable no-lonely-if */
|
||||
|
||||
// Use "light" by default, it changes horizontal lines only.
|
||||
// "normal" is more strong (with vertical lines), but will break kerning, if
|
||||
// no additional care taken. More advanced rendering requires upper level
|
||||
// layout support (via Harfbuzz, for example).
|
||||
if (!opts.autohint_strong) load_flags |= m.FT_LOAD_TARGET_LIGHT;
|
||||
else load_flags |= m.FT_LOAD_TARGET_NORMAL;
|
||||
}
|
||||
|
||||
if (opts.autohint_off) load_flags |= m.FT_LOAD_NO_AUTOHINT;
|
||||
else load_flags |= m.FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
if (opts.use_color_info) load_flags |= m.FT_LOAD_COLOR;
|
||||
|
||||
let error = FT_Load_Glyph(face.ptr, glyph_index, load_flags);
|
||||
|
||||
if (error) throw new Error(`error in FT_Load_Glyph: ${error}`);
|
||||
|
||||
let glyph = m.getValue(face.ptr + m.OFFSET_FACE_GLYPH, 'i32');
|
||||
|
||||
let glyph_data = {
|
||||
glyph_index: m.getValue(glyph + m.OFFSET_GLYPH_INDEX, 'i32'),
|
||||
metrics: {
|
||||
width: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_WIDTH, 'i32')),
|
||||
height: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_HEIGHT, 'i32')),
|
||||
horiBearingX: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_HORI_BEARING_X, 'i32')),
|
||||
horiBearingY: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_HORI_BEARING_Y, 'i32')),
|
||||
horiAdvance: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_HORI_ADVANCE, 'i32')),
|
||||
vertBearingX: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_VERT_BEARING_X, 'i32')),
|
||||
vertBearingY: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_VERT_BEARING_Y, 'i32')),
|
||||
vertAdvance: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_METRICS_VERT_ADVANCE, 'i32'))
|
||||
},
|
||||
linearHoriAdvance: from_16_16(m.getValue(glyph + m.OFFSET_GLYPH_LINEAR_HORI_ADVANCE, 'i32')),
|
||||
linearVertAdvance: from_16_16(m.getValue(glyph + m.OFFSET_GLYPH_LINEAR_VERT_ADVANCE, 'i32')),
|
||||
advance: {
|
||||
x: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_ADVANCE_X, 'i32')),
|
||||
y: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_ADVANCE_Y, 'i32'))
|
||||
},
|
||||
bitmap: {
|
||||
width: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_WIDTH, 'i32'),
|
||||
rows: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_ROWS, 'i32'),
|
||||
pitch: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_PITCH, 'i32'),
|
||||
num_grays: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_NUM_GRAYS, 'i16'),
|
||||
pixel_mode: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_PIXEL_MODE, 'i8'),
|
||||
palette_mode: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_PALETTE_MODE, 'i8')
|
||||
},
|
||||
bitmap_left: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_LEFT, 'i32'),
|
||||
bitmap_top: m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_TOP, 'i32'),
|
||||
lsb_delta: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_LSB_DELTA, 'i32')),
|
||||
rsb_delta: from_26_6(m.getValue(glyph + m.OFFSET_GLYPH_RSB_DELTA, 'i32'))
|
||||
};
|
||||
|
||||
let g_w = glyph_data.bitmap.width;
|
||||
let g_h = glyph_data.bitmap.rows;
|
||||
let g_x = glyph_data.bitmap_left;
|
||||
let g_y = glyph_data.bitmap_top;
|
||||
|
||||
let buffer = m.getValue(glyph + m.OFFSET_GLYPH_BITMAP_BUFFER, 'i32');
|
||||
let pitch = Math.abs(glyph_data.bitmap.pitch);
|
||||
|
||||
let advance_x = glyph_data.linearHoriAdvance;
|
||||
let advance_y = glyph_data.linearVertAdvance;
|
||||
|
||||
let pixel_mode = glyph_data.bitmap.pixel_mode;
|
||||
|
||||
let output = [];
|
||||
|
||||
for (let y = 0; y < g_h; y++) {
|
||||
let row_start = buffer + y * pitch;
|
||||
let line = [];
|
||||
|
||||
for (let x = 0; x < g_w; x++) {
|
||||
if (pixel_mode === m.FT_PIXEL_MODE_MONO) {
|
||||
let value = m.getValue(row_start + ~~(x / 8), 'i8');
|
||||
line.push(value & (1 << (7 - (x % 8))) ? 255 : 0);
|
||||
} else if (pixel_mode === m.FT_PIXEL_MODE_BGRA) {
|
||||
let blue = int8_to_uint8(m.getValue(row_start + (x * 4) + 0, 'i8'));
|
||||
let green = int8_to_uint8(m.getValue(row_start + (x * 4) + 1, 'i8'));
|
||||
let red = int8_to_uint8(m.getValue(row_start + (x * 4) + 2, 'i8'));
|
||||
let alpha = int8_to_uint8(m.getValue(row_start + (x * 4) + 3, 'i8'));
|
||||
// convert RGBA to grayscale
|
||||
let grayscale = Math.round(0.299 * red + 0.587 * green + 0.114 * blue);
|
||||
if (grayscale > 255) grayscale = 255;
|
||||
// meld grayscale into alpha channel
|
||||
alpha = ((255 - grayscale) * alpha) / 255;
|
||||
line.push(alpha);
|
||||
} else {
|
||||
let value = m.getValue(row_start + x, 'i8');
|
||||
line.push(int8_to_uint8(value));
|
||||
}
|
||||
}
|
||||
|
||||
output.push(line);
|
||||
}
|
||||
|
||||
return {
|
||||
x: g_x,
|
||||
y: g_y,
|
||||
width: g_w,
|
||||
height: g_h,
|
||||
advance_x,
|
||||
advance_y,
|
||||
pixels: output,
|
||||
freetype: glyph_data
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.fontface_destroy = function (face) {
|
||||
let error = FT_Done_Face(face.ptr);
|
||||
|
||||
if (error) throw new Error(`error in FT_Done_Face: ${error}`);
|
||||
|
||||
m._free(face.font);
|
||||
face.ptr = 0;
|
||||
face.font = 0;
|
||||
};
|
||||
|
||||
|
||||
module.exports.destroy = function () {
|
||||
let error = m.ccall('FT_Done_FreeType', 'number', [ 'number' ], [ library ]);
|
||||
|
||||
if (error) throw new Error(`error in FT_Done_FreeType: ${error}`);
|
||||
|
||||
library = 0;
|
||||
|
||||
// don't unload wasm - slows down tests too much
|
||||
//m = null;
|
||||
};
|
83
node_modules/lv_font_conv/lib/freetype/render.c
generated
vendored
@ -1,83 +0,0 @@
|
||||
#include <emscripten.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
static void set_js_variable(char* name, int value) {
|
||||
char buffer[strlen(name) + 32];
|
||||
sprintf(buffer, "Module.%s = %d;", name, value);
|
||||
emscripten_run_script(buffer);
|
||||
}
|
||||
|
||||
// Expose constants, used in calls from js
|
||||
void init_constants()
|
||||
{
|
||||
set_js_variable("FT_LOAD_DEFAULT", FT_LOAD_DEFAULT);
|
||||
set_js_variable("FT_LOAD_NO_HINTING", FT_LOAD_NO_HINTING);
|
||||
set_js_variable("FT_LOAD_RENDER", FT_LOAD_RENDER);
|
||||
set_js_variable("FT_LOAD_FORCE_AUTOHINT", FT_LOAD_FORCE_AUTOHINT);
|
||||
set_js_variable("FT_LOAD_PEDANTIC", FT_LOAD_PEDANTIC);
|
||||
set_js_variable("FT_LOAD_MONOCHROME", FT_LOAD_MONOCHROME);
|
||||
set_js_variable("FT_LOAD_NO_AUTOHINT", FT_LOAD_NO_AUTOHINT);
|
||||
set_js_variable("FT_LOAD_COLOR", FT_LOAD_COLOR);
|
||||
|
||||
set_js_variable("FT_LOAD_TARGET_NORMAL", FT_LOAD_TARGET_NORMAL);
|
||||
set_js_variable("FT_LOAD_TARGET_LIGHT", FT_LOAD_TARGET_LIGHT);
|
||||
set_js_variable("FT_LOAD_TARGET_MONO", FT_LOAD_TARGET_MONO);
|
||||
set_js_variable("FT_LOAD_TARGET_LCD", FT_LOAD_TARGET_LCD);
|
||||
set_js_variable("FT_LOAD_TARGET_LCD_V", FT_LOAD_TARGET_LCD_V);
|
||||
|
||||
set_js_variable("FT_RENDER_MODE_NORMAL", FT_RENDER_MODE_NORMAL);
|
||||
set_js_variable("FT_RENDER_MODE_MONO", FT_RENDER_MODE_MONO);
|
||||
set_js_variable("FT_RENDER_MODE_LCD", FT_RENDER_MODE_LCD);
|
||||
set_js_variable("FT_RENDER_MODE_LCD_V", FT_RENDER_MODE_LCD_V);
|
||||
|
||||
set_js_variable("FT_KERNING_DEFAULT", FT_KERNING_DEFAULT);
|
||||
set_js_variable("FT_KERNING_UNFITTED", FT_KERNING_UNFITTED);
|
||||
set_js_variable("FT_KERNING_UNSCALED", FT_KERNING_UNSCALED);
|
||||
|
||||
set_js_variable("FT_SFNT_OS2", FT_SFNT_OS2);
|
||||
|
||||
set_js_variable("FT_FACE_FLAG_COLOR", FT_FACE_FLAG_COLOR);
|
||||
|
||||
set_js_variable("FT_PIXEL_MODE_MONO", FT_PIXEL_MODE_MONO);
|
||||
set_js_variable("FT_PIXEL_MODE_BGRA", FT_PIXEL_MODE_BGRA);
|
||||
|
||||
set_js_variable("OFFSET_FACE_GLYPH", offsetof(FT_FaceRec, glyph));
|
||||
set_js_variable("OFFSET_FACE_UNITS_PER_EM", offsetof(FT_FaceRec, units_per_EM));
|
||||
set_js_variable("OFFSET_FACE_ASCENDER", offsetof(FT_FaceRec, ascender));
|
||||
set_js_variable("OFFSET_FACE_DESCENDER", offsetof(FT_FaceRec, descender));
|
||||
set_js_variable("OFFSET_FACE_HEIGHT", offsetof(FT_FaceRec, height));
|
||||
set_js_variable("OFFSET_FACE_FACE_FLAGS", offsetof(FT_FaceRec, face_flags));
|
||||
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_WIDTH", offsetof(FT_GlyphSlotRec, bitmap.width));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_ROWS", offsetof(FT_GlyphSlotRec, bitmap.rows));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_PITCH", offsetof(FT_GlyphSlotRec, bitmap.pitch));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_BUFFER", offsetof(FT_GlyphSlotRec, bitmap.buffer));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_NUM_GRAYS", offsetof(FT_GlyphSlotRec, bitmap.num_grays));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_PIXEL_MODE", offsetof(FT_GlyphSlotRec, bitmap.pixel_mode));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_PALETTE_MODE", offsetof(FT_GlyphSlotRec, bitmap.palette_mode));
|
||||
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_WIDTH", offsetof(FT_GlyphSlotRec, metrics.width));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_HEIGHT", offsetof(FT_GlyphSlotRec, metrics.height));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_HORI_BEARING_X", offsetof(FT_GlyphSlotRec, metrics.horiBearingX));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_HORI_BEARING_Y", offsetof(FT_GlyphSlotRec, metrics.horiBearingY));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_HORI_ADVANCE", offsetof(FT_GlyphSlotRec, metrics.horiAdvance));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_VERT_BEARING_X", offsetof(FT_GlyphSlotRec, metrics.vertBearingX));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_VERT_BEARING_Y", offsetof(FT_GlyphSlotRec, metrics.vertBearingY));
|
||||
set_js_variable("OFFSET_GLYPH_METRICS_VERT_ADVANCE", offsetof(FT_GlyphSlotRec, metrics.vertAdvance));
|
||||
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_LEFT", offsetof(FT_GlyphSlotRec, bitmap_left));
|
||||
set_js_variable("OFFSET_GLYPH_BITMAP_TOP", offsetof(FT_GlyphSlotRec, bitmap_top));
|
||||
set_js_variable("OFFSET_GLYPH_INDEX", offsetof(FT_GlyphSlotRec, glyph_index));
|
||||
set_js_variable("OFFSET_GLYPH_LINEAR_HORI_ADVANCE", offsetof(FT_GlyphSlotRec, linearHoriAdvance));
|
||||
set_js_variable("OFFSET_GLYPH_LINEAR_VERT_ADVANCE", offsetof(FT_GlyphSlotRec, linearVertAdvance));
|
||||
set_js_variable("OFFSET_GLYPH_ADVANCE_X", offsetof(FT_GlyphSlotRec, advance.x));
|
||||
set_js_variable("OFFSET_GLYPH_ADVANCE_Y", offsetof(FT_GlyphSlotRec, advance.y));
|
||||
set_js_variable("OFFSET_GLYPH_LSB_DELTA", offsetof(FT_GlyphSlotRec, lsb_delta));
|
||||
set_js_variable("OFFSET_GLYPH_RSB_DELTA", offsetof(FT_GlyphSlotRec, rsb_delta));
|
||||
|
||||
set_js_variable("OFFSET_TT_OS2_ASCENDER", offsetof(TT_OS2, sTypoAscender));
|
||||
set_js_variable("OFFSET_TT_OS2_DESCENDER", offsetof(TT_OS2, sTypoDescender));
|
||||
set_js_variable("OFFSET_TT_OS2_LINEGAP", offsetof(TT_OS2, sTypoLineGap));
|
||||
}
|
51
node_modules/lv_font_conv/lib/ranger.js
generated
vendored
@ -1,51 +0,0 @@
|
||||
// Merge ranges into single object
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
class Ranger {
|
||||
constructor() {
|
||||
this.data = {};
|
||||
}
|
||||
|
||||
// input:
|
||||
// -r 0x1F450 - single value, dec or hex format
|
||||
// -r 0x1F450-0x1F470 - range
|
||||
// -r 0x1F450=>0xF005 - single glyph with mapping
|
||||
// -r 0x1F450-0x1F470=>0xF005 - range with mapping
|
||||
add_range(font, start, end, mapped_start) {
|
||||
let offset = mapped_start - start;
|
||||
let output = [];
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
this._set_char(font, i, i + offset);
|
||||
output.push(i);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// input: characters to copy, e.g. '1234567890abcdef'
|
||||
add_symbols(font, str) {
|
||||
let output = [];
|
||||
|
||||
for (let chr of str) {
|
||||
let code = chr.codePointAt(0);
|
||||
this._set_char(font, code, code);
|
||||
output.push(code);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
_set_char(font, code, mapped_to) {
|
||||
this.data[mapped_to] = { font, code };
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = Ranger;
|
131
node_modules/lv_font_conv/lib/utils.js
generated
vendored
@ -1,131 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
function set_byte_depth(depth) {
|
||||
return function (byte) {
|
||||
// calculate significant bits, e.g. for depth=2 it's 0, 1, 2 or 3
|
||||
let value = ~~(byte / (256 >> depth));
|
||||
|
||||
// spread those bits around 0..255 range, e.g. for depth=2 it's 0, 85, 170 or 255
|
||||
let scale = (2 << (depth - 1)) - 1;
|
||||
|
||||
return (value * 0xFFFF / scale) >> 8;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
module.exports.set_depth = function set_depth(glyph, depth) {
|
||||
let pixels = [];
|
||||
let fn = set_byte_depth(depth);
|
||||
|
||||
for (let y = 0; y < glyph.bbox.height; y++) {
|
||||
pixels.push(glyph.pixels[y].map(fn));
|
||||
}
|
||||
|
||||
return Object.assign({}, glyph, { pixels });
|
||||
};
|
||||
|
||||
|
||||
function count_bits(val) {
|
||||
let count = 0;
|
||||
val = ~~val;
|
||||
|
||||
while (val) {
|
||||
count++;
|
||||
val >>= 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Minimal number of bits to store unsigned value
|
||||
module.exports.unsigned_bits = count_bits;
|
||||
|
||||
// Minimal number of bits to store signed value
|
||||
module.exports.signed_bits = function signed_bits(val) {
|
||||
if (val >= 0) return count_bits(val) + 1;
|
||||
|
||||
return count_bits(Math.abs(val) - 1) + 1;
|
||||
};
|
||||
|
||||
// Align value to 4x - useful to create word-aligned arrays
|
||||
function align4(size) {
|
||||
if (size % 4 === 0) return size;
|
||||
return size + 4 - (size % 4);
|
||||
}
|
||||
module.exports.align4 = align4;
|
||||
|
||||
// Align buffer length to 4x (returns copy with zero-filled tail)
|
||||
module.exports.balign4 = function balign4(buf) {
|
||||
let buf_aligned = Buffer.alloc(align4(buf.length));
|
||||
buf.copy(buf_aligned);
|
||||
return buf_aligned;
|
||||
};
|
||||
|
||||
// Pre-filter image to improve compression ratio
|
||||
// In this case - XOR lines, because it's very effective
|
||||
// in decompressor and does not depend on bpp.
|
||||
module.exports.prefilter = function prefilter(pixels) {
|
||||
return pixels.map((line, l_idx, arr) => {
|
||||
if (l_idx === 0) return line.slice();
|
||||
|
||||
return line.map((p, idx) => p ^ arr[l_idx - 1][idx]);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Convert array with uint16 data to buffer
|
||||
module.exports.bFromA16 = function bFromA16(arr) {
|
||||
const buf = Buffer.alloc(arr.length * 2);
|
||||
|
||||
for (let i = 0; i < arr.length; i++) buf.writeUInt16LE(arr[i], i * 2);
|
||||
|
||||
return buf;
|
||||
};
|
||||
|
||||
// Convert array with uint32 data to buffer
|
||||
module.exports.bFromA32 = function bFromA32(arr) {
|
||||
const buf = Buffer.alloc(arr.length * 4);
|
||||
|
||||
for (let i = 0; i < arr.length; i++) buf.writeUInt32LE(arr[i], i * 4);
|
||||
|
||||
return buf;
|
||||
};
|
||||
|
||||
|
||||
function chunk(arr, size) {
|
||||
const result = [];
|
||||
for (let i = 0; i < arr.length; i += size) {
|
||||
result.push(arr.slice(i, i + size));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Dump long array to multiline format with X columns and Y indent
|
||||
module.exports.long_dump = function long_dump(arr, options = {}) {
|
||||
const defaults = {
|
||||
col: 8,
|
||||
indent: 4,
|
||||
hex: false
|
||||
};
|
||||
|
||||
let opts = Object.assign({}, defaults, options);
|
||||
let indent = ' '.repeat(opts.indent);
|
||||
|
||||
return chunk(Array.from(arr), opts.col)
|
||||
.map(l => l.map(v => (opts.hex ? `0x${v.toString(16)}` : v.toString())))
|
||||
.map(l => `${indent}${l.join(', ')}`)
|
||||
.join(',\n');
|
||||
};
|
||||
|
||||
// stable sort by pick() result
|
||||
module.exports.sort_by = function sort_by(arr, pick) {
|
||||
return arr
|
||||
.map((el, idx) => ({ el, idx }))
|
||||
.sort((a, b) => (pick(a.el) - pick(b.el)) || (a.idx - b.idx))
|
||||
.map(({ el }) => el);
|
||||
};
|
||||
|
||||
module.exports.sum = function sum(arr) {
|
||||
return arr.reduce((a, v) => a + v, 0);
|
||||
};
|
17
node_modules/lv_font_conv/lib/writers/bin.js
generated
vendored
@ -1,17 +0,0 @@
|
||||
// Write font in binary format
|
||||
'use strict';
|
||||
|
||||
|
||||
const AppError = require('../app_error');
|
||||
const Font = require('../font/font');
|
||||
|
||||
|
||||
module.exports = function write_images(args, fontData) {
|
||||
if (!args.output) throw new AppError('Output is required for "bin" writer');
|
||||
|
||||
const font = new Font(fontData, args);
|
||||
|
||||
return {
|
||||
[args.output]: font.toBin()
|
||||
};
|
||||
};
|
68
node_modules/lv_font_conv/lib/writers/dump.js
generated
vendored
@ -1,68 +0,0 @@
|
||||
// Write font data into png images
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
const path = require('path');
|
||||
const { PNG } = require('pngjs');
|
||||
const AppError = require('../app_error');
|
||||
const utils = require('../utils');
|
||||
|
||||
const normal_color = [ 255, 255, 255 ];
|
||||
const outside_color = [ 255, 127, 184 ];
|
||||
|
||||
|
||||
module.exports = function write_images(args, font) {
|
||||
if (!args.output) throw new AppError('Output is required for "dump" writer');
|
||||
|
||||
let files = {};
|
||||
|
||||
let glyphs = font.glyphs.map(glyph => utils.set_depth(glyph, args.bpp));
|
||||
|
||||
for (let glyph of glyphs) {
|
||||
let { code, advanceWidth, bbox, pixels } = glyph;
|
||||
|
||||
advanceWidth = Math.round(advanceWidth);
|
||||
|
||||
let minX = bbox.x;
|
||||
let maxX = Math.max(bbox.x + bbox.width - 1, bbox.x);
|
||||
let minY = Math.min(bbox.y, font.typoDescent);
|
||||
let maxY = Math.max(bbox.y + bbox.height - 1, font.typoAscent);
|
||||
|
||||
let png = new PNG({ width: maxX - minX + 1, height: maxY - minY + 1 });
|
||||
|
||||
/* eslint-disable max-depth */
|
||||
for (let pos = 0, y = maxY; y >= minY; y--) {
|
||||
for (let x = minX; x <= maxX; x++) {
|
||||
let value = 0;
|
||||
|
||||
if (x >= bbox.x && x < bbox.x + bbox.width && y >= bbox.y && y < bbox.y + bbox.height) {
|
||||
value = pixels[bbox.height - (y - bbox.y) - 1][x - bbox.x];
|
||||
}
|
||||
|
||||
let r, g, b;
|
||||
|
||||
if (x < 0 || x >= advanceWidth || y < font.typoDescent || y > font.typoAscent) {
|
||||
[ r, g, b ] = outside_color;
|
||||
} else {
|
||||
[ r, g, b ] = normal_color;
|
||||
}
|
||||
|
||||
png.data[pos++] = (255 - value) * r / 255;
|
||||
png.data[pos++] = (255 - value) * g / 255;
|
||||
png.data[pos++] = (255 - value) * b / 255;
|
||||
png.data[pos++] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
files[path.join(args.output, `${code.toString(16)}.png`)] = PNG.sync.write(png);
|
||||
}
|
||||
|
||||
files[path.join(args.output, 'font_info.json')] = JSON.stringify(
|
||||
font,
|
||||
(k, v) => (k === 'pixels' && !args.full_info ? undefined : v),
|
||||
2);
|
||||
|
||||
return files;
|
||||
};
|
17
node_modules/lv_font_conv/lib/writers/lvgl/index.js
generated
vendored
@ -1,17 +0,0 @@
|
||||
// Write font in lvgl format
|
||||
'use strict';
|
||||
|
||||
|
||||
const AppError = require('../../app_error');
|
||||
const Font = require('./lv_font');
|
||||
|
||||
|
||||
module.exports = function write_images(args, fontData) {
|
||||
if (!args.output) throw new AppError('Output is required for "lvgl" writer');
|
||||
|
||||
const font = new Font(fontData, args);
|
||||
|
||||
return {
|
||||
[args.output]: font.toLVGL()
|
||||
};
|
||||
};
|
98
node_modules/lv_font_conv/lib/writers/lvgl/lv_font.js
generated
vendored
@ -1,98 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const Font = require('../../font/font');
|
||||
const Head = require('./lv_table_head');
|
||||
const Cmap = require('./lv_table_cmap');
|
||||
const Glyf = require('./lv_table_glyf');
|
||||
const Kern = require('./lv_table_kern');
|
||||
const AppError = require('../../app_error');
|
||||
|
||||
|
||||
class LvFont extends Font {
|
||||
constructor(fontData, options) {
|
||||
super(fontData, options);
|
||||
|
||||
const ext = path.extname(options.output);
|
||||
this.font_name = path.basename(options.output, ext);
|
||||
|
||||
if (options.bpp === 3 & options.no_compress) {
|
||||
throw new AppError('LittlevGL supports "--bpp 3" with compression only');
|
||||
}
|
||||
}
|
||||
|
||||
init_tables() {
|
||||
this.head = new Head(this);
|
||||
this.glyf = new Glyf(this);
|
||||
this.cmap = new Cmap(this);
|
||||
this.kern = new Kern(this);
|
||||
}
|
||||
|
||||
large_format_guard() {
|
||||
let guard_required = false;
|
||||
let glyphs_bin_size = 0;
|
||||
|
||||
this.glyf.lv_data.forEach(d => {
|
||||
glyphs_bin_size += d.bin.length;
|
||||
|
||||
if (d.glyph.bbox.width > 255 ||
|
||||
d.glyph.bbox.height > 255 ||
|
||||
Math.abs(d.glyph.bbox.x) > 127 ||
|
||||
Math.abs(d.glyph.bbox.y) > 127 ||
|
||||
Math.round(d.glyph.advanceWidth * 16) > 4096) {
|
||||
guard_required = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (glyphs_bin_size > 1024 * 1024) guard_required = true;
|
||||
|
||||
if (!guard_required) return '';
|
||||
|
||||
return `
|
||||
#if (LV_FONT_FMT_TXT_LARGE == 0)
|
||||
# error "Too large font or glyphs in ${this.font_name.toUpperCase()}. Enable LV_FONT_FMT_TXT_LARGE in lv_conf.h")
|
||||
#endif
|
||||
`.trimLeft();
|
||||
}
|
||||
|
||||
toLVGL() {
|
||||
let guard_name = this.font_name.toUpperCase();
|
||||
|
||||
return `/*******************************************************************************
|
||||
* Size: ${this.src.size} px
|
||||
* Bpp: ${this.opts.bpp}
|
||||
* Opts: ${process.argv.slice(2).join(' ')}
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "${this.opts.lv_include || 'lvgl/lvgl.h'}"
|
||||
#endif
|
||||
|
||||
#ifndef ${guard_name}
|
||||
#define ${guard_name} 1
|
||||
#endif
|
||||
|
||||
#if ${guard_name}
|
||||
|
||||
${this.glyf.toLVGL()}
|
||||
|
||||
${this.cmap.toLVGL()}
|
||||
|
||||
${this.kern.toLVGL()}
|
||||
|
||||
${this.head.toLVGL()}
|
||||
|
||||
${this.large_format_guard()}
|
||||
|
||||
#endif /*#if ${guard_name}*/
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = LvFont;
|
125
node_modules/lv_font_conv/lib/writers/lvgl/lv_table_cmap.js
generated
vendored
@ -1,125 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const u = require('../../utils');
|
||||
const build_subtables = require('../../font/cmap_build_subtables');
|
||||
const Cmap = require('../../font/table_cmap');
|
||||
|
||||
|
||||
class LvCmap extends Cmap {
|
||||
constructor(font) {
|
||||
super(font);
|
||||
|
||||
this.lv_compiled = false;
|
||||
this.lv_subtables = [];
|
||||
}
|
||||
|
||||
lv_format2enum(name) {
|
||||
switch (name) {
|
||||
case 'format0_tiny': return 'LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY';
|
||||
case 'format0': return 'LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL';
|
||||
case 'sparse_tiny': return 'LV_FONT_FMT_TXT_CMAP_SPARSE_TINY';
|
||||
case 'sparse': return 'LV_FONT_FMT_TXT_CMAP_SPARSE_FULL';
|
||||
default: throw new Error('Unknown subtable format');
|
||||
}
|
||||
}
|
||||
|
||||
lv_compile() {
|
||||
if (this.lv_compiled) return;
|
||||
this.lv_compiled = true;
|
||||
|
||||
const f = this.font;
|
||||
|
||||
let subtables_plan = build_subtables(f.src.glyphs.map(g => g.code));
|
||||
let idx = 0;
|
||||
|
||||
for (let [ format, codepoints ] of subtables_plan) {
|
||||
let 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 has_charcodes = false;
|
||||
let has_ids = false;
|
||||
let defs = '';
|
||||
let entries_count = 0;
|
||||
|
||||
if (format === 'format0_tiny') {
|
||||
// use default empty values
|
||||
} else if (format === 'format0') {
|
||||
has_ids = true;
|
||||
let d = this.collect_format0_data(min_code, max_code, start_glyph_id);
|
||||
entries_count = d.length;
|
||||
|
||||
defs = `
|
||||
static const uint8_t glyph_id_ofs_list_${idx}[] = {
|
||||
${u.long_dump(d)}
|
||||
};
|
||||
`.trim();
|
||||
|
||||
} else if (format === 'sparse_tiny') {
|
||||
has_charcodes = true;
|
||||
let d = this.collect_sparse_data(codepoints, start_glyph_id);
|
||||
entries_count = d.codes.length;
|
||||
|
||||
defs = `
|
||||
static const uint16_t unicode_list_${idx}[] = {
|
||||
${u.long_dump(d.codes, { hex: true })}
|
||||
};
|
||||
`.trim();
|
||||
|
||||
} else { // assume format === 'sparse'
|
||||
has_charcodes = true;
|
||||
has_ids = true;
|
||||
let d = this.collect_sparse_data(codepoints, start_glyph_id);
|
||||
entries_count = d.codes.length;
|
||||
|
||||
defs = `
|
||||
static const uint16_t unicode_list_${idx}[] = {
|
||||
${u.long_dump(d.codes, { hex: true })}
|
||||
};
|
||||
static const uint16_t glyph_id_ofs_list_${idx}[] = {
|
||||
${u.long_dump(d.ids)}
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
|
||||
const u_list = has_charcodes ? `unicode_list_${idx}` : 'NULL';
|
||||
const id_list = has_ids ? `glyph_id_ofs_list_${idx}` : 'NULL';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
const head = ` {
|
||||
.range_start = ${min_code}, .range_length = ${max_code - min_code + 1}, .glyph_id_start = ${start_glyph_id},
|
||||
.unicode_list = ${u_list}, .glyph_id_ofs_list = ${id_list}, .list_length = ${entries_count}, .type = ${this.lv_format2enum(format)}
|
||||
}`;
|
||||
|
||||
this.lv_subtables.push({
|
||||
defs,
|
||||
head
|
||||
});
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
toLVGL() {
|
||||
this.lv_compile();
|
||||
|
||||
return `
|
||||
/*---------------------
|
||||
* CHARACTER MAPPING
|
||||
*--------------------*/
|
||||
|
||||
${this.lv_subtables.map(d => d.defs).filter(Boolean).join('\n\n')}
|
||||
|
||||
/*Collect the unicode lists and glyph_id offsets*/
|
||||
static const lv_font_fmt_txt_cmap_t cmaps[] =
|
||||
{
|
||||
${this.lv_subtables.map(d => d.head).join(',\n')}
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = LvCmap;
|
121
node_modules/lv_font_conv/lib/writers/lvgl/lv_table_glyf.js
generated
vendored
@ -1,121 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const { BitStream } = require('bit-buffer');
|
||||
const u = require('../../utils');
|
||||
const Glyf = require('../../font/table_glyf');
|
||||
|
||||
|
||||
class LvGlyf extends Glyf {
|
||||
constructor(font) {
|
||||
super(font);
|
||||
|
||||
this.lv_data = [];
|
||||
this.lv_compiled = false;
|
||||
}
|
||||
|
||||
lv_bitmap(glyph) {
|
||||
const buf = Buffer.alloc(100 + glyph.bbox.width * glyph.bbox.height * 4);
|
||||
const bs = new BitStream(buf);
|
||||
bs.bigEndian = true;
|
||||
|
||||
const pixels = this.font.glyf.pixelsToBpp(glyph.pixels);
|
||||
|
||||
this.font.glyf.storePixels(bs, pixels);
|
||||
|
||||
const glyph_bitmap = Buffer.alloc(bs.byteIndex);
|
||||
buf.copy(glyph_bitmap, 0, 0, bs.byteIndex);
|
||||
|
||||
return glyph_bitmap;
|
||||
}
|
||||
|
||||
lv_compile() {
|
||||
if (this.lv_compiled) return;
|
||||
|
||||
this.lv_compiled = true;
|
||||
|
||||
const f = this.font;
|
||||
this.lv_data = [];
|
||||
let offset = 0;
|
||||
|
||||
f.src.glyphs.forEach(g => {
|
||||
const id = f.glyph_id[g.code];
|
||||
const bin = this.lv_bitmap(g);
|
||||
this.lv_data[id] = {
|
||||
bin,
|
||||
offset,
|
||||
glyph: g
|
||||
};
|
||||
offset += bin.length;
|
||||
});
|
||||
}
|
||||
|
||||
to_lv_bitmaps() {
|
||||
this.lv_compile();
|
||||
|
||||
let result = [];
|
||||
this.lv_data.forEach((d, idx) => {
|
||||
if (idx === 0) return;
|
||||
const code_hex = d.glyph.code.toString(16).toUpperCase();
|
||||
const code_str = JSON.stringify(String.fromCodePoint(d.glyph.code));
|
||||
|
||||
let txt = ` /* U+${code_hex.padStart(4, '0')} ${code_str} */
|
||||
${u.long_dump(d.bin, { hex: true })}`;
|
||||
|
||||
if (idx < this.lv_data.length - 1) {
|
||||
// skip comma for zero data
|
||||
txt += d.bin.length ? ',\n\n' : '\n';
|
||||
}
|
||||
|
||||
result.push(txt);
|
||||
});
|
||||
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
to_lv_glyph_dsc() {
|
||||
this.lv_compile();
|
||||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
let result = [ ' {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */' ];
|
||||
|
||||
this.lv_data.forEach(d => {
|
||||
const idx = d.offset,
|
||||
adv_w = Math.round(d.glyph.advanceWidth * 16),
|
||||
h = d.glyph.bbox.height,
|
||||
w = d.glyph.bbox.width,
|
||||
x = d.glyph.bbox.x,
|
||||
y = d.glyph.bbox.y;
|
||||
result.push(` {.bitmap_index = ${idx}, .adv_w = ${adv_w}, .box_w = ${w}, .box_h = ${h}, .ofs_x = ${x}, .ofs_y = ${y}}`);
|
||||
});
|
||||
|
||||
return result.join(',\n');
|
||||
}
|
||||
|
||||
|
||||
toLVGL() {
|
||||
return `
|
||||
/*-----------------
|
||||
* BITMAPS
|
||||
*----------------*/
|
||||
|
||||
/*Store the image of the glyphs*/
|
||||
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
${this.to_lv_bitmaps()}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------
|
||||
* GLYPH DESCRIPTION
|
||||
*--------------------*/
|
||||
|
||||
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
${this.to_lv_glyph_dsc()}
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = LvGlyf;
|
99
node_modules/lv_font_conv/lib/writers/lvgl/lv_table_head.js
generated
vendored
@ -1,99 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const Head = require('../../font/table_head');
|
||||
|
||||
|
||||
class LvHead extends Head {
|
||||
constructor(font) {
|
||||
super(font);
|
||||
}
|
||||
|
||||
kern_ref() {
|
||||
const f = this.font;
|
||||
|
||||
if (!f.hasKerning()) {
|
||||
return {
|
||||
scale: '0',
|
||||
dsc: 'NULL',
|
||||
classes: '0'
|
||||
};
|
||||
}
|
||||
|
||||
if (!f.kern.should_use_format3()) {
|
||||
return {
|
||||
scale: `${Math.round(f.kerningScale * 16)}`,
|
||||
dsc: '&kern_pairs',
|
||||
classes: '0'
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
scale: `${Math.round(f.kerningScale * 16)}`,
|
||||
dsc: '&kern_classes',
|
||||
classes: '1'
|
||||
};
|
||||
}
|
||||
|
||||
toLVGL() {
|
||||
const f = this.font;
|
||||
const kern = this.kern_ref();
|
||||
const subpixels = (f.subpixels_mode === 0) ? 'LV_FONT_SUBPX_NONE' :
|
||||
(f.subpixels_mode === 1) ? 'LV_FONT_SUBPX_HOR' : 'LV_FONT_SUBPX_VER';
|
||||
|
||||
return `
|
||||
/*--------------------
|
||||
* ALL CUSTOM DATA
|
||||
*--------------------*/
|
||||
|
||||
#if LV_VERSION_CHECK(8, 0, 0)
|
||||
/*Store all the custom data of the font*/
|
||||
static lv_font_fmt_txt_glyph_cache_t cache;
|
||||
static const lv_font_fmt_txt_dsc_t font_dsc = {
|
||||
#else
|
||||
static lv_font_fmt_txt_dsc_t font_dsc = {
|
||||
#endif
|
||||
.glyph_bitmap = glyph_bitmap,
|
||||
.glyph_dsc = glyph_dsc,
|
||||
.cmaps = cmaps,
|
||||
.kern_dsc = ${kern.dsc},
|
||||
.kern_scale = ${kern.scale},
|
||||
.cmap_num = ${f.cmap.toBin().readUInt32LE(8)},
|
||||
.bpp = ${f.opts.bpp},
|
||||
.kern_classes = ${kern.classes},
|
||||
.bitmap_format = ${f.glyf.getCompressionCode()},
|
||||
#if LV_VERSION_CHECK(8, 0, 0)
|
||||
.cache = &cache
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/*-----------------
|
||||
* PUBLIC FONT
|
||||
*----------------*/
|
||||
|
||||
/*Initialize a public general font descriptor*/
|
||||
#if LV_VERSION_CHECK(8, 0, 0)
|
||||
const lv_font_t ${f.font_name} = {
|
||||
#else
|
||||
lv_font_t ${f.font_name} = {
|
||||
#endif
|
||||
.get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/
|
||||
.get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/
|
||||
.line_height = ${f.src.ascent - f.src.descent}, /*The maximum line height required by the font*/
|
||||
.base_line = ${-f.src.descent}, /*Baseline measured from the bottom of the line*/
|
||||
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
|
||||
.subpx = ${subpixels},
|
||||
#endif
|
||||
#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
|
||||
.underline_position = ${f.src.underlinePosition},
|
||||
.underline_thickness = ${f.src.underlineThickness},
|
||||
#endif
|
||||
.dsc = &font_dsc /*The custom font data. Will be accessed by \`get_glyph_bitmap/dsc\` */
|
||||
};
|
||||
`.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = LvHead;
|
121
node_modules/lv_font_conv/lib/writers/lvgl/lv_table_kern.js
generated
vendored
@ -1,121 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const u = require('../../utils');
|
||||
const Kern = require('../../font/table_kern');
|
||||
|
||||
|
||||
class LvKern extends Kern {
|
||||
constructor(font) {
|
||||
super(font);
|
||||
}
|
||||
|
||||
to_lv_format0() {
|
||||
const f = this.font;
|
||||
let kern_pairs = this.collect_format0_data();
|
||||
|
||||
return `
|
||||
/*-----------------
|
||||
* KERNING
|
||||
*----------------*/
|
||||
|
||||
|
||||
/*Pair left and right glyphs for kerning*/
|
||||
static const ${f.glyphIdFormat ? 'uint16_t' : 'uint8_t'} kern_pair_glyph_ids[] =
|
||||
{
|
||||
${kern_pairs.map(pair => ` ${pair[0]}, ${pair[1]}`).join(',\n')}
|
||||
};
|
||||
|
||||
/* Kerning between the respective left and right glyphs
|
||||
* 4.4 format which needs to scaled with \`kern_scale\`*/
|
||||
static const int8_t kern_pair_values[] =
|
||||
{
|
||||
${u.long_dump(kern_pairs.map(pair => f.kernToFP(pair[2])))}
|
||||
};
|
||||
|
||||
/*Collect the kern pair's data in one place*/
|
||||
static const lv_font_fmt_txt_kern_pair_t kern_pairs =
|
||||
{
|
||||
.glyph_ids = kern_pair_glyph_ids,
|
||||
.values = kern_pair_values,
|
||||
.pair_cnt = ${kern_pairs.length},
|
||||
.glyph_ids_size = ${f.glyphIdFormat}
|
||||
};
|
||||
|
||||
|
||||
`.trim();
|
||||
}
|
||||
|
||||
to_lv_format3() {
|
||||
const f = this.font;
|
||||
const {
|
||||
left_classes,
|
||||
right_classes,
|
||||
left_mapping,
|
||||
right_mapping,
|
||||
values
|
||||
} = this.collect_format3_data();
|
||||
|
||||
return `
|
||||
/*-----------------
|
||||
* KERNING
|
||||
*----------------*/
|
||||
|
||||
|
||||
/*Map glyph_ids to kern left classes*/
|
||||
static const uint8_t kern_left_class_mapping[] =
|
||||
{
|
||||
${u.long_dump(left_mapping)}
|
||||
};
|
||||
|
||||
/*Map glyph_ids to kern right classes*/
|
||||
static const uint8_t kern_right_class_mapping[] =
|
||||
{
|
||||
${u.long_dump(right_mapping)}
|
||||
};
|
||||
|
||||
/*Kern values between classes*/
|
||||
static const int8_t kern_class_values[] =
|
||||
{
|
||||
${u.long_dump(values.map(v => f.kernToFP(v)))}
|
||||
};
|
||||
|
||||
|
||||
/*Collect the kern class' data in one place*/
|
||||
static const lv_font_fmt_txt_kern_classes_t kern_classes =
|
||||
{
|
||||
.class_pair_values = kern_class_values,
|
||||
.left_class_mapping = kern_left_class_mapping,
|
||||
.right_class_mapping = kern_right_class_mapping,
|
||||
.left_class_cnt = ${left_classes},
|
||||
.right_class_cnt = ${right_classes},
|
||||
};
|
||||
|
||||
|
||||
`.trim();
|
||||
}
|
||||
|
||||
toLVGL() {
|
||||
const f = this.font;
|
||||
|
||||
if (!f.hasKerning()) return '';
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
if (f.kern.should_use_format3()) {
|
||||
if (f.kern.format3_forced) {
|
||||
let diff = this.create_format3_data().length - this.create_format0_data().length;
|
||||
console.log(`Forced faster kerning format (via classes). Size increase is ${diff} bytes.`);
|
||||
}
|
||||
return this.to_lv_format3();
|
||||
}
|
||||
|
||||
if (this.font.opts.fast_kerning) {
|
||||
console.log('Forced faster kerning format (via classes), but data exceeds it\'s limits. Continue use pairs.');
|
||||
}
|
||||
return this.to_lv_format0();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = LvKern;
|
17
node_modules/lv_font_conv/lv_font_conv.js
generated
vendored
@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const AppError = require('./lib/app_error');
|
||||
|
||||
require('./lib/cli').run(process.argv.slice(2)).catch(err => {
|
||||
/*eslint-disable no-console*/
|
||||
if (err instanceof AppError) {
|
||||
// Try to beautify normal errors
|
||||
console.error(err.message.trim());
|
||||
} else {
|
||||
// Print crashes
|
||||
console.error(err.stack);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
216
node_modules/lv_font_conv/node_modules/argparse/CHANGELOG.md
generated
vendored
@ -1,216 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
|
||||
## [2.0.1] - 2020-08-29
|
||||
### Fixed
|
||||
- Fix issue with `process.argv` when used with interpreters (`coffee`, `ts-node`, etc.), #150.
|
||||
|
||||
|
||||
## [2.0.0] - 2020-08-14
|
||||
### Changed
|
||||
- Full rewrite. Now port from python 3.9.0 & more precise following.
|
||||
See [doc](./doc) for difference and migration info.
|
||||
- node.js 10+ required
|
||||
- Removed most of local docs in favour of original ones.
|
||||
|
||||
|
||||
## [1.0.10] - 2018-02-15
|
||||
### Fixed
|
||||
- Use .concat instead of + for arrays, #122.
|
||||
|
||||
|
||||
## [1.0.9] - 2016-09-29
|
||||
### Changed
|
||||
- Rerelease after 1.0.8 - deps cleanup.
|
||||
|
||||
|
||||
## [1.0.8] - 2016-09-29
|
||||
### Changed
|
||||
- Maintenance (deps bump, fix node 6.5+ tests, coverage report).
|
||||
|
||||
|
||||
## [1.0.7] - 2016-03-17
|
||||
### Changed
|
||||
- Teach `addArgument` to accept string arg names. #97, @tomxtobin.
|
||||
|
||||
|
||||
## [1.0.6] - 2016-02-06
|
||||
### Changed
|
||||
- Maintenance: moved to eslint & updated CS.
|
||||
|
||||
|
||||
## [1.0.5] - 2016-02-05
|
||||
### Changed
|
||||
- Removed lodash dependency to significantly reduce install size.
|
||||
Thanks to @mourner.
|
||||
|
||||
|
||||
## [1.0.4] - 2016-01-17
|
||||
### Changed
|
||||
- Maintenance: lodash update to 4.0.0.
|
||||
|
||||
|
||||
## [1.0.3] - 2015-10-27
|
||||
### Fixed
|
||||
- Fix parse `=` in args: `--examplepath="C:\myfolder\env=x64"`. #84, @CatWithApple.
|
||||
|
||||
|
||||
## [1.0.2] - 2015-03-22
|
||||
### Changed
|
||||
- Relaxed lodash version dependency.
|
||||
|
||||
|
||||
## [1.0.1] - 2015-02-20
|
||||
### Changed
|
||||
- Changed dependencies to be compatible with ancient nodejs.
|
||||
|
||||
|
||||
## [1.0.0] - 2015-02-19
|
||||
### Changed
|
||||
- Maintenance release.
|
||||
- Replaced `underscore` with `lodash`.
|
||||
- Bumped version to 1.0.0 to better reflect semver meaning.
|
||||
- HISTORY.md -> CHANGELOG.md
|
||||
|
||||
|
||||
## [0.1.16] - 2013-12-01
|
||||
### Changed
|
||||
- Maintenance release. Updated dependencies and docs.
|
||||
|
||||
|
||||
## [0.1.15] - 2013-05-13
|
||||
### Fixed
|
||||
- Fixed #55, @trebor89
|
||||
|
||||
|
||||
## [0.1.14] - 2013-05-12
|
||||
### Fixed
|
||||
- Fixed #62, @maxtaco
|
||||
|
||||
|
||||
## [0.1.13] - 2013-04-08
|
||||
### Changed
|
||||
- Added `.npmignore` to reduce package size
|
||||
|
||||
|
||||
## [0.1.12] - 2013-02-10
|
||||
### Fixed
|
||||
- Fixed conflictHandler (#46), @hpaulj
|
||||
|
||||
|
||||
## [0.1.11] - 2013-02-07
|
||||
### Added
|
||||
- Added 70+ tests (ported from python), @hpaulj
|
||||
- Added conflictHandler, @applepicke
|
||||
- Added fromfilePrefixChar, @hpaulj
|
||||
|
||||
### Fixed
|
||||
- Multiple bugfixes, @hpaulj
|
||||
|
||||
|
||||
## [0.1.10] - 2012-12-30
|
||||
### Added
|
||||
- Added [mutual exclusion](http://docs.python.org/dev/library/argparse.html#mutual-exclusion)
|
||||
support, thanks to @hpaulj
|
||||
|
||||
### Fixed
|
||||
- Fixed options check for `storeConst` & `appendConst` actions, thanks to @hpaulj
|
||||
|
||||
|
||||
## [0.1.9] - 2012-12-27
|
||||
### Fixed
|
||||
- Fixed option dest interferens with other options (issue #23), thanks to @hpaulj
|
||||
- Fixed default value behavior with `*` positionals, thanks to @hpaulj
|
||||
- Improve `getDefault()` behavior, thanks to @hpaulj
|
||||
- Improve negative argument parsing, thanks to @hpaulj
|
||||
|
||||
|
||||
## [0.1.8] - 2012-12-01
|
||||
### Fixed
|
||||
- Fixed parser parents (issue #19), thanks to @hpaulj
|
||||
- Fixed negative argument parse (issue #20), thanks to @hpaulj
|
||||
|
||||
|
||||
## [0.1.7] - 2012-10-14
|
||||
### Fixed
|
||||
- Fixed 'choices' argument parse (issue #16)
|
||||
- Fixed stderr output (issue #15)
|
||||
|
||||
|
||||
## [0.1.6] - 2012-09-09
|
||||
### Fixed
|
||||
- Fixed check for conflict of options (thanks to @tomxtobin)
|
||||
|
||||
|
||||
## [0.1.5] - 2012-09-03
|
||||
### Fixed
|
||||
- Fix parser #setDefaults method (thanks to @tomxtobin)
|
||||
|
||||
|
||||
## [0.1.4] - 2012-07-30
|
||||
### Fixed
|
||||
- Fixed pseudo-argument support (thanks to @CGamesPlay)
|
||||
- Fixed addHelp default (should be true), if not set (thanks to @benblank)
|
||||
|
||||
|
||||
## [0.1.3] - 2012-06-27
|
||||
### Fixed
|
||||
- Fixed formatter api name: Formatter -> HelpFormatter
|
||||
|
||||
|
||||
## [0.1.2] - 2012-05-29
|
||||
### Fixed
|
||||
- Removed excess whitespace in help
|
||||
- Fixed error reporting, when parcer with subcommands
|
||||
called with empty arguments
|
||||
|
||||
### Added
|
||||
- Added basic tests
|
||||
|
||||
|
||||
## [0.1.1] - 2012-05-23
|
||||
### Fixed
|
||||
- Fixed line wrapping in help formatter
|
||||
- Added better error reporting on invalid arguments
|
||||
|
||||
|
||||
## [0.1.0] - 2012-05-16
|
||||
### Added
|
||||
- First release.
|
||||
|
||||
|
||||
[2.0.1]: https://github.com/nodeca/argparse/compare/2.0.0...2.0.1
|
||||
[2.0.0]: https://github.com/nodeca/argparse/compare/1.0.10...2.0.0
|
||||
[1.0.10]: https://github.com/nodeca/argparse/compare/1.0.9...1.0.10
|
||||
[1.0.9]: https://github.com/nodeca/argparse/compare/1.0.8...1.0.9
|
||||
[1.0.8]: https://github.com/nodeca/argparse/compare/1.0.7...1.0.8
|
||||
[1.0.7]: https://github.com/nodeca/argparse/compare/1.0.6...1.0.7
|
||||
[1.0.6]: https://github.com/nodeca/argparse/compare/1.0.5...1.0.6
|
||||
[1.0.5]: https://github.com/nodeca/argparse/compare/1.0.4...1.0.5
|
||||
[1.0.4]: https://github.com/nodeca/argparse/compare/1.0.3...1.0.4
|
||||
[1.0.3]: https://github.com/nodeca/argparse/compare/1.0.2...1.0.3
|
||||
[1.0.2]: https://github.com/nodeca/argparse/compare/1.0.1...1.0.2
|
||||
[1.0.1]: https://github.com/nodeca/argparse/compare/1.0.0...1.0.1
|
||||
[1.0.0]: https://github.com/nodeca/argparse/compare/0.1.16...1.0.0
|
||||
[0.1.16]: https://github.com/nodeca/argparse/compare/0.1.15...0.1.16
|
||||
[0.1.15]: https://github.com/nodeca/argparse/compare/0.1.14...0.1.15
|
||||
[0.1.14]: https://github.com/nodeca/argparse/compare/0.1.13...0.1.14
|
||||
[0.1.13]: https://github.com/nodeca/argparse/compare/0.1.12...0.1.13
|
||||
[0.1.12]: https://github.com/nodeca/argparse/compare/0.1.11...0.1.12
|
||||
[0.1.11]: https://github.com/nodeca/argparse/compare/0.1.10...0.1.11
|
||||
[0.1.10]: https://github.com/nodeca/argparse/compare/0.1.9...0.1.10
|
||||
[0.1.9]: https://github.com/nodeca/argparse/compare/0.1.8...0.1.9
|
||||
[0.1.8]: https://github.com/nodeca/argparse/compare/0.1.7...0.1.8
|
||||
[0.1.7]: https://github.com/nodeca/argparse/compare/0.1.6...0.1.7
|
||||
[0.1.6]: https://github.com/nodeca/argparse/compare/0.1.5...0.1.6
|
||||
[0.1.5]: https://github.com/nodeca/argparse/compare/0.1.4...0.1.5
|
||||
[0.1.4]: https://github.com/nodeca/argparse/compare/0.1.3...0.1.4
|
||||
[0.1.3]: https://github.com/nodeca/argparse/compare/0.1.2...0.1.3
|
||||
[0.1.2]: https://github.com/nodeca/argparse/compare/0.1.1...0.1.2
|
||||
[0.1.1]: https://github.com/nodeca/argparse/compare/0.1.0...0.1.1
|
||||
[0.1.0]: https://github.com/nodeca/argparse/releases/tag/0.1.0
|
254
node_modules/lv_font_conv/node_modules/argparse/LICENSE
generated
vendored
@ -1,254 +0,0 @@
|
||||
A. HISTORY OF THE SOFTWARE
|
||||
==========================
|
||||
|
||||
Python was created in the early 1990s by Guido van Rossum at Stichting
|
||||
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
|
||||
as a successor of a language called ABC. Guido remains Python's
|
||||
principal author, although it includes many contributions from others.
|
||||
|
||||
In 1995, Guido continued his work on Python at the Corporation for
|
||||
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
|
||||
in Reston, Virginia where he released several versions of the
|
||||
software.
|
||||
|
||||
In May 2000, Guido and the Python core development team moved to
|
||||
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
|
||||
year, the PythonLabs team moved to Digital Creations, which became
|
||||
Zope Corporation. In 2001, the Python Software Foundation (PSF, see
|
||||
https://www.python.org/psf/) was formed, a non-profit organization
|
||||
created specifically to own Python-related Intellectual Property.
|
||||
Zope Corporation was a sponsoring member of the PSF.
|
||||
|
||||
All Python releases are Open Source (see http://www.opensource.org for
|
||||
the Open Source Definition). Historically, most, but not all, Python
|
||||
releases have also been GPL-compatible; the table below summarizes
|
||||
the various releases.
|
||||
|
||||
Release Derived Year Owner GPL-
|
||||
from compatible? (1)
|
||||
|
||||
0.9.0 thru 1.2 1991-1995 CWI yes
|
||||
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
|
||||
1.6 1.5.2 2000 CNRI no
|
||||
2.0 1.6 2000 BeOpen.com no
|
||||
1.6.1 1.6 2001 CNRI yes (2)
|
||||
2.1 2.0+1.6.1 2001 PSF no
|
||||
2.0.1 2.0+1.6.1 2001 PSF yes
|
||||
2.1.1 2.1+2.0.1 2001 PSF yes
|
||||
2.1.2 2.1.1 2002 PSF yes
|
||||
2.1.3 2.1.2 2002 PSF yes
|
||||
2.2 and above 2.1.1 2001-now PSF yes
|
||||
|
||||
Footnotes:
|
||||
|
||||
(1) GPL-compatible doesn't mean that we're distributing Python under
|
||||
the GPL. All Python licenses, unlike the GPL, let you distribute
|
||||
a modified version without making your changes open source. The
|
||||
GPL-compatible licenses make it possible to combine Python with
|
||||
other software that is released under the GPL; the others don't.
|
||||
|
||||
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
|
||||
because its license has a choice of law clause. According to
|
||||
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
|
||||
is "not incompatible" with the GPL.
|
||||
|
||||
Thanks to the many outside volunteers who have worked under Guido's
|
||||
direction to make these releases possible.
|
||||
|
||||
|
||||
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
|
||||
===============================================================
|
||||
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
--------------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||
distribute, and otherwise use Python alone or in any derivative version,
|
||||
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
|
||||
All Rights Reserved" are retained in Python alone or in any derivative version
|
||||
prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
||||
|
||||
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
|
||||
-------------------------------------------
|
||||
|
||||
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
|
||||
|
||||
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
|
||||
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
|
||||
Individual or Organization ("Licensee") accessing and otherwise using
|
||||
this software in source or binary form and its associated
|
||||
documentation ("the Software").
|
||||
|
||||
2. Subject to the terms and conditions of this BeOpen Python License
|
||||
Agreement, BeOpen hereby grants Licensee a non-exclusive,
|
||||
royalty-free, world-wide license to reproduce, analyze, test, perform
|
||||
and/or display publicly, prepare derivative works, distribute, and
|
||||
otherwise use the Software alone or in any derivative version,
|
||||
provided, however, that the BeOpen Python License is retained in the
|
||||
Software, alone or in any derivative version prepared by Licensee.
|
||||
|
||||
3. BeOpen is making the Software available to Licensee on an "AS IS"
|
||||
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
|
||||
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
|
||||
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
|
||||
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
5. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
6. This License Agreement shall be governed by and interpreted in all
|
||||
respects by the law of the State of California, excluding conflict of
|
||||
law provisions. Nothing in this License Agreement shall be deemed to
|
||||
create any relationship of agency, partnership, or joint venture
|
||||
between BeOpen and Licensee. This License Agreement does not grant
|
||||
permission to use BeOpen trademarks or trade names in a trademark
|
||||
sense to endorse or promote products or services of Licensee, or any
|
||||
third party. As an exception, the "BeOpen Python" logos available at
|
||||
http://www.pythonlabs.com/logos.html may be used according to the
|
||||
permissions granted on that web page.
|
||||
|
||||
7. By copying, installing or otherwise using the software, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
||||
|
||||
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
|
||||
---------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Corporation for National
|
||||
Research Initiatives, having an office at 1895 Preston White Drive,
|
||||
Reston, VA 20191 ("CNRI"), and the Individual or Organization
|
||||
("Licensee") accessing and otherwise using Python 1.6.1 software in
|
||||
source or binary form and its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, CNRI
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python 1.6.1
|
||||
alone or in any derivative version, provided, however, that CNRI's
|
||||
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
|
||||
1995-2001 Corporation for National Research Initiatives; All Rights
|
||||
Reserved" are retained in Python 1.6.1 alone or in any derivative
|
||||
version prepared by Licensee. Alternately, in lieu of CNRI's License
|
||||
Agreement, Licensee may substitute the following text (omitting the
|
||||
quotes): "Python 1.6.1 is made available subject to the terms and
|
||||
conditions in CNRI's License Agreement. This Agreement together with
|
||||
Python 1.6.1 may be located on the Internet using the following
|
||||
unique, persistent identifier (known as a handle): 1895.22/1013. This
|
||||
Agreement may also be obtained from a proxy server on the Internet
|
||||
using the following URL: http://hdl.handle.net/1895.22/1013".
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python 1.6.1 or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python 1.6.1.
|
||||
|
||||
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
|
||||
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. This License Agreement shall be governed by the federal
|
||||
intellectual property law of the United States, including without
|
||||
limitation the federal copyright law, and, to the extent such
|
||||
U.S. federal law does not apply, by the law of the Commonwealth of
|
||||
Virginia, excluding Virginia's conflict of law provisions.
|
||||
Notwithstanding the foregoing, with regard to derivative works based
|
||||
on Python 1.6.1 that incorporate non-separable material that was
|
||||
previously distributed under the GNU General Public License (GPL), the
|
||||
law of the Commonwealth of Virginia shall govern this License
|
||||
Agreement only as to issues arising under or with respect to
|
||||
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
|
||||
License Agreement shall be deemed to create any relationship of
|
||||
agency, partnership, or joint venture between CNRI and Licensee. This
|
||||
License Agreement does not grant permission to use CNRI trademarks or
|
||||
trade name in a trademark sense to endorse or promote products or
|
||||
services of Licensee, or any third party.
|
||||
|
||||
8. By clicking on the "ACCEPT" button where indicated, or by copying,
|
||||
installing or otherwise using Python 1.6.1, Licensee agrees to be
|
||||
bound by the terms and conditions of this License Agreement.
|
||||
|
||||
ACCEPT
|
||||
|
||||
|
||||
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
|
||||
--------------------------------------------------
|
||||
|
||||
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
|
||||
The Netherlands. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
84
node_modules/lv_font_conv/node_modules/argparse/README.md
generated
vendored
@ -1,84 +0,0 @@
|
||||
argparse
|
||||
========
|
||||
|
||||
[![Build Status](https://secure.travis-ci.org/nodeca/argparse.svg?branch=master)](http://travis-ci.org/nodeca/argparse)
|
||||
[![NPM version](https://img.shields.io/npm/v/argparse.svg)](https://www.npmjs.org/package/argparse)
|
||||
|
||||
CLI arguments parser for node.js, with [sub-commands](https://docs.python.org/3.9/library/argparse.html#sub-commands) support. Port of python's [argparse](http://docs.python.org/dev/library/argparse.html) (version [3.9.0](https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py)).
|
||||
|
||||
**Difference with original.**
|
||||
|
||||
- JS has no keyword arguments support.
|
||||
- Pass options instead: `new ArgumentParser({ description: 'example', add_help: true })`.
|
||||
- JS has no python's types `int`, `float`, ...
|
||||
- Use string-typed names: `.add_argument('-b', { type: 'int', help: 'help' })`.
|
||||
- `%r` format specifier uses `require('util').inspect()`.
|
||||
|
||||
More details in [doc](./doc).
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
`test.js` file:
|
||||
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
const { ArgumentParser } = require('argparse');
|
||||
const { version } = require('./package.json');
|
||||
|
||||
const parser = new ArgumentParser({
|
||||
description: 'Argparse example'
|
||||
});
|
||||
|
||||
parser.add_argument('-v', '--version', { action: 'version', version });
|
||||
parser.add_argument('-f', '--foo', { help: 'foo bar' });
|
||||
parser.add_argument('-b', '--bar', { help: 'bar foo' });
|
||||
parser.add_argument('--baz', { help: 'baz bar' });
|
||||
|
||||
console.dir(parser.parse_args());
|
||||
```
|
||||
|
||||
Display help:
|
||||
|
||||
```
|
||||
$ ./test.js -h
|
||||
usage: test.js [-h] [-v] [-f FOO] [-b BAR] [--baz BAZ]
|
||||
|
||||
Argparse example
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-v, --version show program's version number and exit
|
||||
-f FOO, --foo FOO foo bar
|
||||
-b BAR, --bar BAR bar foo
|
||||
--baz BAZ baz bar
|
||||
```
|
||||
|
||||
Parse arguments:
|
||||
|
||||
```
|
||||
$ ./test.js -f=3 --bar=4 --baz 5
|
||||
{ foo: '3', bar: '4', baz: '5' }
|
||||
```
|
||||
|
||||
|
||||
API docs
|
||||
--------
|
||||
|
||||
Since this is a port with minimal divergence, there's no separate documentation.
|
||||
Use original one instead, with notes about difference.
|
||||
|
||||
1. [Original doc](https://docs.python.org/3.9/library/argparse.html).
|
||||
2. [Original tutorial](https://docs.python.org/3.9/howto/argparse.html).
|
||||
3. [Difference with python](./doc).
|
||||
|
||||
|
||||
argparse for enterprise
|
||||
-----------------------
|
||||
|
||||
Available as part of the Tidelift Subscription
|
||||
|
||||
The maintainers of argparse and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-argparse?utm_source=npm-argparse&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
3707
node_modules/lv_font_conv/node_modules/argparse/argparse.js
generated
vendored
67
node_modules/lv_font_conv/node_modules/argparse/lib/sub.js
generated
vendored
@ -1,67 +0,0 @@
|
||||
// Limited implementation of python % string operator, supports only %s and %r for now
|
||||
// (other formats are not used here, but may appear in custom templates)
|
||||
|
||||
'use strict'
|
||||
|
||||
const { inspect } = require('util')
|
||||
|
||||
|
||||
module.exports = function sub(pattern, ...values) {
|
||||
let regex = /%(?:(%)|(-)?(\*)?(?:\((\w+)\))?([A-Za-z]))/g
|
||||
|
||||
let result = pattern.replace(regex, function (_, is_literal, is_left_align, is_padded, name, format) {
|
||||
if (is_literal) return '%'
|
||||
|
||||
let padded_count = 0
|
||||
if (is_padded) {
|
||||
if (values.length === 0) throw new TypeError('not enough arguments for format string')
|
||||
padded_count = values.shift()
|
||||
if (!Number.isInteger(padded_count)) throw new TypeError('* wants int')
|
||||
}
|
||||
|
||||
let str
|
||||
if (name !== undefined) {
|
||||
let dict = values[0]
|
||||
if (typeof dict !== 'object' || dict === null) throw new TypeError('format requires a mapping')
|
||||
if (!(name in dict)) throw new TypeError(`no such key: '${name}'`)
|
||||
str = dict[name]
|
||||
} else {
|
||||
if (values.length === 0) throw new TypeError('not enough arguments for format string')
|
||||
str = values.shift()
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case 's':
|
||||
str = String(str)
|
||||
break
|
||||
case 'r':
|
||||
str = inspect(str)
|
||||
break
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (typeof str !== 'number') {
|
||||
throw new TypeError(`%${format} format: a number is required, not ${typeof str}`)
|
||||
}
|
||||
str = String(str.toFixed(0))
|
||||
break
|
||||
default:
|
||||
throw new TypeError(`unsupported format character '${format}'`)
|
||||
}
|
||||
|
||||
if (padded_count > 0) {
|
||||
return is_left_align ? str.padEnd(padded_count) : str.padStart(padded_count)
|
||||
} else {
|
||||
return str
|
||||
}
|
||||
})
|
||||
|
||||
if (values.length) {
|
||||
if (values.length === 1 && typeof values[0] === 'object' && values[0] !== null) {
|
||||
// mapping
|
||||
} else {
|
||||
throw new TypeError('not all arguments converted during string formatting')
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
440
node_modules/lv_font_conv/node_modules/argparse/lib/textwrap.js
generated
vendored
@ -1,440 +0,0 @@
|
||||
// Partial port of python's argparse module, version 3.9.0 (only wrap and fill functions):
|
||||
// https://github.com/python/cpython/blob/v3.9.0b4/Lib/textwrap.py
|
||||
|
||||
'use strict'
|
||||
|
||||
/*
|
||||
* Text wrapping and filling.
|
||||
*/
|
||||
|
||||
// Copyright (C) 1999-2001 Gregory P. Ward.
|
||||
// Copyright (C) 2002, 2003 Python Software Foundation.
|
||||
// Copyright (C) 2020 argparse.js authors
|
||||
// Originally written by Greg Ward <gward@python.net>
|
||||
|
||||
// Hardcode the recognized whitespace characters to the US-ASCII
|
||||
// whitespace characters. The main reason for doing this is that
|
||||
// some Unicode spaces (like \u00a0) are non-breaking whitespaces.
|
||||
//
|
||||
// This less funky little regex just split on recognized spaces. E.g.
|
||||
// "Hello there -- you goof-ball, use the -b option!"
|
||||
// splits into
|
||||
// Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/
|
||||
const wordsep_simple_re = /([\t\n\x0b\x0c\r ]+)/
|
||||
|
||||
class TextWrapper {
|
||||
/*
|
||||
* Object for wrapping/filling text. The public interface consists of
|
||||
* the wrap() and fill() methods; the other methods are just there for
|
||||
* subclasses to override in order to tweak the default behaviour.
|
||||
* If you want to completely replace the main wrapping algorithm,
|
||||
* you'll probably have to override _wrap_chunks().
|
||||
*
|
||||
* Several instance attributes control various aspects of wrapping:
|
||||
* width (default: 70)
|
||||
* the maximum width of wrapped lines (unless break_long_words
|
||||
* is false)
|
||||
* initial_indent (default: "")
|
||||
* string that will be prepended to the first line of wrapped
|
||||
* output. Counts towards the line's width.
|
||||
* subsequent_indent (default: "")
|
||||
* string that will be prepended to all lines save the first
|
||||
* of wrapped output; also counts towards each line's width.
|
||||
* expand_tabs (default: true)
|
||||
* Expand tabs in input text to spaces before further processing.
|
||||
* Each tab will become 0 .. 'tabsize' spaces, depending on its position
|
||||
* in its line. If false, each tab is treated as a single character.
|
||||
* tabsize (default: 8)
|
||||
* Expand tabs in input text to 0 .. 'tabsize' spaces, unless
|
||||
* 'expand_tabs' is false.
|
||||
* replace_whitespace (default: true)
|
||||
* Replace all whitespace characters in the input text by spaces
|
||||
* after tab expansion. Note that if expand_tabs is false and
|
||||
* replace_whitespace is true, every tab will be converted to a
|
||||
* single space!
|
||||
* fix_sentence_endings (default: false)
|
||||
* Ensure that sentence-ending punctuation is always followed
|
||||
* by two spaces. Off by default because the algorithm is
|
||||
* (unavoidably) imperfect.
|
||||
* break_long_words (default: true)
|
||||
* Break words longer than 'width'. If false, those words will not
|
||||
* be broken, and some lines might be longer than 'width'.
|
||||
* break_on_hyphens (default: true)
|
||||
* Allow breaking hyphenated words. If true, wrapping will occur
|
||||
* preferably on whitespaces and right after hyphens part of
|
||||
* compound words.
|
||||
* drop_whitespace (default: true)
|
||||
* Drop leading and trailing whitespace from lines.
|
||||
* max_lines (default: None)
|
||||
* Truncate wrapped lines.
|
||||
* placeholder (default: ' [...]')
|
||||
* Append to the last line of truncated text.
|
||||
*/
|
||||
|
||||
constructor(options = {}) {
|
||||
let {
|
||||
width = 70,
|
||||
initial_indent = '',
|
||||
subsequent_indent = '',
|
||||
expand_tabs = true,
|
||||
replace_whitespace = true,
|
||||
fix_sentence_endings = false,
|
||||
break_long_words = true,
|
||||
drop_whitespace = true,
|
||||
break_on_hyphens = true,
|
||||
tabsize = 8,
|
||||
max_lines = undefined,
|
||||
placeholder=' [...]'
|
||||
} = options
|
||||
|
||||
this.width = width
|
||||
this.initial_indent = initial_indent
|
||||
this.subsequent_indent = subsequent_indent
|
||||
this.expand_tabs = expand_tabs
|
||||
this.replace_whitespace = replace_whitespace
|
||||
this.fix_sentence_endings = fix_sentence_endings
|
||||
this.break_long_words = break_long_words
|
||||
this.drop_whitespace = drop_whitespace
|
||||
this.break_on_hyphens = break_on_hyphens
|
||||
this.tabsize = tabsize
|
||||
this.max_lines = max_lines
|
||||
this.placeholder = placeholder
|
||||
}
|
||||
|
||||
|
||||
// -- Private methods -----------------------------------------------
|
||||
// (possibly useful for subclasses to override)
|
||||
|
||||
_munge_whitespace(text) {
|
||||
/*
|
||||
* _munge_whitespace(text : string) -> string
|
||||
*
|
||||
* Munge whitespace in text: expand tabs and convert all other
|
||||
* whitespace characters to spaces. Eg. " foo\\tbar\\n\\nbaz"
|
||||
* becomes " foo bar baz".
|
||||
*/
|
||||
if (this.expand_tabs) {
|
||||
text = text.replace(/\t/g, ' '.repeat(this.tabsize)) // not strictly correct in js
|
||||
}
|
||||
if (this.replace_whitespace) {
|
||||
text = text.replace(/[\t\n\x0b\x0c\r]/g, ' ')
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
_split(text) {
|
||||
/*
|
||||
* _split(text : string) -> [string]
|
||||
*
|
||||
* Split the text to wrap into indivisible chunks. Chunks are
|
||||
* not quite the same as words; see _wrap_chunks() for full
|
||||
* details. As an example, the text
|
||||
* Look, goof-ball -- use the -b option!
|
||||
* breaks into the following chunks:
|
||||
* 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
|
||||
* 'use', ' ', 'the', ' ', '-b', ' ', 'option!'
|
||||
* if break_on_hyphens is True, or in:
|
||||
* 'Look,', ' ', 'goof-ball', ' ', '--', ' ',
|
||||
* 'use', ' ', 'the', ' ', '-b', ' ', option!'
|
||||
* otherwise.
|
||||
*/
|
||||
let chunks = text.split(wordsep_simple_re)
|
||||
chunks = chunks.filter(Boolean)
|
||||
return chunks
|
||||
}
|
||||
|
||||
_handle_long_word(reversed_chunks, cur_line, cur_len, width) {
|
||||
/*
|
||||
* _handle_long_word(chunks : [string],
|
||||
* cur_line : [string],
|
||||
* cur_len : int, width : int)
|
||||
*
|
||||
* Handle a chunk of text (most likely a word, not whitespace) that
|
||||
* is too long to fit in any line.
|
||||
*/
|
||||
// Figure out when indent is larger than the specified width, and make
|
||||
// sure at least one character is stripped off on every pass
|
||||
let space_left
|
||||
if (width < 1) {
|
||||
space_left = 1
|
||||
} else {
|
||||
space_left = width - cur_len
|
||||
}
|
||||
|
||||
// If we're allowed to break long words, then do so: put as much
|
||||
// of the next chunk onto the current line as will fit.
|
||||
if (this.break_long_words) {
|
||||
cur_line.push(reversed_chunks[reversed_chunks.length - 1].slice(0, space_left))
|
||||
reversed_chunks[reversed_chunks.length - 1] = reversed_chunks[reversed_chunks.length - 1].slice(space_left)
|
||||
|
||||
// Otherwise, we have to preserve the long word intact. Only add
|
||||
// it to the current line if there's nothing already there --
|
||||
// that minimizes how much we violate the width constraint.
|
||||
} else if (!cur_line) {
|
||||
cur_line.push(...reversed_chunks.pop())
|
||||
}
|
||||
|
||||
// If we're not allowed to break long words, and there's already
|
||||
// text on the current line, do nothing. Next time through the
|
||||
// main loop of _wrap_chunks(), we'll wind up here again, but
|
||||
// cur_len will be zero, so the next line will be entirely
|
||||
// devoted to the long word that we can't handle right now.
|
||||
}
|
||||
|
||||
_wrap_chunks(chunks) {
|
||||
/*
|
||||
* _wrap_chunks(chunks : [string]) -> [string]
|
||||
*
|
||||
* Wrap a sequence of text chunks and return a list of lines of
|
||||
* length 'self.width' or less. (If 'break_long_words' is false,
|
||||
* some lines may be longer than this.) Chunks correspond roughly
|
||||
* to words and the whitespace between them: each chunk is
|
||||
* indivisible (modulo 'break_long_words'), but a line break can
|
||||
* come between any two chunks. Chunks should not have internal
|
||||
* whitespace; ie. a chunk is either all whitespace or a "word".
|
||||
* Whitespace chunks will be removed from the beginning and end of
|
||||
* lines, but apart from that whitespace is preserved.
|
||||
*/
|
||||
let lines = []
|
||||
let indent
|
||||
if (this.width <= 0) {
|
||||
throw Error(`invalid width ${this.width} (must be > 0)`)
|
||||
}
|
||||
if (this.max_lines !== undefined) {
|
||||
if (this.max_lines > 1) {
|
||||
indent = this.subsequent_indent
|
||||
} else {
|
||||
indent = this.initial_indent
|
||||
}
|
||||
if (indent.length + this.placeholder.trimStart().length > this.width) {
|
||||
throw Error('placeholder too large for max width')
|
||||
}
|
||||
}
|
||||
|
||||
// Arrange in reverse order so items can be efficiently popped
|
||||
// from a stack of chucks.
|
||||
chunks = chunks.reverse()
|
||||
|
||||
while (chunks.length > 0) {
|
||||
|
||||
// Start the list of chunks that will make up the current line.
|
||||
// cur_len is just the length of all the chunks in cur_line.
|
||||
let cur_line = []
|
||||
let cur_len = 0
|
||||
|
||||
// Figure out which static string will prefix this line.
|
||||
let indent
|
||||
if (lines) {
|
||||
indent = this.subsequent_indent
|
||||
} else {
|
||||
indent = this.initial_indent
|
||||
}
|
||||
|
||||
// Maximum width for this line.
|
||||
let width = this.width - indent.length
|
||||
|
||||
// First chunk on line is whitespace -- drop it, unless this
|
||||
// is the very beginning of the text (ie. no lines started yet).
|
||||
if (this.drop_whitespace && chunks[chunks.length - 1].trim() === '' && lines.length > 0) {
|
||||
chunks.pop()
|
||||
}
|
||||
|
||||
while (chunks.length > 0) {
|
||||
let l = chunks[chunks.length - 1].length
|
||||
|
||||
// Can at least squeeze this chunk onto the current line.
|
||||
if (cur_len + l <= width) {
|
||||
cur_line.push(chunks.pop())
|
||||
cur_len += l
|
||||
|
||||
// Nope, this line is full.
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// The current line is full, and the next chunk is too big to
|
||||
// fit on *any* line (not just this one).
|
||||
if (chunks.length && chunks[chunks.length - 1].length > width) {
|
||||
this._handle_long_word(chunks, cur_line, cur_len, width)
|
||||
cur_len = cur_line.map(l => l.length).reduce((a, b) => a + b, 0)
|
||||
}
|
||||
|
||||
// If the last chunk on this line is all whitespace, drop it.
|
||||
if (this.drop_whitespace && cur_line.length > 0 && cur_line[cur_line.length - 1].trim() === '') {
|
||||
cur_len -= cur_line[cur_line.length - 1].length
|
||||
cur_line.pop()
|
||||
}
|
||||
|
||||
if (cur_line) {
|
||||
if (this.max_lines === undefined ||
|
||||
lines.length + 1 < this.max_lines ||
|
||||
(chunks.length === 0 ||
|
||||
this.drop_whitespace &&
|
||||
chunks.length === 1 &&
|
||||
!chunks[0].trim()) && cur_len <= width) {
|
||||
// Convert current line back to a string and store it in
|
||||
// list of all lines (return value).
|
||||
lines.push(indent + cur_line.join(''))
|
||||
} else {
|
||||
let had_break = false
|
||||
while (cur_line) {
|
||||
if (cur_line[cur_line.length - 1].trim() &&
|
||||
cur_len + this.placeholder.length <= width) {
|
||||
cur_line.push(this.placeholder)
|
||||
lines.push(indent + cur_line.join(''))
|
||||
had_break = true
|
||||
break
|
||||
}
|
||||
cur_len -= cur_line[-1].length
|
||||
cur_line.pop()
|
||||
}
|
||||
if (!had_break) {
|
||||
if (lines) {
|
||||
let prev_line = lines[lines.length - 1].trimEnd()
|
||||
if (prev_line.length + this.placeholder.length <=
|
||||
this.width) {
|
||||
lines[lines.length - 1] = prev_line + this.placeholder
|
||||
break
|
||||
}
|
||||
}
|
||||
lines.push(indent + this.placeholder.lstrip())
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
_split_chunks(text) {
|
||||
text = this._munge_whitespace(text)
|
||||
return this._split(text)
|
||||
}
|
||||
|
||||
// -- Public interface ----------------------------------------------
|
||||
|
||||
wrap(text) {
|
||||
/*
|
||||
* wrap(text : string) -> [string]
|
||||
*
|
||||
* Reformat the single paragraph in 'text' so it fits in lines of
|
||||
* no more than 'self.width' columns, and return a list of wrapped
|
||||
* lines. Tabs in 'text' are expanded with string.expandtabs(),
|
||||
* and all other whitespace characters (including newline) are
|
||||
* converted to space.
|
||||
*/
|
||||
let chunks = this._split_chunks(text)
|
||||
// not implemented in js
|
||||
//if (this.fix_sentence_endings) {
|
||||
// this._fix_sentence_endings(chunks)
|
||||
//}
|
||||
return this._wrap_chunks(chunks)
|
||||
}
|
||||
|
||||
fill(text) {
|
||||
/*
|
||||
* fill(text : string) -> string
|
||||
*
|
||||
* Reformat the single paragraph in 'text' to fit in lines of no
|
||||
* more than 'self.width' columns, and return a new string
|
||||
* containing the entire wrapped paragraph.
|
||||
*/
|
||||
return this.wrap(text).join('\n')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Convenience interface ---------------------------------------------
|
||||
|
||||
function wrap(text, options = {}) {
|
||||
/*
|
||||
* Wrap a single paragraph of text, returning a list of wrapped lines.
|
||||
*
|
||||
* Reformat the single paragraph in 'text' so it fits in lines of no
|
||||
* more than 'width' columns, and return a list of wrapped lines. By
|
||||
* default, tabs in 'text' are expanded with string.expandtabs(), and
|
||||
* all other whitespace characters (including newline) are converted to
|
||||
* space. See TextWrapper class for available keyword args to customize
|
||||
* wrapping behaviour.
|
||||
*/
|
||||
let { width = 70, ...kwargs } = options
|
||||
let w = new TextWrapper(Object.assign({ width }, kwargs))
|
||||
return w.wrap(text)
|
||||
}
|
||||
|
||||
function fill(text, options = {}) {
|
||||
/*
|
||||
* Fill a single paragraph of text, returning a new string.
|
||||
*
|
||||
* Reformat the single paragraph in 'text' to fit in lines of no more
|
||||
* than 'width' columns, and return a new string containing the entire
|
||||
* wrapped paragraph. As with wrap(), tabs are expanded and other
|
||||
* whitespace characters converted to space. See TextWrapper class for
|
||||
* available keyword args to customize wrapping behaviour.
|
||||
*/
|
||||
let { width = 70, ...kwargs } = options
|
||||
let w = new TextWrapper(Object.assign({ width }, kwargs))
|
||||
return w.fill(text)
|
||||
}
|
||||
|
||||
// -- Loosely related functionality -------------------------------------
|
||||
|
||||
let _whitespace_only_re = /^[ \t]+$/mg
|
||||
let _leading_whitespace_re = /(^[ \t]*)(?:[^ \t\n])/mg
|
||||
|
||||
function dedent(text) {
|
||||
/*
|
||||
* Remove any common leading whitespace from every line in `text`.
|
||||
*
|
||||
* This can be used to make triple-quoted strings line up with the left
|
||||
* edge of the display, while still presenting them in the source code
|
||||
* in indented form.
|
||||
*
|
||||
* Note that tabs and spaces are both treated as whitespace, but they
|
||||
* are not equal: the lines " hello" and "\\thello" are
|
||||
* considered to have no common leading whitespace.
|
||||
*
|
||||
* Entirely blank lines are normalized to a newline character.
|
||||
*/
|
||||
// Look for the longest leading string of spaces and tabs common to
|
||||
// all lines.
|
||||
let margin = undefined
|
||||
text = text.replace(_whitespace_only_re, '')
|
||||
let indents = text.match(_leading_whitespace_re) || []
|
||||
for (let indent of indents) {
|
||||
indent = indent.slice(0, -1)
|
||||
|
||||
if (margin === undefined) {
|
||||
margin = indent
|
||||
|
||||
// Current line more deeply indented than previous winner:
|
||||
// no change (previous winner is still on top).
|
||||
} else if (indent.startsWith(margin)) {
|
||||
// pass
|
||||
|
||||
// Current line consistent with and no deeper than previous winner:
|
||||
// it's the new winner.
|
||||
} else if (margin.startsWith(indent)) {
|
||||
margin = indent
|
||||
|
||||
// Find the largest common whitespace between current line and previous
|
||||
// winner.
|
||||
} else {
|
||||
for (let i = 0; i < margin.length && i < indent.length; i++) {
|
||||
if (margin[i] !== indent[i]) {
|
||||
margin = margin.slice(0, i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (margin) {
|
||||
text = text.replace(new RegExp('^' + margin, 'mg'), '')
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
module.exports = { wrap, fill, dedent }
|
67
node_modules/lv_font_conv/node_modules/argparse/package.json
generated
vendored
@ -1,67 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"argparse@2.0.1",
|
||||
"/home/vitaly/Dropbox/Coding/lv_font_conv"
|
||||
]
|
||||
],
|
||||
"_from": "argparse@2.0.1",
|
||||
"_id": "argparse@2.0.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"_location": "/argparse",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "argparse@2.0.1",
|
||||
"name": "argparse",
|
||||
"escapedName": "argparse",
|
||||
"rawSpec": "2.0.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.0.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/",
|
||||
"/mocha/js-yaml"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"_spec": "2.0.1",
|
||||
"_where": "/home/vitaly/Dropbox/Coding/lv_font_conv",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nodeca/argparse/issues"
|
||||
},
|
||||
"description": "CLI arguments parser. Native port of python's argparse.",
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.11.0",
|
||||
"@babel/plugin-syntax-class-properties": "^7.10.4",
|
||||
"eslint": "^7.5.0",
|
||||
"mocha": "^8.0.1",
|
||||
"nyc": "^15.1.0"
|
||||
},
|
||||
"files": [
|
||||
"argparse.js",
|
||||
"lib/"
|
||||
],
|
||||
"homepage": "https://github.com/nodeca/argparse#readme",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"parser",
|
||||
"argparse",
|
||||
"option",
|
||||
"args"
|
||||
],
|
||||
"license": "Python-2.0",
|
||||
"main": "argparse.js",
|
||||
"name": "argparse",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nodeca/argparse.git"
|
||||
},
|
||||
"scripts": {
|
||||
"coverage": "npm run test && nyc report --reporter html",
|
||||
"lint": "eslint .",
|
||||
"test": "npm run lint && nyc mocha"
|
||||
},
|
||||
"version": "2.0.1"
|
||||
}
|
36
node_modules/lv_font_conv/node_modules/bit-buffer/.github/workflows/ci.yml
generated
vendored
@ -1,36 +0,0 @@
|
||||
name: Node.js CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 15.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 15.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
21
node_modules/lv_font_conv/node_modules/bit-buffer/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 bit-buffer developers
|
||||
|
||||
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.
|
148
node_modules/lv_font_conv/node_modules/bit-buffer/README.md
generated
vendored
@ -1,148 +0,0 @@
|
||||
# BitBuffer
|
||||
|
||||
![Node.js CI](https://github.com/inolen/bit-buffer/workflows/Node.js%20CI/badge.svg)
|
||||
|
||||
BitBuffer provides two objects, `BitView` and `BitStream`. `BitView` is a wrapper for ArrayBuffers, similar to JavaScript's [DataView](https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays/DataView), but with support for bit-level reads and writes. `BitStream` is a wrapper for a `BitView` used to help maintain your current buffer position, as well as to provide higher-level read / write operations such as for ASCII strings.
|
||||
|
||||
## BitView
|
||||
|
||||
### Attributes
|
||||
|
||||
```javascript
|
||||
bb.buffer // Underlying ArrayBuffer.
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.bigEndian = true; // Switch to big endian (default is little)
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### BitView(buffer, optional byteOffset, optional byteLength)
|
||||
|
||||
Default constructor, takes in a single argument of an ArrayBuffer. Optional are the `byteOffset` and `byteLength` arguments to offset and truncate the view's representation of the buffer.
|
||||
|
||||
### getBits(offset, bits, signed)
|
||||
|
||||
Reads `bits` number of bits starting at `offset`, twiddling the bits appropriately to return a proper 32-bit signed or unsigned value. NOTE: While JavaScript numbers are 64-bit floating-point values, we don't bother with anything other than the first 32 bits.
|
||||
|
||||
### getInt8, getUint8, getInt16, getUint16, getInt32, getUint32(offset)
|
||||
|
||||
Shortcuts for getBits, setting the correct `bits` / `signed` values.
|
||||
|
||||
### getFloat32(offset)
|
||||
|
||||
Gets 32 bits from `offset`, and coerces and returns as a proper float32 value.
|
||||
|
||||
### getFloat64(offset)
|
||||
|
||||
Gets 64 bits from `offset`, and coerces and returns as a proper float64 value.
|
||||
|
||||
### setBits(offset, value, bits)
|
||||
|
||||
Sets `bits` number of bits at `offset`.
|
||||
|
||||
### setInt8, setUint8, setInt16, setUint16, setInt32, setUint32(offset)
|
||||
|
||||
Shortcuts for setBits, setting the correct `bits` count.
|
||||
|
||||
### setFloat32(offset)
|
||||
|
||||
Coerces a float32 to uint32 and sets at `offset`.
|
||||
|
||||
### setFloat64(offset)
|
||||
|
||||
Coerces a float64 to two uint32s and sets at `offset`.
|
||||
|
||||
|
||||
## BitStream
|
||||
|
||||
### Attributes
|
||||
|
||||
```javascript
|
||||
bb.byteIndex; // Get current index in bytes.
|
||||
bb.byteIndex = 0; // Set current index in bytes.
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.view; // Underlying BitView
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.length; // Get the length of the stream in bits
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.bitsLeft; // The number of bits left in the stream
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.index; // Get the current index in bits
|
||||
bb.index = 0// Set the current index in bits
|
||||
```
|
||||
|
||||
```javascript
|
||||
bb.bigEndian = true; // Switch to big endian (default is little)
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### BitStream(view)
|
||||
|
||||
Default constructor, takes in a single argument of a `BitView`, `ArrayBuffer` or node `Buffer`.
|
||||
|
||||
#### BitSteam(buffer, optional byteOffset, optional byteLength)
|
||||
|
||||
Shortcut constructor that initializes a new `BitView(buffer, byteOffset, byteLength)` for the stream to use.
|
||||
|
||||
#### readBits(bits, signed)
|
||||
|
||||
Returns `bits` numbers of bits from the view at the current index, updating the index.
|
||||
|
||||
#### writeBits(value, bits)
|
||||
|
||||
Sets `bits` numbers of bits from `value` in the view at the current index, updating the index.
|
||||
|
||||
#### readUint8(), readUint16(), readUint32(), readInt8(), readInt16(), readInt32()
|
||||
|
||||
Read a 8, 16 or 32 bits (unsigned) integer at the current index, updating the index.
|
||||
|
||||
#### writeUint8(value), writeUint16(value), writeUint32(value), writeInt8(value), writeInt16(value), writeInt32(value)
|
||||
|
||||
Write 8, 16 or 32 bits from `value` as (unsigned) integer at the current index, updating the index.
|
||||
|
||||
#### readFloat32(), readFloat64()
|
||||
|
||||
Read a 32 or 64 bit floating point number at the current index, updating the index.
|
||||
|
||||
#### writeFloat32(value), writeFloat64()
|
||||
|
||||
Set 32 or 64 bits from `value` as floating point value at the current index, updating the index.
|
||||
|
||||
#### readBoolean()
|
||||
|
||||
Read a single bit from the view at the current index, updating the index.
|
||||
|
||||
#### writeBoolean(value)
|
||||
|
||||
Write a single bit to the view at the current index, updating the index.
|
||||
|
||||
#### readASCIIString(optional bytes), readUTF8String(optional bytes)
|
||||
|
||||
Reads bytes from the underlying view at the current index until either `bytes` count is reached or a 0x00 terminator is reached.
|
||||
|
||||
#### writeASCIIString(string, optional bytes), writeUTF8String(string, optional bytes)
|
||||
|
||||
Writes a string followed by a NULL character to the underlying view starting at the current index. If the string is longer than `bytes` it will be truncated, and if it is shorter 0x00 will be written in its place.
|
||||
|
||||
#### readBitStream(length)
|
||||
|
||||
Create a new `BitStream` from the underlying view starting the the current index and a length of `length` bits. Updating the index of the existing `BitStream`
|
||||
|
||||
#### readArrayBuffer(byteLength)
|
||||
|
||||
Read `byteLength` bytes of data from the underlying view as `ArrayBuffer`, updating the index.
|
||||
|
||||
## license
|
||||
|
||||
MIT
|
115
node_modules/lv_font_conv/node_modules/bit-buffer/bit-buffer.d.ts
generated
vendored
@ -1,115 +0,0 @@
|
||||
declare module 'bit-buffer' {
|
||||
import {Buffer} from 'buffer';
|
||||
|
||||
export class BitView {
|
||||
constructor(buffer: ArrayBuffer | Buffer, byteLength?: number);
|
||||
|
||||
readonly buffer: Buffer;
|
||||
readonly byteLength: number;
|
||||
bigEndian: boolean;
|
||||
|
||||
getBits(offset: number, bits: number, signed?: boolean): number;
|
||||
|
||||
getInt8(offset: number): number;
|
||||
|
||||
getInt16(offset: number): number;
|
||||
|
||||
getInt32(offset: number): number;
|
||||
|
||||
getUint8(offset: number): number;
|
||||
|
||||
getUint16(offset: number): number;
|
||||
|
||||
getUint32(offset: number): number;
|
||||
|
||||
getFloat32(offset: number): number;
|
||||
|
||||
getFloat64(offset: number): number;
|
||||
|
||||
setBits(offset: number, value: number, bits: number);
|
||||
|
||||
setInt8(offset: number);
|
||||
|
||||
setInt16(offset: number);
|
||||
|
||||
setInt32(offset: number);
|
||||
|
||||
setUint8(offset: number);
|
||||
|
||||
setUint16(offset: number);
|
||||
|
||||
setUint32(offset: number);
|
||||
|
||||
setFloat32(offset: number, value: number);
|
||||
|
||||
setFloat64(offset: number, value: number);
|
||||
}
|
||||
|
||||
export class BitStream {
|
||||
constructor(source: ArrayBuffer | Buffer | BitView, byteOffset?: number, byteLength?: number)
|
||||
|
||||
readonly length: number;
|
||||
readonly bitsLeft: number;
|
||||
readonly buffer: Buffer;
|
||||
readonly view: BitView;
|
||||
byteIndex: number;
|
||||
index: number;
|
||||
bigEndian: boolean;
|
||||
|
||||
readBits(bits: number, signed?: boolean): number;
|
||||
|
||||
writeBits(value: number, bits: number);
|
||||
|
||||
readBoolean(): boolean;
|
||||
|
||||
readInt8(): number;
|
||||
|
||||
readUint8(): number;
|
||||
|
||||
readInt16(): number;
|
||||
|
||||
readUint16(): number;
|
||||
|
||||
readInt32(): number;
|
||||
|
||||
readUint32(): number;
|
||||
|
||||
readFloat32(): number;
|
||||
|
||||
readFloat64(): number;
|
||||
|
||||
writeBoolean(value: boolean);
|
||||
|
||||
writeInt8(value: number);
|
||||
|
||||
writeUint8(value: number);
|
||||
|
||||
writeInt16(value: number);
|
||||
|
||||
writeUint16(value: number);
|
||||
|
||||
writeInt32(value: number);
|
||||
|
||||
writeUint32(value: number);
|
||||
|
||||
writeFloat32(value: number);
|
||||
|
||||
writeFloat64(value: number);
|
||||
|
||||
readASCIIString(length?: number): string;
|
||||
|
||||
readUTF8String(length?: number): string;
|
||||
|
||||
writeASCIIString(data: string, length?: number);
|
||||
|
||||
writeUTF8String(data: string, length?: number);
|
||||
|
||||
readBitStream(length: number): BitStream;
|
||||
|
||||
readArrayBuffer(byteLength: number): Uint8Array;
|
||||
|
||||
writeBitStream(stream: BitStream, length?: number);
|
||||
|
||||
writeArrayBuffer(buffer: BitStream, length?: number);
|
||||
}
|
||||
}
|
502
node_modules/lv_font_conv/node_modules/bit-buffer/bit-buffer.js
generated
vendored
@ -1,502 +0,0 @@
|
||||
(function (root) {
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* BitView
|
||||
*
|
||||
* BitView provides a similar interface to the standard
|
||||
* DataView, but with support for bit-level reads / writes.
|
||||
*
|
||||
**********************************************************/
|
||||
var BitView = function (source, byteOffset, byteLength) {
|
||||
var isBuffer = source instanceof ArrayBuffer ||
|
||||
(typeof Buffer !== 'undefined' && source instanceof Buffer);
|
||||
|
||||
if (!isBuffer) {
|
||||
throw new Error('Must specify a valid ArrayBuffer or Buffer.');
|
||||
}
|
||||
|
||||
byteOffset = byteOffset || 0;
|
||||
byteLength = byteLength || source.byteLength /* ArrayBuffer */ || source.length /* Buffer */;
|
||||
|
||||
this._view = new Uint8Array(source.buffer || source, byteOffset, byteLength);
|
||||
|
||||
this.bigEndian = false;
|
||||
};
|
||||
|
||||
// Used to massage fp values so we can operate on them
|
||||
// at the bit level.
|
||||
BitView._scratch = new DataView(new ArrayBuffer(8));
|
||||
|
||||
Object.defineProperty(BitView.prototype, 'buffer', {
|
||||
get: function () { return typeof Buffer !== 'undefined' ? Buffer.from(this._view.buffer) : this._view.buffer; },
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
Object.defineProperty(BitView.prototype, 'byteLength', {
|
||||
get: function () { return this._view.length; },
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
BitView.prototype._setBit = function (offset, on) {
|
||||
if (on) {
|
||||
this._view[offset >> 3] |= 1 << (offset & 7);
|
||||
} else {
|
||||
this._view[offset >> 3] &= ~(1 << (offset & 7));
|
||||
}
|
||||
};
|
||||
|
||||
BitView.prototype.getBits = function (offset, bits, signed) {
|
||||
var available = (this._view.length * 8 - offset);
|
||||
|
||||
if (bits > available) {
|
||||
throw new Error('Cannot get ' + bits + ' bit(s) from offset ' + offset + ', ' + available + ' available');
|
||||
}
|
||||
|
||||
var value = 0;
|
||||
for (var i = 0; i < bits;) {
|
||||
var remaining = bits - i;
|
||||
var bitOffset = offset & 7;
|
||||
var currentByte = this._view[offset >> 3];
|
||||
|
||||
// the max number of bits we can read from the current byte
|
||||
var read = Math.min(remaining, 8 - bitOffset);
|
||||
|
||||
var mask, readBits;
|
||||
if (this.bigEndian) {
|
||||
// create a mask with the correct bit width
|
||||
mask = ~(0xFF << read);
|
||||
// shift the bits we want to the start of the byte and mask of the rest
|
||||
readBits = (currentByte >> (8 - read - bitOffset)) & mask;
|
||||
|
||||
value <<= read;
|
||||
value |= readBits;
|
||||
} else {
|
||||
// create a mask with the correct bit width
|
||||
mask = ~(0xFF << read);
|
||||
// shift the bits we want to the start of the byte and mask off the rest
|
||||
readBits = (currentByte >> bitOffset) & mask;
|
||||
|
||||
value |= readBits << i;
|
||||
}
|
||||
|
||||
offset += read;
|
||||
i += read;
|
||||
}
|
||||
|
||||
if (signed) {
|
||||
// If we're not working with a full 32 bits, check the
|
||||
// imaginary MSB for this bit count and convert to a
|
||||
// valid 32-bit signed value if set.
|
||||
if (bits !== 32 && value & (1 << (bits - 1))) {
|
||||
value |= -1 ^ ((1 << bits) - 1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return value >>> 0;
|
||||
};
|
||||
|
||||
BitView.prototype.setBits = function (offset, value, bits) {
|
||||
var available = (this._view.length * 8 - offset);
|
||||
|
||||
if (bits > available) {
|
||||
throw new Error('Cannot set ' + bits + ' bit(s) from offset ' + offset + ', ' + available + ' available');
|
||||
}
|
||||
|
||||
for (var i = 0; i < bits;) {
|
||||
var remaining = bits - i;
|
||||
var bitOffset = offset & 7;
|
||||
var byteOffset = offset >> 3;
|
||||
var wrote = Math.min(remaining, 8 - bitOffset);
|
||||
|
||||
var mask, writeBits, destMask;
|
||||
if (this.bigEndian) {
|
||||
// create a mask with the correct bit width
|
||||
mask = ~(~0 << wrote);
|
||||
// shift the bits we want to the start of the byte and mask of the rest
|
||||
writeBits = (value >> (bits - i - wrote)) & mask;
|
||||
|
||||
var destShift = 8 - bitOffset - wrote;
|
||||
// destination mask to zero all the bits we're changing first
|
||||
destMask = ~(mask << destShift);
|
||||
|
||||
this._view[byteOffset] =
|
||||
(this._view[byteOffset] & destMask)
|
||||
| (writeBits << destShift);
|
||||
|
||||
} else {
|
||||
// create a mask with the correct bit width
|
||||
mask = ~(0xFF << wrote);
|
||||
// shift the bits we want to the start of the byte and mask of the rest
|
||||
writeBits = value & mask;
|
||||
value >>= wrote;
|
||||
|
||||
// destination mask to zero all the bits we're changing first
|
||||
destMask = ~(mask << bitOffset);
|
||||
|
||||
this._view[byteOffset] =
|
||||
(this._view[byteOffset] & destMask)
|
||||
| (writeBits << bitOffset);
|
||||
}
|
||||
|
||||
offset += wrote;
|
||||
i += wrote;
|
||||
}
|
||||
};
|
||||
|
||||
BitView.prototype.getBoolean = function (offset) {
|
||||
return this.getBits(offset, 1, false) !== 0;
|
||||
};
|
||||
BitView.prototype.getInt8 = function (offset) {
|
||||
return this.getBits(offset, 8, true);
|
||||
};
|
||||
BitView.prototype.getUint8 = function (offset) {
|
||||
return this.getBits(offset, 8, false);
|
||||
};
|
||||
BitView.prototype.getInt16 = function (offset) {
|
||||
return this.getBits(offset, 16, true);
|
||||
};
|
||||
BitView.prototype.getUint16 = function (offset) {
|
||||
return this.getBits(offset, 16, false);
|
||||
};
|
||||
BitView.prototype.getInt32 = function (offset) {
|
||||
return this.getBits(offset, 32, true);
|
||||
};
|
||||
BitView.prototype.getUint32 = function (offset) {
|
||||
return this.getBits(offset, 32, false);
|
||||
};
|
||||
BitView.prototype.getFloat32 = function (offset) {
|
||||
BitView._scratch.setUint32(0, this.getUint32(offset));
|
||||
return BitView._scratch.getFloat32(0);
|
||||
};
|
||||
BitView.prototype.getFloat64 = function (offset) {
|
||||
BitView._scratch.setUint32(0, this.getUint32(offset));
|
||||
// DataView offset is in bytes.
|
||||
BitView._scratch.setUint32(4, this.getUint32(offset+32));
|
||||
return BitView._scratch.getFloat64(0);
|
||||
};
|
||||
|
||||
BitView.prototype.setBoolean = function (offset, value) {
|
||||
this.setBits(offset, value ? 1 : 0, 1);
|
||||
};
|
||||
BitView.prototype.setInt8 =
|
||||
BitView.prototype.setUint8 = function (offset, value) {
|
||||
this.setBits(offset, value, 8);
|
||||
};
|
||||
BitView.prototype.setInt16 =
|
||||
BitView.prototype.setUint16 = function (offset, value) {
|
||||
this.setBits(offset, value, 16);
|
||||
};
|
||||
BitView.prototype.setInt32 =
|
||||
BitView.prototype.setUint32 = function (offset, value) {
|
||||
this.setBits(offset, value, 32);
|
||||
};
|
||||
BitView.prototype.setFloat32 = function (offset, value) {
|
||||
BitView._scratch.setFloat32(0, value);
|
||||
this.setBits(offset, BitView._scratch.getUint32(0), 32);
|
||||
};
|
||||
BitView.prototype.setFloat64 = function (offset, value) {
|
||||
BitView._scratch.setFloat64(0, value);
|
||||
this.setBits(offset, BitView._scratch.getUint32(0), 32);
|
||||
this.setBits(offset+32, BitView._scratch.getUint32(4), 32);
|
||||
};
|
||||
BitView.prototype.getArrayBuffer = function (offset, byteLength) {
|
||||
var buffer = new Uint8Array(byteLength);
|
||||
for (var i = 0; i < byteLength; i++) {
|
||||
buffer[i] = this.getUint8(offset + (i * 8));
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* BitStream
|
||||
*
|
||||
* Small wrapper for a BitView to maintain your position,
|
||||
* as well as to handle reading / writing of string data
|
||||
* to the underlying buffer.
|
||||
*
|
||||
**********************************************************/
|
||||
var reader = function (name, size) {
|
||||
return function () {
|
||||
if (this._index + size > this._length) {
|
||||
throw new Error('Trying to read past the end of the stream');
|
||||
}
|
||||
var val = this._view[name](this._index);
|
||||
this._index += size;
|
||||
return val;
|
||||
};
|
||||
};
|
||||
|
||||
var writer = function (name, size) {
|
||||
return function (value) {
|
||||
this._view[name](this._index, value);
|
||||
this._index += size;
|
||||
};
|
||||
};
|
||||
|
||||
function readASCIIString(stream, bytes) {
|
||||
return readString(stream, bytes, false);
|
||||
}
|
||||
|
||||
function readUTF8String(stream, bytes) {
|
||||
return readString(stream, bytes, true);
|
||||
}
|
||||
|
||||
function readString(stream, bytes, utf8) {
|
||||
if (bytes === 0) {
|
||||
return '';
|
||||
}
|
||||
var i = 0;
|
||||
var chars = [];
|
||||
var append = true;
|
||||
var fixedLength = !!bytes;
|
||||
if (!bytes) {
|
||||
bytes = Math.floor((stream._length - stream._index) / 8);
|
||||
}
|
||||
|
||||
// Read while we still have space available, or until we've
|
||||
// hit the fixed byte length passed in.
|
||||
while (i < bytes) {
|
||||
var c = stream.readUint8();
|
||||
|
||||
// Stop appending chars once we hit 0x00
|
||||
if (c === 0x00) {
|
||||
append = false;
|
||||
|
||||
// If we don't have a fixed length to read, break out now.
|
||||
if (!fixedLength) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (append) {
|
||||
chars.push(c);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
var string = String.fromCharCode.apply(null, chars);
|
||||
if (utf8) {
|
||||
try {
|
||||
return decodeURIComponent(escape(string)); // https://stackoverflow.com/a/17192845
|
||||
} catch (e) {
|
||||
return string;
|
||||
}
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
function writeASCIIString(stream, string, bytes) {
|
||||
var length = bytes || string.length + 1; // + 1 for NULL
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
stream.writeUint8(i < string.length ? string.charCodeAt(i) : 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
function writeUTF8String(stream, string, bytes) {
|
||||
var byteArray = stringToByteArray(string);
|
||||
|
||||
var length = bytes || byteArray.length + 1; // + 1 for NULL
|
||||
for (var i = 0; i < length; i++) {
|
||||
stream.writeUint8(i < byteArray.length ? byteArray[i] : 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
function stringToByteArray(str) { // https://gist.github.com/volodymyr-mykhailyk/2923227
|
||||
var b = [], i, unicode;
|
||||
for (i = 0; i < str.length; i++) {
|
||||
unicode = str.charCodeAt(i);
|
||||
// 0x00000000 - 0x0000007f -> 0xxxxxxx
|
||||
if (unicode <= 0x7f) {
|
||||
b.push(unicode);
|
||||
// 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
|
||||
} else if (unicode <= 0x7ff) {
|
||||
b.push((unicode >> 6) | 0xc0);
|
||||
b.push((unicode & 0x3F) | 0x80);
|
||||
// 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
|
||||
} else if (unicode <= 0xffff) {
|
||||
b.push((unicode >> 12) | 0xe0);
|
||||
b.push(((unicode >> 6) & 0x3f) | 0x80);
|
||||
b.push((unicode & 0x3f) | 0x80);
|
||||
// 0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
} else {
|
||||
b.push((unicode >> 18) | 0xf0);
|
||||
b.push(((unicode >> 12) & 0x3f) | 0x80);
|
||||
b.push(((unicode >> 6) & 0x3f) | 0x80);
|
||||
b.push((unicode & 0x3f) | 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
var BitStream = function (source, byteOffset, byteLength) {
|
||||
var isBuffer = source instanceof ArrayBuffer ||
|
||||
(typeof Buffer !== 'undefined' && source instanceof Buffer);
|
||||
|
||||
if (!(source instanceof BitView) && !isBuffer) {
|
||||
throw new Error('Must specify a valid BitView, ArrayBuffer or Buffer');
|
||||
}
|
||||
|
||||
if (isBuffer) {
|
||||
this._view = new BitView(source, byteOffset, byteLength);
|
||||
} else {
|
||||
this._view = source;
|
||||
}
|
||||
|
||||
this._index = 0;
|
||||
this._startIndex = 0;
|
||||
this._length = this._view.byteLength * 8;
|
||||
};
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'index', {
|
||||
get: function () { return this._index - this._startIndex; },
|
||||
set: function (val) { this._index = val + this._startIndex; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'length', {
|
||||
get: function () { return this._length - this._startIndex; },
|
||||
set: function (val) { this._length = val + this._startIndex; },
|
||||
enumerable : true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'bitsLeft', {
|
||||
get: function () { return this._length - this._index; },
|
||||
enumerable : true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'byteIndex', {
|
||||
// Ceil the returned value, over compensating for the amount of
|
||||
// bits written to the stream.
|
||||
get: function () { return Math.ceil(this._index / 8); },
|
||||
set: function (val) { this._index = val * 8; },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'buffer', {
|
||||
get: function () { return this._view.buffer; },
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'view', {
|
||||
get: function () { return this._view; },
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
Object.defineProperty(BitStream.prototype, 'bigEndian', {
|
||||
get: function () { return this._view.bigEndian; },
|
||||
set: function (val) { this._view.bigEndian = val; },
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
BitStream.prototype.readBits = function (bits, signed) {
|
||||
var val = this._view.getBits(this._index, bits, signed);
|
||||
this._index += bits;
|
||||
return val;
|
||||
};
|
||||
|
||||
BitStream.prototype.writeBits = function (value, bits) {
|
||||
this._view.setBits(this._index, value, bits);
|
||||
this._index += bits;
|
||||
};
|
||||
|
||||
BitStream.prototype.readBoolean = reader('getBoolean', 1);
|
||||
BitStream.prototype.readInt8 = reader('getInt8', 8);
|
||||
BitStream.prototype.readUint8 = reader('getUint8', 8);
|
||||
BitStream.prototype.readInt16 = reader('getInt16', 16);
|
||||
BitStream.prototype.readUint16 = reader('getUint16', 16);
|
||||
BitStream.prototype.readInt32 = reader('getInt32', 32);
|
||||
BitStream.prototype.readUint32 = reader('getUint32', 32);
|
||||
BitStream.prototype.readFloat32 = reader('getFloat32', 32);
|
||||
BitStream.prototype.readFloat64 = reader('getFloat64', 64);
|
||||
|
||||
BitStream.prototype.writeBoolean = writer('setBoolean', 1);
|
||||
BitStream.prototype.writeInt8 = writer('setInt8', 8);
|
||||
BitStream.prototype.writeUint8 = writer('setUint8', 8);
|
||||
BitStream.prototype.writeInt16 = writer('setInt16', 16);
|
||||
BitStream.prototype.writeUint16 = writer('setUint16', 16);
|
||||
BitStream.prototype.writeInt32 = writer('setInt32', 32);
|
||||
BitStream.prototype.writeUint32 = writer('setUint32', 32);
|
||||
BitStream.prototype.writeFloat32 = writer('setFloat32', 32);
|
||||
BitStream.prototype.writeFloat64 = writer('setFloat64', 64);
|
||||
|
||||
BitStream.prototype.readASCIIString = function (bytes) {
|
||||
return readASCIIString(this, bytes);
|
||||
};
|
||||
|
||||
BitStream.prototype.readUTF8String = function (bytes) {
|
||||
return readUTF8String(this, bytes);
|
||||
};
|
||||
|
||||
BitStream.prototype.writeASCIIString = function (string, bytes) {
|
||||
writeASCIIString(this, string, bytes);
|
||||
};
|
||||
|
||||
BitStream.prototype.writeUTF8String = function (string, bytes) {
|
||||
writeUTF8String(this, string, bytes);
|
||||
};
|
||||
BitStream.prototype.readBitStream = function(bitLength) {
|
||||
var slice = new BitStream(this._view);
|
||||
slice._startIndex = this._index;
|
||||
slice._index = this._index;
|
||||
slice.length = bitLength;
|
||||
this._index += bitLength;
|
||||
return slice;
|
||||
};
|
||||
|
||||
BitStream.prototype.writeBitStream = function(stream, length) {
|
||||
if (!length) {
|
||||
length = stream.bitsLeft;
|
||||
}
|
||||
|
||||
var bitsToWrite;
|
||||
while (length > 0) {
|
||||
bitsToWrite = Math.min(length, 32);
|
||||
this.writeBits(stream.readBits(bitsToWrite), bitsToWrite);
|
||||
length -= bitsToWrite;
|
||||
}
|
||||
};
|
||||
|
||||
BitStream.prototype.readArrayBuffer = function(byteLength) {
|
||||
var buffer = this._view.getArrayBuffer(this._index, byteLength);
|
||||
this._index += (byteLength * 8);
|
||||
return buffer;
|
||||
};
|
||||
|
||||
BitStream.prototype.writeArrayBuffer = function(buffer, byteLength) {
|
||||
this.writeBitStream(new BitStream(buffer), byteLength * 8);
|
||||
};
|
||||
|
||||
// AMD / RequireJS
|
||||
if (typeof define !== 'undefined' && define.amd) {
|
||||
define(function () {
|
||||
return {
|
||||
BitView: BitView,
|
||||
BitStream: BitStream
|
||||
};
|
||||
});
|
||||
}
|
||||
// Node.js
|
||||
else if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
BitView: BitView,
|
||||
BitStream: BitStream
|
||||
};
|
||||
}
|
||||
|
||||
}(this));
|
71
node_modules/lv_font_conv/node_modules/bit-buffer/package.json
generated
vendored
@ -1,71 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"bit-buffer@0.2.5",
|
||||
"/home/vitaly/Dropbox/Coding/lv_font_conv"
|
||||
]
|
||||
],
|
||||
"_from": "bit-buffer@0.2.5",
|
||||
"_id": "bit-buffer@0.2.5",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-x1yGnmXvFg6e3DiyRztElbcn1bsCTFSoM/ncAzY62uE0JdTl5xlKJd0ooqLYoPbhdsnpehSIQrdIvclcZJYwiA==",
|
||||
"_location": "/bit-buffer",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "bit-buffer@0.2.5",
|
||||
"name": "bit-buffer",
|
||||
"escapedName": "bit-buffer",
|
||||
"rawSpec": "0.2.5",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "0.2.5"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/bit-buffer/-/bit-buffer-0.2.5.tgz",
|
||||
"_spec": "0.2.5",
|
||||
"_where": "/home/vitaly/Dropbox/Coding/lv_font_conv",
|
||||
"author": {
|
||||
"name": "Anthony Pesch"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/inolen/bit-buffer/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Robin Appelman"
|
||||
}
|
||||
],
|
||||
"description": "Bit-level reads and writes for ArrayBuffers",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.14.22",
|
||||
"jshint": "^2.12.0",
|
||||
"mocha": "^8.2.1"
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"gitHead": "cd4417237bed1f22dd5adfd8a6b961ea7234d9c9",
|
||||
"homepage": "https://github.com/inolen/bit-buffer#readme",
|
||||
"keywords": [
|
||||
"dataview",
|
||||
"arraybuffer",
|
||||
"bit",
|
||||
"bits"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "bit-buffer.js",
|
||||
"name": "bit-buffer",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/inolen/bit-buffer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "jshint bit-buffer.js",
|
||||
"test": "mocha --ui tdd"
|
||||
},
|
||||
"types": "./bit-buffer.d.ts",
|
||||
"version": "0.2.5"
|
||||
}
|
628
node_modules/lv_font_conv/node_modules/bit-buffer/test.js
generated
vendored
@ -1,628 +0,0 @@
|
||||
var assert = require('assert'),
|
||||
BitView = require('./bit-buffer').BitView,
|
||||
BitStream = require('./bit-buffer').BitStream;
|
||||
|
||||
suite('BitBuffer', function () {
|
||||
var array, bv, bsw, bsr;
|
||||
|
||||
setup(function () {
|
||||
array = new ArrayBuffer(64);
|
||||
bv = new BitView(array);
|
||||
bsw = new BitStream(bv);
|
||||
// Test initializing straight from the array.
|
||||
bsr = new BitStream(array);
|
||||
});
|
||||
|
||||
test('Min / max signed 5 bits', function () {
|
||||
var signed_max = (1 << 4) - 1;
|
||||
|
||||
bsw.writeBits(signed_max, 5);
|
||||
bsw.writeBits(-signed_max - 1, 5);
|
||||
assert(bsr.readBits(5, true) === signed_max);
|
||||
assert(bsr.readBits(5, true) === -signed_max - 1);
|
||||
});
|
||||
|
||||
test('Min / max unsigned 5 bits', function () {
|
||||
var unsigned_max = (1 << 5) - 1;
|
||||
|
||||
bsw.writeBits(unsigned_max, 5);
|
||||
bsw.writeBits(-unsigned_max, 5);
|
||||
assert.equal(bsr.readBits(5), unsigned_max);
|
||||
assert.equal(bsr.readBits(5), 1);
|
||||
});
|
||||
|
||||
test('Min / max int8', function () {
|
||||
var signed_max = 0x7F;
|
||||
|
||||
bsw.writeInt8(signed_max);
|
||||
bsw.writeInt8(-signed_max - 1);
|
||||
assert.equal(bsr.readInt8(), signed_max);
|
||||
assert.equal(bsr.readInt8(), -signed_max - 1);
|
||||
});
|
||||
|
||||
test('Min / max uint8', function () {
|
||||
var unsigned_max = 0xFF;
|
||||
|
||||
bsw.writeUint8(unsigned_max);
|
||||
bsw.writeUint8(-unsigned_max);
|
||||
assert.equal(bsr.readUint8(), unsigned_max);
|
||||
assert.equal(bsr.readUint8(), 1);
|
||||
});
|
||||
|
||||
test('Min / max int16', function () {
|
||||
var signed_max = 0x7FFF;
|
||||
|
||||
bsw.writeInt16(signed_max);
|
||||
bsw.writeInt16(-signed_max - 1);
|
||||
assert.equal(bsr.readInt16(), signed_max);
|
||||
assert.equal(bsr.readInt16(), -signed_max - 1);
|
||||
});
|
||||
|
||||
test('Min / max uint16', function () {
|
||||
var unsigned_max = 0xFFFF;
|
||||
|
||||
bsw.writeUint16(unsigned_max);
|
||||
bsw.writeUint16(-unsigned_max);
|
||||
assert.equal(bsr.readUint16(), unsigned_max);
|
||||
assert.equal(bsr.readUint16(), 1);
|
||||
});
|
||||
|
||||
test('Min / max int32', function () {
|
||||
var signed_max = 0x7FFFFFFF;
|
||||
|
||||
bsw.writeInt32(signed_max);
|
||||
bsw.writeInt32(-signed_max - 1);
|
||||
assert.equal(bsr.readInt32(), signed_max);
|
||||
assert.equal(bsr.readInt32(), -signed_max - 1);
|
||||
});
|
||||
|
||||
test('Min / max uint32', function () {
|
||||
var unsigned_max = 0xFFFFFFFF;
|
||||
|
||||
bsw.writeUint32(unsigned_max);
|
||||
bsw.writeUint32(-unsigned_max);
|
||||
assert.equal(bsr.readUint32(), unsigned_max);
|
||||
assert.equal(bsr.readUint32(), 1);
|
||||
});
|
||||
|
||||
test('Unaligned reads', function () {
|
||||
bsw.writeBits(13, 5);
|
||||
bsw.writeUint8(0xFF);
|
||||
bsw.writeBits(14, 5);
|
||||
|
||||
assert.equal(bsr.readBits(5), 13);
|
||||
assert.equal(bsr.readUint8(), 0xFF);
|
||||
assert.equal(bsr.readBits(5), 14);
|
||||
});
|
||||
|
||||
test('Min / max float32 (normal values)', function () {
|
||||
var scratch = new DataView(new ArrayBuffer(8));
|
||||
|
||||
scratch.setUint32(0, 0x00800000);
|
||||
scratch.setUint32(4, 0x7f7fffff);
|
||||
|
||||
var min = scratch.getFloat32(0);
|
||||
var max = scratch.getFloat32(4);
|
||||
|
||||
bsw.writeFloat32(min);
|
||||
bsw.writeFloat32(max);
|
||||
|
||||
assert.equal(bsr.readFloat32(), min);
|
||||
assert.equal(bsr.readFloat32(), max);
|
||||
});
|
||||
|
||||
test('Min / max float64 (normal values)', function () {
|
||||
var scratch = new DataView(new ArrayBuffer(16));
|
||||
|
||||
scratch.setUint32(0, 0x00100000);
|
||||
scratch.setUint32(4, 0x00000000);
|
||||
scratch.setUint32(8, 0x7fefffff);
|
||||
scratch.setUint32(12, 0xffffffff);
|
||||
|
||||
var min = scratch.getFloat64(0);
|
||||
var max = scratch.getFloat64(8);
|
||||
|
||||
bsw.writeFloat64(min);
|
||||
bsw.writeFloat64(max);
|
||||
|
||||
assert.equal(bsr.readFloat64(), min);
|
||||
assert.equal(bsr.readFloat64(), max);
|
||||
});
|
||||
|
||||
test('Overwrite previous value with 0', function () {
|
||||
bv.setUint8(0, 13);
|
||||
bv.setUint8(0, 0);
|
||||
|
||||
assert.equal(bv.getUint8(0), 0);
|
||||
});
|
||||
|
||||
test('Read / write ASCII string, fixed length', function () {
|
||||
var str = 'foobar';
|
||||
var len = 16;
|
||||
|
||||
bsw.writeASCIIString(str, len);
|
||||
assert.equal(bsw.byteIndex, len);
|
||||
|
||||
assert.equal(bsr.readASCIIString(len), str);
|
||||
assert.equal(bsr.byteIndex, len);
|
||||
});
|
||||
|
||||
test('Read / write ASCII string, unknown length', function () {
|
||||
var str = 'foobar';
|
||||
|
||||
bsw.writeASCIIString(str);
|
||||
assert.equal(bsw.byteIndex, str.length + 1); // +1 for 0x00
|
||||
|
||||
assert.equal(bsr.readASCIIString(), str);
|
||||
assert.equal(bsr.byteIndex, str.length + 1);
|
||||
});
|
||||
|
||||
test('Read ASCII string, 0 length', function () {
|
||||
var str = 'foobar';
|
||||
|
||||
bsw.writeASCIIString(str);
|
||||
assert.equal(bsw.byteIndex, str.length + 1); // +1 for 0x00
|
||||
|
||||
assert.equal(bsr.readASCIIString(0), '');
|
||||
assert.equal(bsr.byteIndex, 0);
|
||||
});
|
||||
|
||||
test('Read overflow', function () {
|
||||
var exception = false;
|
||||
|
||||
try {
|
||||
bsr.readASCIIString(128);
|
||||
} catch (e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
assert(exception);
|
||||
});
|
||||
|
||||
test('Write overflow', function () {
|
||||
var exception = false;
|
||||
|
||||
try {
|
||||
bsw.writeASCIIString('foobar', 128);
|
||||
} catch (e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
assert(exception);
|
||||
});
|
||||
|
||||
test('Get boolean', function () {
|
||||
bv.setUint8(0, 1);
|
||||
|
||||
assert(bv.getBoolean(0));
|
||||
|
||||
bv.setUint8(0, 0);
|
||||
assert(!bv.getBoolean(0));
|
||||
});
|
||||
|
||||
test('Set boolean', function () {
|
||||
bv.setBoolean(0, true);
|
||||
|
||||
assert(bv.getBoolean(0));
|
||||
|
||||
bv.setBoolean(0, false);
|
||||
|
||||
assert(!bv.getBoolean(0));
|
||||
});
|
||||
|
||||
test('Read boolean', function () {
|
||||
bv.setBits(0, 1, 1);
|
||||
bv.setBits(1, 0, 1);
|
||||
|
||||
assert(bsr.readBoolean());
|
||||
assert(!bsr.readBoolean());
|
||||
});
|
||||
|
||||
test('Write boolean', function () {
|
||||
bsr.writeBoolean(true);
|
||||
assert.equal(bv.getBits(0, 1, false), 1);
|
||||
bsr.writeBoolean(false);
|
||||
assert.equal(bv.getBits(1, 1, false), 0);
|
||||
});
|
||||
|
||||
test('Read / write UTF8 string, only ASCII characters', function () {
|
||||
var str = 'foobar';
|
||||
|
||||
bsw.writeUTF8String(str);
|
||||
assert(bsw.byteIndex === str.length + 1); // +1 for 0x00
|
||||
|
||||
assert.equal(bsr.readUTF8String(), str);
|
||||
assert.equal(bsr.byteIndex, str.length + 1);
|
||||
});
|
||||
|
||||
test('Read / write UTF8 string, non ASCII characters', function () {
|
||||
var str = '日本語';
|
||||
|
||||
var bytes = [
|
||||
0xE6,
|
||||
0x97,
|
||||
0xA5,
|
||||
0xE6,
|
||||
0x9C,
|
||||
0xAC,
|
||||
0xE8,
|
||||
0xAA,
|
||||
0x9E
|
||||
];
|
||||
|
||||
bsw.writeUTF8String(str);
|
||||
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
assert.equal(bytes[i], bv.getBits(i * 8, 8));
|
||||
}
|
||||
|
||||
assert.equal(bsw.byteIndex, bytes.length + 1); // +1 for 0x00
|
||||
|
||||
assert.equal(str, bsr.readUTF8String());
|
||||
assert.equal(bsr.byteIndex, bytes.length + 1);
|
||||
});
|
||||
|
||||
test('readBitStream', function () {
|
||||
bsw.writeBits(0xF0, 8); //0b11110000
|
||||
bsw.writeBits(0xF1, 8); //0b11110001
|
||||
bsr.readBits(3); //offset
|
||||
var slice = bsr.readBitStream(8);
|
||||
assert.equal(slice.readBits(6), 0x3E); //0b111110
|
||||
assert.equal(9, slice._index);
|
||||
assert.equal(6, slice.index);
|
||||
assert.equal(8, slice.length);
|
||||
assert.equal(2, slice.bitsLeft);
|
||||
|
||||
assert.equal(bsr._index, 11);
|
||||
assert.equal((64 * 8) - 11, bsr.bitsLeft);
|
||||
});
|
||||
|
||||
test('readBitStream overflow', function () {
|
||||
bsw.writeBits(0xF0, 8); //0b11110000
|
||||
bsw.writeBits(0xF1, 8); //0b11110001
|
||||
bsr.readBits(3); //offset
|
||||
var slice = bsr.readBitStream(4);
|
||||
|
||||
var exception = false;
|
||||
|
||||
try {
|
||||
slice.readUint8();
|
||||
} catch (e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
assert(exception);
|
||||
});
|
||||
|
||||
test('writeBitStream', function () {
|
||||
var buf = new ArrayBuffer(64);
|
||||
var sourceStream = new BitStream(buf);
|
||||
|
||||
sourceStream.writeBits(0xF0, 8); //0b11110000
|
||||
sourceStream.writeBits(0xF1, 8); //0b11110001
|
||||
sourceStream.index = 0;
|
||||
sourceStream.readBits(3); //offset
|
||||
bsr.writeBitStream(sourceStream, 8);
|
||||
assert.equal(8, bsr.index);
|
||||
bsr.index = 0;
|
||||
assert.equal(bsr.readBits(6), 0x3E); //0b00111110
|
||||
assert.equal(11, sourceStream.index);
|
||||
|
||||
var bin = new Uint8Array(buf);
|
||||
assert.equal(bin[0], 0xF0);
|
||||
assert.equal(bin[1], 0xF1);
|
||||
});
|
||||
|
||||
test('writeBitStream Buffer', function () {
|
||||
var buf = Buffer.alloc(64);
|
||||
var sourceStream = new BitStream(buf);
|
||||
|
||||
sourceStream.writeBits(0xF0, 8); //0b11110000
|
||||
sourceStream.writeBits(0xF1, 8); //0b11110001
|
||||
sourceStream.index = 0;
|
||||
sourceStream.readBits(3); //offset
|
||||
bsr.writeBitStream(sourceStream, 8);
|
||||
assert.equal(8, bsr.index);
|
||||
bsr.index = 0;
|
||||
assert.equal(bsr.readBits(6), 0x3E); //0b00111110
|
||||
assert.equal(11, sourceStream.index);
|
||||
|
||||
var bin = new Uint8Array(buf.buffer);
|
||||
assert.equal(bin[0], 0xF0);
|
||||
assert.equal(bin[1], 0xF1);
|
||||
});
|
||||
|
||||
test('writeBitStream long', function () {
|
||||
var sourceStream = new BitStream(new ArrayBuffer(64));
|
||||
|
||||
sourceStream.writeBits(0xF0, 8);
|
||||
sourceStream.writeBits(0xF1, 8);
|
||||
sourceStream.writeBits(0xF1, 8);
|
||||
sourceStream.writeBits(0xF1, 8);
|
||||
sourceStream.writeBits(0xF1, 8);
|
||||
sourceStream.index = 0;
|
||||
sourceStream.readBits(3); //offset
|
||||
bsr.index = 3;
|
||||
bsr.writeBitStream(sourceStream, 35);
|
||||
assert.equal(38, bsr.index);
|
||||
bsr.index = 3;
|
||||
assert.equal(bsr.readBits(35), 1044266558);
|
||||
assert.equal(38, sourceStream.index);
|
||||
});
|
||||
|
||||
test('readArrayBuffer', function () {
|
||||
bsw.writeBits(0xF0, 8); //0b11110000
|
||||
bsw.writeBits(0xF1, 8); //0b11110001
|
||||
bsw.writeBits(0xF0, 8); //0b11110000
|
||||
bsr.readBits(3); //offset
|
||||
|
||||
var buffer = bsr.readArrayBuffer(2);
|
||||
|
||||
assert.equal(0x3E, buffer[0]); //0b00111110
|
||||
assert.equal(0x1E, buffer[1]); //0b00011110
|
||||
|
||||
assert.equal(3 + (2 * 8), bsr._index);
|
||||
});
|
||||
|
||||
test('writeArrayBuffer', function () {
|
||||
var source = new Uint8Array(4);
|
||||
source[0] = 0xF0;
|
||||
source[1] = 0xF1;
|
||||
source[2] = 0xF1;
|
||||
bsr.readBits(3); //offset
|
||||
|
||||
bsr.writeArrayBuffer(source.buffer, 2);
|
||||
assert.equal(19, bsr.index);
|
||||
|
||||
bsr.index = 0;
|
||||
|
||||
assert.equal(bsr.readBits(8), 128);
|
||||
});
|
||||
|
||||
test('Get buffer from view', function () {
|
||||
bv.setBits(0, 0xFFFFFFFF, 32);
|
||||
var buffer = bv.buffer;
|
||||
|
||||
assert.equal(64, buffer.length);
|
||||
assert.equal(0xFFFF, buffer.readUInt16LE(0));
|
||||
});
|
||||
|
||||
test('Get buffer from stream', function () {
|
||||
bsw.writeBits(0xFFFFFFFF, 32);
|
||||
var buffer = bsr.buffer;
|
||||
|
||||
assert.equal(64, buffer.length);
|
||||
assert.equal(0xFFFF, buffer.readUInt16LE(0));
|
||||
});
|
||||
});
|
||||
|
||||
suite('Reading big/little endian', function () {
|
||||
var array, u8, bv, bsw, bsr;
|
||||
|
||||
setup(function () {
|
||||
array = new ArrayBuffer(64);
|
||||
u8 = new Uint8Array(array);
|
||||
u8[0] = 0x01;
|
||||
u8[1] = 0x02;
|
||||
// Test initializing straight from the array.
|
||||
bsr = new BitStream(array);
|
||||
});
|
||||
|
||||
test('4b, little-endian', function () {
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [#2] [#1] [#4] [#3]
|
||||
assert.deepEqual(result, [1, 0, 2, 0]);
|
||||
});
|
||||
|
||||
test('8b, little-endian', function () {
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(8));
|
||||
result.push(bsr.readBits(8));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1] [ #2]
|
||||
assert.deepEqual(result, [1, 2]);
|
||||
});
|
||||
|
||||
test('10b, little-endian', function () {
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(10));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// ... #1] [ #2][#1...
|
||||
assert.deepEqual(result, [513]);
|
||||
});
|
||||
|
||||
test('16b, little-endian', function () {
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(16));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1]
|
||||
assert.deepEqual(result, [0x201]);
|
||||
});
|
||||
|
||||
test('24b, little-endian', function () {
|
||||
u8[2] = 0x03;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(24));
|
||||
|
||||
// 0000 0001 0000 0010 0000 0011 [01 02 03]
|
||||
// [ #1]
|
||||
assert.deepEqual(result, [0x30201]);
|
||||
});
|
||||
|
||||
test('4b, big-endian', function () {
|
||||
bsr.bigEndian = true;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
result.push(bsr.readBits(4));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [#1] [#2] [#3] [#4]
|
||||
assert.deepEqual(result, [0, 1, 0, 2]);
|
||||
});
|
||||
|
||||
test('8b, big-endian', function () {
|
||||
bsr.bigEndian = true;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(8));
|
||||
result.push(bsr.readBits(8));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1] [ #2]
|
||||
assert.deepEqual(result, [1, 2]);
|
||||
});
|
||||
|
||||
test('10b, big-endian', function () {
|
||||
bsr.bigEndian = true;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(10));
|
||||
result.push(bsr.readBits(6));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1][ #2]
|
||||
assert.deepEqual(result, [4, 2]);
|
||||
});
|
||||
|
||||
test('16b, big-endian', function () {
|
||||
bsr.bigEndian = true;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(16));
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1]
|
||||
assert.deepEqual(result, [0x102]);
|
||||
});
|
||||
|
||||
test('24b, big-endian', function () {
|
||||
u8[2] = 0x03;
|
||||
bsr.bigEndian = true;
|
||||
assert.equal(bsr.index, 0, 'BitStream didn\'t init at offset 0');
|
||||
|
||||
var result = [];
|
||||
result.push(bsr.readBits(24));
|
||||
|
||||
// 0000 0001 0000 0010 0000 0011 [01 02 03]
|
||||
// [ #1]
|
||||
assert.deepEqual(result, [0x10203]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Writing big/little endian', function () {
|
||||
var array, u8, bv, bsw, bsr;
|
||||
|
||||
setup(function () {
|
||||
array = new ArrayBuffer(2);
|
||||
u8 = new Uint8Array(array);
|
||||
bv = new BitView(array);
|
||||
bsw = new BitStream(bv);
|
||||
});
|
||||
|
||||
test('4b, little-endian', function () {
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [#2] [#1] [#4] [#3]
|
||||
bsw.writeBits(1, 4);
|
||||
bsw.writeBits(0, 4);
|
||||
bsw.writeBits(2, 4);
|
||||
bsw.writeBits(0, 4);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('8b, little-endian', function () {
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1] [ #2]
|
||||
bsw.writeBits(1, 8);
|
||||
bsw.writeBits(2, 8);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('10b, little-endian', function () {
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// ... #1] [ #2][#1...
|
||||
bsw.writeBits(513, 10);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('16b, little-endian', function () {
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1]
|
||||
bsw.writeBits(0x201, 16);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('4b, big-endian', function () {
|
||||
bsw.bigEndian = true;
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [#1] [#2] [#3] [#4]
|
||||
bsw.writeBits(0, 4);
|
||||
bsw.writeBits(1, 4);
|
||||
bsw.writeBits(0, 4);
|
||||
bsw.writeBits(2, 4);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('8b, big-endian', function () {
|
||||
bsw.bigEndian = true;
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1] [ #2]
|
||||
bsw.writeBits(1, 8);
|
||||
bsw.writeBits(2, 8);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('10b, big-endian', function () {
|
||||
bsw.bigEndian = true;
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1][ #2]
|
||||
bsw.writeBits(4, 10);
|
||||
bsw.writeBits(2, 6);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
|
||||
test('16b, big-endian', function () {
|
||||
bsw.bigEndian = true;
|
||||
|
||||
// 0000 0001 0000 0010 [01 02]
|
||||
// [ #1]
|
||||
bsw.writeBits(0x102, 16);
|
||||
|
||||
assert.deepEqual(u8, new Uint8Array([0x01, 0x02]));
|
||||
});
|
||||
});
|
19
node_modules/lv_font_conv/node_modules/debug/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
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.
|
||||
|
455
node_modules/lv_font_conv/node_modules/debug/README.md
generated
vendored
@ -1,455 +0,0 @@
|
||||
# debug
|
||||
[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master) [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
|
||||
[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
A tiny JavaScript debugging utility modelled after Node.js core's debugging
|
||||
technique. Works in Node.js and web browsers.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ npm install debug
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
|
||||
|
||||
Example [_app.js_](./examples/node/app.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %o', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
```
|
||||
|
||||
Example [_worker.js_](./examples/node/worker.js):
|
||||
|
||||
```js
|
||||
var a = require('debug')('worker:a')
|
||||
, b = require('debug')('worker:b');
|
||||
|
||||
function work() {
|
||||
a('doing lots of uninteresting work');
|
||||
setTimeout(work, Math.random() * 1000);
|
||||
}
|
||||
|
||||
work();
|
||||
|
||||
function workb() {
|
||||
b('doing some work');
|
||||
setTimeout(workb, Math.random() * 2000);
|
||||
}
|
||||
|
||||
workb();
|
||||
```
|
||||
|
||||
The `DEBUG` environment variable is then used to enable these based on space or
|
||||
comma-delimited names.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png">
|
||||
|
||||
#### Windows command prompt notes
|
||||
|
||||
##### CMD
|
||||
|
||||
On Windows the environment variable is set using the `set` command.
|
||||
|
||||
```cmd
|
||||
set DEBUG=*,-not_this
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
set DEBUG=* & node app.js
|
||||
```
|
||||
|
||||
##### PowerShell (VS Code default)
|
||||
|
||||
PowerShell uses different syntax to set environment variables.
|
||||
|
||||
```cmd
|
||||
$env:DEBUG = "*,-not_this"
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
$env:DEBUG='app';node app.js
|
||||
```
|
||||
|
||||
Then, run the program to be debugged as usual.
|
||||
|
||||
npm script example:
|
||||
```js
|
||||
"windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js",
|
||||
```
|
||||
|
||||
## Namespace Colors
|
||||
|
||||
Every debug instance has a color generated for it based on its namespace name.
|
||||
This helps when visually parsing the debug output to identify which debug instance
|
||||
a debug line belongs to.
|
||||
|
||||
#### Node.js
|
||||
|
||||
In Node.js, colors are enabled when stderr is a TTY. You also _should_ install
|
||||
the [`supports-color`](https://npmjs.org/supports-color) module alongside debug,
|
||||
otherwise debug will only use a small handful of basic colors.
|
||||
|
||||
<img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png">
|
||||
|
||||
#### Web Browser
|
||||
|
||||
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
|
||||
option. These are WebKit web inspectors, Firefox ([since version
|
||||
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
|
||||
and the Firebug plugin for Firefox (any version).
|
||||
|
||||
<img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png">
|
||||
|
||||
|
||||
## Millisecond diff
|
||||
|
||||
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png">
|
||||
|
||||
|
||||
## Conventions
|
||||
|
||||
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output.
|
||||
|
||||
## Wildcards
|
||||
|
||||
The `*` character may be used as a wildcard. Suppose for example your library has
|
||||
debuggers named "connect:bodyParser", "connect:compress", "connect:session",
|
||||
instead of listing all three with
|
||||
`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do
|
||||
`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
|
||||
|
||||
You can also exclude specific debuggers by prefixing them with a "-" character.
|
||||
For example, `DEBUG=*,-connect:*` would include all debuggers except those
|
||||
starting with "connect:".
|
||||
|
||||
## Environment Variables
|
||||
|
||||
When running through Node.js, you can set a few environment variables that will
|
||||
change the behavior of the debug logging:
|
||||
|
||||
| Name | Purpose |
|
||||
|-----------|-------------------------------------------------|
|
||||
| `DEBUG` | Enables/disables specific debugging namespaces. |
|
||||
| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). |
|
||||
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
|
||||
| `DEBUG_DEPTH` | Object inspection depth. |
|
||||
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
|
||||
|
||||
|
||||
__Note:__ The environment variables beginning with `DEBUG_` end up being
|
||||
converted into an Options object that gets used with `%o`/`%O` formatters.
|
||||
See the Node.js documentation for
|
||||
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
|
||||
for the complete list.
|
||||
|
||||
## Formatters
|
||||
|
||||
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.
|
||||
Below are the officially supported formatters:
|
||||
|
||||
| Formatter | Representation |
|
||||
|-----------|----------------|
|
||||
| `%O` | Pretty-print an Object on multiple lines. |
|
||||
| `%o` | Pretty-print an Object all on a single line. |
|
||||
| `%s` | String. |
|
||||
| `%d` | Number (both integer and float). |
|
||||
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
|
||||
| `%%` | Single percent sign ('%'). This does not consume an argument. |
|
||||
|
||||
|
||||
### Custom formatters
|
||||
|
||||
You can add custom formatters by extending the `debug.formatters` object.
|
||||
For example, if you wanted to add support for rendering a Buffer as hex with
|
||||
`%h`, you could do something like:
|
||||
|
||||
```js
|
||||
const createDebug = require('debug')
|
||||
createDebug.formatters.h = (v) => {
|
||||
return v.toString('hex')
|
||||
}
|
||||
|
||||
// …elsewhere
|
||||
const debug = createDebug('foo')
|
||||
debug('this is hex: %h', new Buffer('hello world'))
|
||||
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
|
||||
```
|
||||
|
||||
|
||||
## Browser Support
|
||||
|
||||
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
|
||||
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
|
||||
if you don't want to build it yourself.
|
||||
|
||||
Debug's enable state is currently persisted by `localStorage`.
|
||||
Consider the situation shown below where you have `worker:a` and `worker:b`,
|
||||
and wish to debug both. You can enable this using `localStorage.debug`:
|
||||
|
||||
```js
|
||||
localStorage.debug = 'worker:*'
|
||||
```
|
||||
|
||||
And then refresh the page.
|
||||
|
||||
```js
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
b('doing some work');
|
||||
}, 1200);
|
||||
```
|
||||
|
||||
|
||||
## Output streams
|
||||
|
||||
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
|
||||
|
||||
Example [_stdout.js_](./examples/node/stdout.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug');
|
||||
var error = debug('app:error');
|
||||
|
||||
// by default stderr is used
|
||||
error('goes to stderr!');
|
||||
|
||||
var log = debug('app:log');
|
||||
// set this namespace to log via console.log
|
||||
log.log = console.log.bind(console); // don't forget to bind to console!
|
||||
log('goes to stdout');
|
||||
error('still goes to stderr!');
|
||||
|
||||
// set all output to go via console.info
|
||||
// overrides all per-namespace log settings
|
||||
debug.log = console.info.bind(console);
|
||||
error('now goes to stdout via console.info');
|
||||
log('still goes to stdout, but via console.info now');
|
||||
```
|
||||
|
||||
## Extend
|
||||
You can simply extend debugger
|
||||
```js
|
||||
const log = require('debug')('auth');
|
||||
|
||||
//creates new debug instance with extended namespace
|
||||
const logSign = log.extend('sign');
|
||||
const logLogin = log.extend('login');
|
||||
|
||||
log('hello'); // auth hello
|
||||
logSign('hello'); //auth:sign hello
|
||||
logLogin('hello'); //auth:login hello
|
||||
```
|
||||
|
||||
## Set dynamically
|
||||
|
||||
You can also enable debug dynamically by calling the `enable()` method :
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
|
||||
console.log(1, debug.enabled('test'));
|
||||
|
||||
debug.enable('test');
|
||||
console.log(2, debug.enabled('test'));
|
||||
|
||||
debug.disable();
|
||||
console.log(3, debug.enabled('test'));
|
||||
|
||||
```
|
||||
|
||||
print :
|
||||
```
|
||||
1 false
|
||||
2 true
|
||||
3 false
|
||||
```
|
||||
|
||||
Usage :
|
||||
`enable(namespaces)`
|
||||
`namespaces` can include modes separated by a colon and wildcards.
|
||||
|
||||
Note that calling `enable()` completely overrides previously set DEBUG variable :
|
||||
|
||||
```
|
||||
$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))'
|
||||
=> false
|
||||
```
|
||||
|
||||
`disable()`
|
||||
|
||||
Will disable all namespaces. The functions returns the namespaces currently
|
||||
enabled (and skipped). This can be useful if you want to disable debugging
|
||||
temporarily without knowing what was enabled to begin with.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
debug.enable('foo:*,-foo:bar');
|
||||
let namespaces = debug.disable();
|
||||
debug.enable(namespaces);
|
||||
```
|
||||
|
||||
Note: There is no guarantee that the string will be identical to the initial
|
||||
enable string, but semantically they will be identical.
|
||||
|
||||
## Checking whether a debug target is enabled
|
||||
|
||||
After you've created a debug instance, you can determine whether or not it is
|
||||
enabled by checking the `enabled` property:
|
||||
|
||||
```javascript
|
||||
const debug = require('debug')('http');
|
||||
|
||||
if (debug.enabled) {
|
||||
// do stuff...
|
||||
}
|
||||
```
|
||||
|
||||
You can also manually toggle this property to force the debug instance to be
|
||||
enabled or disabled.
|
||||
|
||||
|
||||
## Authors
|
||||
|
||||
- TJ Holowaychuk
|
||||
- Nathan Rajlich
|
||||
- Andrew Rhyne
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
|
||||
|
||||
<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
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.
|
111
node_modules/lv_font_conv/node_modules/debug/package.json
generated
vendored
@ -1,111 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"debug@4.3.1",
|
||||
"/home/vitaly/Dropbox/Coding/lv_font_conv"
|
||||
]
|
||||
],
|
||||
"_from": "debug@4.3.1",
|
||||
"_id": "debug@4.3.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"_location": "/debug",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "debug@4.3.1",
|
||||
"name": "debug",
|
||||
"escapedName": "debug",
|
||||
"rawSpec": "4.3.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "4.3.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/",
|
||||
"/@babel/core",
|
||||
"/@babel/helper-define-polyfill-provider",
|
||||
"/@babel/traverse",
|
||||
"/@eslint/eslintrc",
|
||||
"/eslint",
|
||||
"/istanbul-lib-source-maps",
|
||||
"/mocha"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"_spec": "4.3.1",
|
||||
"_where": "/home/vitaly/Dropbox/Coding/lv_font_conv",
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
"browser": "./src/browser.js",
|
||||
"bugs": {
|
||||
"url": "https://github.com/visionmedia/debug/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Nathan Rajlich",
|
||||
"email": "nathan@tootallnate.net",
|
||||
"url": "http://n8.io"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Rhyne",
|
||||
"email": "rhyneandrew@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Josh Junon",
|
||||
"email": "josh@junon.me"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"description": "small debugging utility",
|
||||
"devDependencies": {
|
||||
"brfs": "^2.0.1",
|
||||
"browserify": "^16.2.3",
|
||||
"coveralls": "^3.0.2",
|
||||
"istanbul": "^0.4.5",
|
||||
"karma": "^3.1.4",
|
||||
"karma-browserify": "^6.0.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-lcov-reporter": "^1.2.0",
|
||||
"xo": "^0.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"homepage": "https://github.com/visionmedia/debug#readme",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./src/index.js",
|
||||
"name": "debug",
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/debug.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "xo",
|
||||
"test": "npm run test:node && npm run test:browser && npm run lint",
|
||||
"test:browser": "karma start --single-run",
|
||||
"test:coverage": "cat ./coverage/lcov.info | coveralls",
|
||||
"test:node": "istanbul cover _mocha -- test.js"
|
||||
},
|
||||
"version": "4.3.1"
|
||||
}
|
269
node_modules/lv_font_conv/node_modules/debug/src/browser.js
generated
vendored
@ -1,269 +0,0 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
/**
|
||||
* This is the web browser implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.storage = localstorage();
|
||||
exports.destroy = (() => {
|
||||
let warned = false;
|
||||
|
||||
return () => {
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [
|
||||
'#0000CC',
|
||||
'#0000FF',
|
||||
'#0033CC',
|
||||
'#0033FF',
|
||||
'#0066CC',
|
||||
'#0066FF',
|
||||
'#0099CC',
|
||||
'#0099FF',
|
||||
'#00CC00',
|
||||
'#00CC33',
|
||||
'#00CC66',
|
||||
'#00CC99',
|
||||
'#00CCCC',
|
||||
'#00CCFF',
|
||||
'#3300CC',
|
||||
'#3300FF',
|
||||
'#3333CC',
|
||||
'#3333FF',
|
||||
'#3366CC',
|
||||
'#3366FF',
|
||||
'#3399CC',
|
||||
'#3399FF',
|
||||
'#33CC00',
|
||||
'#33CC33',
|
||||
'#33CC66',
|
||||
'#33CC99',
|
||||
'#33CCCC',
|
||||
'#33CCFF',
|
||||
'#6600CC',
|
||||
'#6600FF',
|
||||
'#6633CC',
|
||||
'#6633FF',
|
||||
'#66CC00',
|
||||
'#66CC33',
|
||||
'#9900CC',
|
||||
'#9900FF',
|
||||
'#9933CC',
|
||||
'#9933FF',
|
||||
'#99CC00',
|
||||
'#99CC33',
|
||||
'#CC0000',
|
||||
'#CC0033',
|
||||
'#CC0066',
|
||||
'#CC0099',
|
||||
'#CC00CC',
|
||||
'#CC00FF',
|
||||
'#CC3300',
|
||||
'#CC3333',
|
||||
'#CC3366',
|
||||
'#CC3399',
|
||||
'#CC33CC',
|
||||
'#CC33FF',
|
||||
'#CC6600',
|
||||
'#CC6633',
|
||||
'#CC9900',
|
||||
'#CC9933',
|
||||
'#CCCC00',
|
||||
'#CCCC33',
|
||||
'#FF0000',
|
||||
'#FF0033',
|
||||
'#FF0066',
|
||||
'#FF0099',
|
||||
'#FF00CC',
|
||||
'#FF00FF',
|
||||
'#FF3300',
|
||||
'#FF3333',
|
||||
'#FF3366',
|
||||
'#FF3399',
|
||||
'#FF33CC',
|
||||
'#FF33FF',
|
||||
'#FF6600',
|
||||
'#FF6633',
|
||||
'#FF9900',
|
||||
'#FF9933',
|
||||
'#FFCC00',
|
||||
'#FFCC33'
|
||||
];
|
||||
|
||||
/**
|
||||
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
||||
* and the Firebug extension (any Firefox version) are known
|
||||
* to support "%c" CSS customizations.
|
||||
*
|
||||
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
function useColors() {
|
||||
// NB: In an Electron preload script, document will be defined but not fully
|
||||
// initialized. Since we know we're in Chrome, we'll just detect this case
|
||||
// explicitly
|
||||
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Internet Explorer and Edge do not support colors.
|
||||
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
||||
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
||||
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
||||
// Is firebug? http://stackoverflow.com/a/398120/376773
|
||||
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
||||
// Is firefox >= v31?
|
||||
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
|
||||
// Double check webkit in userAgent just in case we are in a worker
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorize log arguments if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
args[0] = (this.useColors ? '%c' : '') +
|
||||
this.namespace +
|
||||
(this.useColors ? ' %c' : ' ') +
|
||||
args[0] +
|
||||
(this.useColors ? '%c ' : ' ') +
|
||||
'+' + module.exports.humanize(this.diff);
|
||||
|
||||
if (!this.useColors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const c = 'color: ' + this.color;
|
||||
args.splice(1, 0, c, 'color: inherit');
|
||||
|
||||
// The final "%c" is somewhat tricky, because there could be other
|
||||
// arguments passed either before or after the %c, so we need to
|
||||
// figure out the correct index to insert the CSS into
|
||||
let index = 0;
|
||||
let lastC = 0;
|
||||
args[0].replace(/%[a-zA-Z%]/g, match => {
|
||||
if (match === '%%') {
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
if (match === '%c') {
|
||||
// We only are interested in the *last* %c
|
||||
// (the user may have provided their own)
|
||||
lastC = index;
|
||||
}
|
||||
});
|
||||
|
||||
args.splice(lastC, 0, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `console.debug()` when available.
|
||||
* No-op when `console.debug` is not a "function".
|
||||
* If `console.debug` is not available, falls back
|
||||
* to `console.log`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
exports.log = console.debug || console.log || (() => {});
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
try {
|
||||
if (namespaces) {
|
||||
exports.storage.setItem('debug', namespaces);
|
||||
} else {
|
||||
exports.storage.removeItem('debug');
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
function load() {
|
||||
let r;
|
||||
try {
|
||||
r = exports.storage.getItem('debug');
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
|
||||
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
||||
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
||||
r = process.env.DEBUG;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Localstorage attempts to return the localstorage.
|
||||
*
|
||||
* This is necessary because safari throws
|
||||
* when a user disables cookies/localstorage
|
||||
* and you attempt to access it.
|
||||
*
|
||||
* @return {LocalStorage}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function localstorage() {
|
||||
try {
|
||||
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
|
||||
// The Browser also has localStorage in the global context.
|
||||
return localStorage;
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
||||
*/
|
||||
|
||||
formatters.j = function (v) {
|
||||
try {
|
||||
return JSON.stringify(v);
|
||||
} catch (error) {
|
||||
return '[UnexpectedJSONParseError]: ' + error.message;
|
||||
}
|
||||
};
|
261
node_modules/lv_font_conv/node_modules/debug/src/common.js
generated
vendored
@ -1,261 +0,0 @@
|
||||
|
||||
/**
|
||||
* This is the common logic for both the Node.js and web browser
|
||||
* implementations of `debug()`.
|
||||
*/
|
||||
|
||||
function setup(env) {
|
||||
createDebug.debug = createDebug;
|
||||
createDebug.default = createDebug;
|
||||
createDebug.coerce = coerce;
|
||||
createDebug.disable = disable;
|
||||
createDebug.enable = enable;
|
||||
createDebug.enabled = enabled;
|
||||
createDebug.humanize = require('ms');
|
||||
createDebug.destroy = destroy;
|
||||
|
||||
Object.keys(env).forEach(key => {
|
||||
createDebug[key] = env[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* The currently active debug mode names, and names to skip.
|
||||
*/
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
/**
|
||||
* Map of special "%n" handling functions, for the debug "format" argument.
|
||||
*
|
||||
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
||||
*/
|
||||
createDebug.formatters = {};
|
||||
|
||||
/**
|
||||
* Selects a color for a debug namespace
|
||||
* @param {String} namespace The namespace string for the for the debug instance to be colored
|
||||
* @return {Number|String} An ANSI color code for the given namespace
|
||||
* @api private
|
||||
*/
|
||||
function selectColor(namespace) {
|
||||
let hash = 0;
|
||||
|
||||
for (let i = 0; i < namespace.length; i++) {
|
||||
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
|
||||
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
||||
}
|
||||
createDebug.selectColor = selectColor;
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `namespace`.
|
||||
*
|
||||
* @param {String} namespace
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
function createDebug(namespace) {
|
||||
let prevTime;
|
||||
let enableOverride = null;
|
||||
|
||||
function debug(...args) {
|
||||
// Disabled?
|
||||
if (!debug.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const self = debug;
|
||||
|
||||
// Set `diff` timestamp
|
||||
const curr = Number(new Date());
|
||||
const ms = curr - (prevTime || curr);
|
||||
self.diff = ms;
|
||||
self.prev = prevTime;
|
||||
self.curr = curr;
|
||||
prevTime = curr;
|
||||
|
||||
args[0] = createDebug.coerce(args[0]);
|
||||
|
||||
if (typeof args[0] !== 'string') {
|
||||
// Anything else let's inspect with %O
|
||||
args.unshift('%O');
|
||||
}
|
||||
|
||||
// Apply any `formatters` transformations
|
||||
let index = 0;
|
||||
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
||||
// If we encounter an escaped % then don't increase the array index
|
||||
if (match === '%%') {
|
||||
return '%';
|
||||
}
|
||||
index++;
|
||||
const formatter = createDebug.formatters[format];
|
||||
if (typeof formatter === 'function') {
|
||||
const val = args[index];
|
||||
match = formatter.call(self, val);
|
||||
|
||||
// Now we need to remove `args[index]` since it's inlined in the `format`
|
||||
args.splice(index, 1);
|
||||
index--;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
// Apply env-specific formatting (colors, etc.)
|
||||
createDebug.formatArgs.call(self, args);
|
||||
|
||||
const logFn = self.log || createDebug.log;
|
||||
logFn.apply(self, args);
|
||||
}
|
||||
|
||||
debug.namespace = namespace;
|
||||
debug.useColors = createDebug.useColors();
|
||||
debug.color = createDebug.selectColor(namespace);
|
||||
debug.extend = extend;
|
||||
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
||||
|
||||
Object.defineProperty(debug, 'enabled', {
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride,
|
||||
set: v => {
|
||||
enableOverride = v;
|
||||
}
|
||||
});
|
||||
|
||||
// Env-specific initialization logic for debug instances
|
||||
if (typeof createDebug.init === 'function') {
|
||||
createDebug.init(debug);
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
function extend(namespace, delimiter) {
|
||||
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
||||
newDebug.log = this.log;
|
||||
return newDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a debug mode by namespaces. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function enable(namespaces) {
|
||||
createDebug.save(namespaces);
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
let i;
|
||||
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
|
||||
const len = split.length;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!split[i]) {
|
||||
// ignore empty strings
|
||||
continue;
|
||||
}
|
||||
|
||||
namespaces = split[i].replace(/\*/g, '.*?');
|
||||
|
||||
if (namespaces[0] === '-') {
|
||||
createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
|
||||
} else {
|
||||
createDebug.names.push(new RegExp('^' + namespaces + '$'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @return {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function disable() {
|
||||
const namespaces = [
|
||||
...createDebug.names.map(toNamespace),
|
||||
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
|
||||
].join(',');
|
||||
createDebug.enable('');
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
function enabled(name) {
|
||||
if (name[name.length - 1] === '*') {
|
||||
return true;
|
||||
}
|
||||
|
||||
let i;
|
||||
let len;
|
||||
|
||||
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
||||
if (createDebug.skips[i].test(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, len = createDebug.names.length; i < len; i++) {
|
||||
if (createDebug.names[i].test(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert regexp to namespace
|
||||
*
|
||||
* @param {RegExp} regxep
|
||||
* @return {String} namespace
|
||||
* @api private
|
||||
*/
|
||||
function toNamespace(regexp) {
|
||||
return regexp.toString()
|
||||
.substring(2, regexp.toString().length - 2)
|
||||
.replace(/\.\*\?$/, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce `val`.
|
||||
*
|
||||
* @param {Mixed} val
|
||||
* @return {Mixed}
|
||||
* @api private
|
||||
*/
|
||||
function coerce(val) {
|
||||
if (val instanceof Error) {
|
||||
return val.stack || val.message;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX DO NOT USE. This is a temporary stub function.
|
||||
* XXX It WILL be removed in the next major release.
|
||||
*/
|
||||
function destroy() {
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
|
||||
createDebug.enable(createDebug.load());
|
||||
|
||||
return createDebug;
|
||||
}
|
||||
|
||||
module.exports = setup;
|
10
node_modules/lv_font_conv/node_modules/debug/src/index.js
generated
vendored
@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Detect Electron renderer / nwjs process, which is node, but we should
|
||||
* treat as a browser.
|
||||
*/
|
||||
|
||||
if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
|
||||
module.exports = require('./browser.js');
|
||||
} else {
|
||||
module.exports = require('./node.js');
|
||||
}
|
263
node_modules/lv_font_conv/node_modules/debug/src/node.js
generated
vendored
@ -1,263 +0,0 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const tty = require('tty');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* This is the Node.js implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.init = init;
|
||||
exports.log = log;
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.destroy = util.deprecate(
|
||||
() => {},
|
||||
'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [6, 2, 3, 4, 5, 1];
|
||||
|
||||
try {
|
||||
// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
const supportsColor = require('supports-color');
|
||||
|
||||
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
||||
exports.colors = [
|
||||
20,
|
||||
21,
|
||||
26,
|
||||
27,
|
||||
32,
|
||||
33,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
56,
|
||||
57,
|
||||
62,
|
||||
63,
|
||||
68,
|
||||
69,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
92,
|
||||
93,
|
||||
98,
|
||||
99,
|
||||
112,
|
||||
113,
|
||||
128,
|
||||
129,
|
||||
134,
|
||||
135,
|
||||
148,
|
||||
149,
|
||||
160,
|
||||
161,
|
||||
162,
|
||||
163,
|
||||
164,
|
||||
165,
|
||||
166,
|
||||
167,
|
||||
168,
|
||||
169,
|
||||
170,
|
||||
171,
|
||||
172,
|
||||
173,
|
||||
178,
|
||||
179,
|
||||
184,
|
||||
185,
|
||||
196,
|
||||
197,
|
||||
198,
|
||||
199,
|
||||
200,
|
||||
201,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
205,
|
||||
206,
|
||||
207,
|
||||
208,
|
||||
209,
|
||||
214,
|
||||
215,
|
||||
220,
|
||||
221
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow - we only care if `supports-color` is available; it doesn't have to be.
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the default `inspectOpts` object from the environment variables.
|
||||
*
|
||||
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
|
||||
*/
|
||||
|
||||
exports.inspectOpts = Object.keys(process.env).filter(key => {
|
||||
return /^debug_/i.test(key);
|
||||
}).reduce((obj, key) => {
|
||||
// Camel-case
|
||||
const prop = key
|
||||
.substring(6)
|
||||
.toLowerCase()
|
||||
.replace(/_([a-z])/g, (_, k) => {
|
||||
return k.toUpperCase();
|
||||
});
|
||||
|
||||
// Coerce string value into JS value
|
||||
let val = process.env[key];
|
||||
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
||||
val = true;
|
||||
} else if (/^(no|off|false|disabled)$/i.test(val)) {
|
||||
val = false;
|
||||
} else if (val === 'null') {
|
||||
val = null;
|
||||
} else {
|
||||
val = Number(val);
|
||||
}
|
||||
|
||||
obj[prop] = val;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
/**
|
||||
* Is stdout a TTY? Colored output is enabled when `true`.
|
||||
*/
|
||||
|
||||
function useColors() {
|
||||
return 'colors' in exports.inspectOpts ?
|
||||
Boolean(exports.inspectOpts.colors) :
|
||||
tty.isatty(process.stderr.fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ANSI color escape codes if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
const {namespace: name, useColors} = this;
|
||||
|
||||
if (useColors) {
|
||||
const c = this.color;
|
||||
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
|
||||
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
|
||||
|
||||
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
|
||||
args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
|
||||
} else {
|
||||
args[0] = getDate() + name + ' ' + args[0];
|
||||
}
|
||||
}
|
||||
|
||||
function getDate() {
|
||||
if (exports.inspectOpts.hideDate) {
|
||||
return '';
|
||||
}
|
||||
return new Date().toISOString() + ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `util.format()` with the specified arguments and writes to stderr.
|
||||
*/
|
||||
|
||||
function log(...args) {
|
||||
return process.stderr.write(util.format(...args) + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
if (namespaces) {
|
||||
process.env.DEBUG = namespaces;
|
||||
} else {
|
||||
// If you set a process.env field to null or undefined, it gets cast to the
|
||||
// string 'null' or 'undefined'. Just delete instead.
|
||||
delete process.env.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function load() {
|
||||
return process.env.DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init logic for `debug` instances.
|
||||
*
|
||||
* Create a new `inspectOpts` object in case `useColors` is set
|
||||
* differently for a particular `debug` instance.
|
||||
*/
|
||||
|
||||
function init(debug) {
|
||||
debug.inspectOpts = {};
|
||||
|
||||
const keys = Object.keys(exports.inspectOpts);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %o to `util.inspect()`, all on a single line.
|
||||
*/
|
||||
|
||||
formatters.o = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts)
|
||||
.split('\n')
|
||||
.map(str => str.trim())
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Map %O to `util.inspect()`, allowing multiple lines if needed.
|
||||
*/
|
||||
|
||||
formatters.O = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts);
|
||||
};
|
5
node_modules/lv_font_conv/node_modules/make-error/LICENSE
generated
vendored
@ -1,5 +0,0 @@
|
||||
Copyright 2014 Julien Fontanet
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
112
node_modules/lv_font_conv/node_modules/make-error/README.md
generated
vendored
@ -1,112 +0,0 @@
|
||||
# make-error
|
||||
|
||||
[![Package Version](https://badgen.net/npm/v/make-error)](https://npmjs.org/package/make-error) [![Build Status](https://travis-ci.org/JsCommunity/make-error.png?branch=master)](https://travis-ci.org/JsCommunity/make-error) [![PackagePhobia](https://badgen.net/packagephobia/install/make-error)](https://packagephobia.now.sh/result?p=make-error) [![Latest Commit](https://badgen.net/github/last-commit/JsCommunity/make-error)](https://github.com/JsCommunity/make-error/commits/master)
|
||||
|
||||
> Make your own error types!
|
||||
|
||||
## Features
|
||||
|
||||
- Compatible Node & browsers
|
||||
- `instanceof` support
|
||||
- `error.name` & `error.stack` support
|
||||
- compatible with [CSP](https://en.wikipedia.org/wiki/Content_Security_Policy) (i.e. no `eval()`)
|
||||
|
||||
## Installation
|
||||
|
||||
### Node & [Browserify](http://browserify.org/)/[Webpack](https://webpack.js.org/)
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/make-error):
|
||||
|
||||
```
|
||||
> npm install --save make-error
|
||||
```
|
||||
|
||||
Then require the package:
|
||||
|
||||
```javascript
|
||||
var makeError = require("make-error");
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
You can directly use the build provided at [unpkg.com](https://unpkg.com):
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/make-error@1/dist/make-error.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic named error
|
||||
|
||||
```javascript
|
||||
var CustomError = makeError("CustomError");
|
||||
|
||||
// Parameters are forwarded to the super class (here Error).
|
||||
throw new CustomError("a message");
|
||||
```
|
||||
|
||||
### Advanced error class
|
||||
|
||||
```javascript
|
||||
function CustomError(customValue) {
|
||||
CustomError.super.call(this, "custom error message");
|
||||
|
||||
this.customValue = customValue;
|
||||
}
|
||||
makeError(CustomError);
|
||||
|
||||
// Feel free to extend the prototype.
|
||||
CustomError.prototype.myMethod = function CustomError$myMethod() {
|
||||
console.log("CustomError.myMethod (%s, %s)", this.code, this.message);
|
||||
};
|
||||
|
||||
//-----
|
||||
|
||||
try {
|
||||
throw new CustomError(42);
|
||||
} catch (error) {
|
||||
error.myMethod();
|
||||
}
|
||||
```
|
||||
|
||||
### Specialized error
|
||||
|
||||
```javascript
|
||||
var SpecializedError = makeError("SpecializedError", CustomError);
|
||||
|
||||
throw new SpecializedError(42);
|
||||
```
|
||||
|
||||
### Inheritance
|
||||
|
||||
> Best for ES2015+.
|
||||
|
||||
```javascript
|
||||
import { BaseError } from "make-error";
|
||||
|
||||
class CustomError extends BaseError {
|
||||
constructor() {
|
||||
super("custom error message");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [make-error-cause](https://www.npmjs.com/package/make-error-cause): Make your own error types, with a cause!
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/JsCommunity/make-error/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Julien Fontanet](http://julien.isonoe.net)
|
1
node_modules/lv_font_conv/node_modules/make-error/dist/make-error.js
generated
vendored
@ -1 +0,0 @@
|
||||
!function(f){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=f();else if("function"==typeof define&&define.amd)define([],f);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).makeError=f()}}(function(){return function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}({1:[function(require,module,exports){"use strict";var construct="undefined"!=typeof Reflect?Reflect.construct:void 0,defineProperty=Object.defineProperty,captureStackTrace=Error.captureStackTrace;function BaseError(message){void 0!==message&&defineProperty(this,"message",{configurable:!0,value:message,writable:!0});var cname=this.constructor.name;void 0!==cname&&cname!==this.name&&defineProperty(this,"name",{configurable:!0,value:cname,writable:!0}),captureStackTrace(this,this.constructor)}void 0===captureStackTrace&&(captureStackTrace=function(error){var container=new Error;defineProperty(error,"stack",{configurable:!0,get:function(){var stack=container.stack;return defineProperty(this,"stack",{configurable:!0,value:stack,writable:!0}),stack},set:function(stack){defineProperty(error,"stack",{configurable:!0,value:stack,writable:!0})}})}),BaseError.prototype=Object.create(Error.prototype,{constructor:{configurable:!0,value:BaseError,writable:!0}});var setFunctionName=function(){function setFunctionName(fn,name){return defineProperty(fn,"name",{configurable:!0,value:name})}try{var f=function(){};if(setFunctionName(f,"foo"),"foo"===f.name)return setFunctionName}catch(_){}}();(module.exports=function(constructor,super_){if(null==super_||super_===Error)super_=BaseError;else if("function"!=typeof super_)throw new TypeError("super_ should be a function");var name;if("string"==typeof constructor)name=constructor,constructor=void 0!==construct?function(){return construct(super_,arguments,this.constructor)}:function(){super_.apply(this,arguments)},void 0!==setFunctionName&&(setFunctionName(constructor,name),name=void 0);else if("function"!=typeof constructor)throw new TypeError("constructor should be either a string or a function");constructor.super_=constructor.super=super_;var properties={constructor:{configurable:!0,value:constructor,writable:!0}};return void 0!==name&&(properties.name={configurable:!0,value:name,writable:!0}),constructor.prototype=Object.create(super_.prototype,properties),constructor}).BaseError=BaseError},{}]},{},[1])(1)});
|
47
node_modules/lv_font_conv/node_modules/make-error/index.d.ts
generated
vendored
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Create a new error constructor instance.
|
||||
*/
|
||||
declare function makeError(
|
||||
name: string
|
||||
): makeError.Constructor<makeError.BaseError>;
|
||||
|
||||
/**
|
||||
* Set the constructor prototype to `BaseError`.
|
||||
*/
|
||||
declare function makeError<T extends Error>(super_: {
|
||||
new (...args: any[]): T;
|
||||
}): makeError.Constructor<T & makeError.BaseError>;
|
||||
|
||||
/**
|
||||
* Create a specialized error instance.
|
||||
*/
|
||||
declare function makeError<T extends Error, K>(
|
||||
name: string | Function,
|
||||
super_: K
|
||||
): K & makeError.SpecializedConstructor<T>;
|
||||
|
||||
declare namespace makeError {
|
||||
/**
|
||||
* Use with ES2015+ inheritance.
|
||||
*/
|
||||
export class BaseError extends Error {
|
||||
message: string;
|
||||
name: string;
|
||||
stack: string;
|
||||
|
||||
constructor(message?: string);
|
||||
}
|
||||
|
||||
export interface Constructor<T> {
|
||||
new (message?: string): T;
|
||||
super_: any;
|
||||
prototype: T;
|
||||
}
|
||||
|
||||
export interface SpecializedConstructor<T> {
|
||||
super_: any;
|
||||
prototype: T;
|
||||
}
|
||||
}
|
||||
|
||||
export = makeError;
|
151
node_modules/lv_font_conv/node_modules/make-error/index.js
generated
vendored
@ -1,151 +0,0 @@
|
||||
// ISC @ Julien Fontanet
|
||||
|
||||
"use strict";
|
||||
|
||||
// ===================================================================
|
||||
|
||||
var construct = typeof Reflect !== "undefined" ? Reflect.construct : undefined;
|
||||
var defineProperty = Object.defineProperty;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
var captureStackTrace = Error.captureStackTrace;
|
||||
if (captureStackTrace === undefined) {
|
||||
captureStackTrace = function captureStackTrace(error) {
|
||||
var container = new Error();
|
||||
|
||||
defineProperty(error, "stack", {
|
||||
configurable: true,
|
||||
get: function getStack() {
|
||||
var stack = container.stack;
|
||||
|
||||
// Replace property with value for faster future accesses.
|
||||
defineProperty(this, "stack", {
|
||||
configurable: true,
|
||||
value: stack,
|
||||
writable: true,
|
||||
});
|
||||
|
||||
return stack;
|
||||
},
|
||||
set: function setStack(stack) {
|
||||
defineProperty(error, "stack", {
|
||||
configurable: true,
|
||||
value: stack,
|
||||
writable: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function BaseError(message) {
|
||||
if (message !== undefined) {
|
||||
defineProperty(this, "message", {
|
||||
configurable: true,
|
||||
value: message,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
|
||||
var cname = this.constructor.name;
|
||||
if (cname !== undefined && cname !== this.name) {
|
||||
defineProperty(this, "name", {
|
||||
configurable: true,
|
||||
value: cname,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
|
||||
captureStackTrace(this, this.constructor);
|
||||
}
|
||||
|
||||
BaseError.prototype = Object.create(Error.prototype, {
|
||||
// See: https://github.com/JsCommunity/make-error/issues/4
|
||||
constructor: {
|
||||
configurable: true,
|
||||
value: BaseError,
|
||||
writable: true,
|
||||
},
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Sets the name of a function if possible (depends of the JS engine).
|
||||
var setFunctionName = (function() {
|
||||
function setFunctionName(fn, name) {
|
||||
return defineProperty(fn, "name", {
|
||||
configurable: true,
|
||||
value: name,
|
||||
});
|
||||
}
|
||||
try {
|
||||
var f = function() {};
|
||||
setFunctionName(f, "foo");
|
||||
if (f.name === "foo") {
|
||||
return setFunctionName;
|
||||
}
|
||||
} catch (_) {}
|
||||
})();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function makeError(constructor, super_) {
|
||||
if (super_ == null || super_ === Error) {
|
||||
super_ = BaseError;
|
||||
} else if (typeof super_ !== "function") {
|
||||
throw new TypeError("super_ should be a function");
|
||||
}
|
||||
|
||||
var name;
|
||||
if (typeof constructor === "string") {
|
||||
name = constructor;
|
||||
constructor =
|
||||
construct !== undefined
|
||||
? function() {
|
||||
return construct(super_, arguments, this.constructor);
|
||||
}
|
||||
: function() {
|
||||
super_.apply(this, arguments);
|
||||
};
|
||||
|
||||
// If the name can be set, do it once and for all.
|
||||
if (setFunctionName !== undefined) {
|
||||
setFunctionName(constructor, name);
|
||||
name = undefined;
|
||||
}
|
||||
} else if (typeof constructor !== "function") {
|
||||
throw new TypeError("constructor should be either a string or a function");
|
||||
}
|
||||
|
||||
// Also register the super constructor also as `constructor.super_` just
|
||||
// like Node's `util.inherits()`.
|
||||
//
|
||||
// eslint-disable-next-line dot-notation
|
||||
constructor.super_ = constructor["super"] = super_;
|
||||
|
||||
var properties = {
|
||||
constructor: {
|
||||
configurable: true,
|
||||
value: constructor,
|
||||
writable: true,
|
||||
},
|
||||
};
|
||||
|
||||
// If the name could not be set on the constructor, set it on the
|
||||
// prototype.
|
||||
if (name !== undefined) {
|
||||
properties.name = {
|
||||
configurable: true,
|
||||
value: name,
|
||||
writable: true,
|
||||
};
|
||||
}
|
||||
constructor.prototype = Object.create(super_.prototype, properties);
|
||||
|
||||
return constructor;
|
||||
}
|
||||
exports = module.exports = makeError;
|
||||
exports.BaseError = BaseError;
|
95
node_modules/lv_font_conv/node_modules/make-error/package.json
generated
vendored
@ -1,95 +0,0 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"make-error@1.3.6",
|
||||
"/home/vitaly/Dropbox/Coding/lv_font_conv"
|
||||
]
|
||||
],
|
||||
"_from": "make-error@1.3.6",
|
||||
"_id": "make-error@1.3.6",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"_location": "/make-error",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "make-error@1.3.6",
|
||||
"name": "make-error",
|
||||
"escapedName": "make-error",
|
||||
"rawSpec": "1.3.6",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "1.3.6"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"_spec": "1.3.6",
|
||||
"_where": "/home/vitaly/Dropbox/Coding/lv_font_conv",
|
||||
"author": {
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@isonoe.net"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/JsCommunity/make-error/issues"
|
||||
},
|
||||
"description": "Make your own error types!",
|
||||
"devDependencies": {
|
||||
"browserify": "^16.2.3",
|
||||
"eslint": "^6.5.1",
|
||||
"eslint-config-prettier": "^6.4.0",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-node": "^10.0.0",
|
||||
"eslint-plugin-promise": "^4.0.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"husky": "^3.0.9",
|
||||
"jest": "^24",
|
||||
"prettier": "^1.14.3",
|
||||
"uglify-js": "^3.3.2"
|
||||
},
|
||||
"files": [
|
||||
"dist/",
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"homepage": "https://github.com/JsCommunity/make-error",
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"commit-msg": "npm run test"
|
||||
}
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "node"
|
||||
},
|
||||
"keywords": [
|
||||
"create",
|
||||
"custom",
|
||||
"derive",
|
||||
"error",
|
||||
"errors",
|
||||
"extend",
|
||||
"extending",
|
||||
"extension",
|
||||
"factory",
|
||||
"inherit",
|
||||
"make",
|
||||
"subclass"
|
||||
],
|
||||
"license": "ISC",
|
||||
"main": "index.js",
|
||||
"name": "make-error",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/JsCommunity/make-error.git"
|
||||
},
|
||||
"scripts": {
|
||||
"dev-test": "jest --watch",
|
||||
"format": "prettier --write '**'",
|
||||
"prepublishOnly": "mkdir -p dist && browserify -s makeError index.js | uglifyjs -c > dist/make-error.js",
|
||||
"pretest": "eslint --ignore-path .gitignore .",
|
||||
"test": "jest"
|
||||
},
|
||||
"version": "1.3.6"
|
||||
}
|
15
node_modules/lv_font_conv/node_modules/mkdirp/CHANGELOG.md
generated
vendored
@ -1,15 +0,0 @@
|
||||
# Changers Lorgs!
|
||||
|
||||
## 1.0
|
||||
|
||||
Full rewrite. Essentially a brand new module.
|
||||
|
||||
- Return a promise instead of taking a callback.
|
||||
- Use native `fs.mkdir(path, { recursive: true })` when available.
|
||||
- Drop support for outdated Node.js versions. (Technically still works on
|
||||
Node.js v8, but only 10 and above are officially supported.)
|
||||
|
||||
## 0.x
|
||||
|
||||
Original and most widely used recursive directory creation implementation
|
||||
in JavaScript, dating back to 2010.
|
21
node_modules/lv_font_conv/node_modules/mkdirp/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me)
|
||||
|
||||
This project is free software released under the MIT license:
|
||||
|
||||
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.
|
68
node_modules/lv_font_conv/node_modules/mkdirp/bin/cmd.js
generated
vendored
@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const usage = () => `
|
||||
usage: mkdirp [DIR1,DIR2..] {OPTIONS}
|
||||
|
||||
Create each supplied directory including any necessary parent directories
|
||||
that don't yet exist.
|
||||
|
||||
If the directory already exists, do nothing.
|
||||
|
||||
OPTIONS are:
|
||||
|
||||
-m<mode> If a directory needs to be created, set the mode as an octal
|
||||
--mode=<mode> permission string.
|
||||
|
||||
-v --version Print the mkdirp version number
|
||||
|
||||
-h --help Print this helpful banner
|
||||
|
||||
-p --print Print the first directories created for each path provided
|
||||
|
||||
--manual Use manual implementation, even if native is available
|
||||
`
|
||||
|
||||
const dirs = []
|
||||
const opts = {}
|
||||
let print = false
|
||||
let dashdash = false
|
||||
let manual = false
|
||||
for (const arg of process.argv.slice(2)) {
|
||||
if (dashdash)
|
||||
dirs.push(arg)
|
||||
else if (arg === '--')
|
||||
dashdash = true
|
||||
else if (arg === '--manual')
|
||||
manual = true
|
||||
else if (/^-h/.test(arg) || /^--help/.test(arg)) {
|
||||
console.log(usage())
|
||||
process.exit(0)
|
||||
} else if (arg === '-v' || arg === '--version') {
|
||||
console.log(require('../package.json').version)
|
||||
process.exit(0)
|
||||
} else if (arg === '-p' || arg === '--print') {
|
||||
print = true
|
||||
} else if (/^-m/.test(arg) || /^--mode=/.test(arg)) {
|
||||
const mode = parseInt(arg.replace(/^(-m|--mode=)/, ''), 8)
|
||||
if (isNaN(mode)) {
|
||||
console.error(`invalid mode argument: ${arg}\nMust be an octal number.`)
|
||||
process.exit(1)
|
||||
}
|
||||
opts.mode = mode
|
||||
} else
|
||||
dirs.push(arg)
|
||||
}
|
||||
|
||||
const mkdirp = require('../')
|
||||
const impl = manual ? mkdirp.manual : mkdirp
|
||||
if (dirs.length === 0)
|
||||
console.error(usage())
|
||||
|
||||
Promise.all(dirs.map(dir => impl(dir, opts)))
|
||||
.then(made => print ? made.forEach(m => m && console.log(m)) : null)
|
||||
.catch(er => {
|
||||
console.error(er.message)
|
||||
if (er.code)
|
||||
console.error(' code: ' + er.code)
|
||||
process.exit(1)
|
||||
})
|
31
node_modules/lv_font_conv/node_modules/mkdirp/index.js
generated
vendored
@ -1,31 +0,0 @@
|
||||
const optsArg = require('./lib/opts-arg.js')
|
||||
const pathArg = require('./lib/path-arg.js')
|
||||
|
||||
const {mkdirpNative, mkdirpNativeSync} = require('./lib/mkdirp-native.js')
|
||||
const {mkdirpManual, mkdirpManualSync} = require('./lib/mkdirp-manual.js')
|
||||
const {useNative, useNativeSync} = require('./lib/use-native.js')
|
||||
|
||||
|
||||
const mkdirp = (path, opts) => {
|
||||
path = pathArg(path)
|
||||
opts = optsArg(opts)
|
||||
return useNative(opts)
|
||||
? mkdirpNative(path, opts)
|
||||
: mkdirpManual(path, opts)
|
||||
}
|
||||
|
||||
const mkdirpSync = (path, opts) => {
|
||||
path = pathArg(path)
|
||||
opts = optsArg(opts)
|
||||
return useNativeSync(opts)
|
||||
? mkdirpNativeSync(path, opts)
|
||||
: mkdirpManualSync(path, opts)
|
||||
}
|
||||
|
||||
mkdirp.sync = mkdirpSync
|
||||
mkdirp.native = (path, opts) => mkdirpNative(pathArg(path), optsArg(opts))
|
||||
mkdirp.manual = (path, opts) => mkdirpManual(pathArg(path), optsArg(opts))
|
||||
mkdirp.nativeSync = (path, opts) => mkdirpNativeSync(pathArg(path), optsArg(opts))
|
||||
mkdirp.manualSync = (path, opts) => mkdirpManualSync(pathArg(path), optsArg(opts))
|
||||
|
||||
module.exports = mkdirp
|