mirror of
https://github.com/curioustorvald/Terrarum-sans-bitmap.git
synced 2026-06-06 14:08:30 +09:00
Compare commits
21 Commits
f4e1db5846
...
v1.16.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af334ad20b | ||
|
|
55ad8ee943 | ||
|
|
e9fcf6bbce | ||
|
|
45d5b758e3 | ||
|
|
d3ae868723 | ||
|
|
372ae9b354 | ||
|
|
45027be83c | ||
|
|
6bc365fc57 | ||
|
|
69f868c3e8 | ||
|
|
a1147c8611 | ||
|
|
4bd8febfdf | ||
|
|
04fbddb200 | ||
|
|
fb935ab28f | ||
|
|
6c65cfc0a1 | ||
|
|
c5c2ae4022 | ||
|
|
2279873222 | ||
|
|
4dbcbb7df5 | ||
|
|
ad4a044ace | ||
|
|
9ca8117b5f | ||
|
|
76f223aee8 | ||
|
|
662dc5b093 |
30
.claude/settings.local.json
Normal file
30
.claude/settings.local.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"WebFetch(domain:github.com)",
|
||||||
|
"WebSearch",
|
||||||
|
"Bash(head:*)",
|
||||||
|
"WebFetch(domain:gitlab.com)",
|
||||||
|
"Bash(java:*)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"Bash(jar tf:*)",
|
||||||
|
"Bash(chmod +x:*)",
|
||||||
|
"WebFetch(domain:fontforge.org)",
|
||||||
|
"WebFetch(domain:fonttools.readthedocs.io)",
|
||||||
|
"Bash(grep:*)",
|
||||||
|
"Bash(tail:*)",
|
||||||
|
"Bash(python3:*)",
|
||||||
|
"Bash(make:*)",
|
||||||
|
"Bash(git stash:*)",
|
||||||
|
"Bash(./autokem*)",
|
||||||
|
"Bash(cmp:*)",
|
||||||
|
"Bash(wc:*)",
|
||||||
|
"Bash(pip3:*)",
|
||||||
|
"Bash(pip install:*)",
|
||||||
|
"Bash(.venv/bin/python3:*)",
|
||||||
|
"Bash(.venv/bin/python:*)",
|
||||||
|
"Bash(find:*)",
|
||||||
|
"Skill(update-config)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
93
.claude/skills/add-unicode-block/SKILL.md
Normal file
93
.claude/skills/add-unicode-block/SKILL.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
name: add-unicode-block
|
||||||
|
description: Add a new Unicode script/block to the Terrarum Sans Bitmap font engine.
|
||||||
|
---
|
||||||
|
# Add Unicode Block
|
||||||
|
|
||||||
|
## Required inputs
|
||||||
|
|
||||||
|
The user must supply:
|
||||||
|
- **Script name** — human-readable name used in constant/function names (e.g. `Ogham`, `LatinExtE`)
|
||||||
|
- **TGA filename** — the sprite sheet filename without path (e.g. `ogham_variable.tga`)
|
||||||
|
- **Unicode range** — start and end codepoints inclusive (e.g. `U+1680..U+169F`)
|
||||||
|
|
||||||
|
If any of these are missing, ask for them before proceeding. Extra directions can be given after Unicode range.
|
||||||
|
|
||||||
|
## Step 1 — Determine the next sheet index
|
||||||
|
|
||||||
|
Read the sheet index constants from both files to find the current highest index (excluding `SHEET_UNKNOWN = 254`):
|
||||||
|
|
||||||
|
- Kotlin: `src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt` — grep for `internal const val SHEET_`
|
||||||
|
- Python: `OTFbuild/sheet_config.py` — grep for `^SHEET_`
|
||||||
|
|
||||||
|
The new index = highest existing index + 1.
|
||||||
|
|
||||||
|
## Step 2 — Derive identifiers
|
||||||
|
|
||||||
|
From the script name, derive:
|
||||||
|
- **Kotlin constant**: `SHEET_<UPPER_SNAKE>_VARW` (e.g. `SHEET_OGHAM_VARW`)
|
||||||
|
- **Kotlin indexY function**: `<camelCase>IndexY` (e.g. `oghamIndexY`)
|
||||||
|
- **Python constant**: same as Kotlin constant
|
||||||
|
- **Range start hex**: the lower bound codepoint as a `0x`-prefixed Kotlin/Python literal
|
||||||
|
|
||||||
|
## Step 3 — Edit both files
|
||||||
|
|
||||||
|
Make all 6 edits. Read each section before editing.
|
||||||
|
|
||||||
|
### Kotlin: `src/net/torvald/terrarumsansbitmap/gdx/TerrarumSansBitmap.kt`
|
||||||
|
|
||||||
|
**a) Sheet index constant** — find the block of `internal const val SHEET_*` constants (just before `SHEET_UNKNOWN = 254`) and append:
|
||||||
|
```kotlin
|
||||||
|
internal const val SHEET_<NAME>_VARW = <INDEX>
|
||||||
|
```
|
||||||
|
|
||||||
|
**b) fileList entry** — find `internal val fileList` array and append before the closing `)`:
|
||||||
|
```kotlin
|
||||||
|
"<tga_filename>",
|
||||||
|
```
|
||||||
|
|
||||||
|
**c) codeRange entry** — find `internal val codeRange` array and append before the closing `)`:
|
||||||
|
```kotlin
|
||||||
|
0x<START>..<0x<END>, // SHEET_<NAME>_VARW
|
||||||
|
```
|
||||||
|
Use `+` to combine non-contiguous ranges if needed.
|
||||||
|
|
||||||
|
**d) getSheetwisePosition when-branch** — find the `when` block that dispatches to indexY functions (just before `else -> ch / 16`) and append:
|
||||||
|
```kotlin
|
||||||
|
SHEET_<NAME>_VARW -> <camelCase>IndexY(ch)
|
||||||
|
```
|
||||||
|
|
||||||
|
**e) indexY function** — find the block of private `*IndexY` functions near the bottom of the companion object and append:
|
||||||
|
```kotlin
|
||||||
|
private fun <camelCase>IndexY(c: CodePoint) = (c - 0x<START>) / 16
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python: `OTFbuild/sheet_config.py`
|
||||||
|
|
||||||
|
**f) Sheet index constant** — find the block of `SHEET_* = <n>` constants (just before `SHEET_UNKNOWN = 254`) and append:
|
||||||
|
```python
|
||||||
|
SHEET_<NAME>_VARW = <INDEX>
|
||||||
|
```
|
||||||
|
|
||||||
|
**g) FILE_LIST entry** — find `FILE_LIST = [` array and append before the closing `]`:
|
||||||
|
```python
|
||||||
|
"<tga_filename>",
|
||||||
|
```
|
||||||
|
|
||||||
|
**h) CODE_RANGE entry** — find `CODE_RANGE = [` array and append before the closing `]`:
|
||||||
|
```python
|
||||||
|
list(range(0x<START>, 0x<END+1>)), # <INDEX>: <ScriptName>
|
||||||
|
```
|
||||||
|
|
||||||
|
**i) index_y lambda** — find the dict in `get_index_y(sheet_index, c)` (just before `SHEET_HANGUL: lambda: 0`) and append:
|
||||||
|
```python
|
||||||
|
SHEET_<NAME>_VARW: lambda: (c - 0x<START>) // 16,
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 4 — Verify
|
||||||
|
|
||||||
|
After all edits, confirm:
|
||||||
|
1. The Kotlin constant, fileList, codeRange, when-branch, and indexY function are all present and consistent.
|
||||||
|
2. The Python constant, FILE_LIST, CODE_RANGE, and index_y lambda are all present and consistent.
|
||||||
|
3. The indices in both files match.
|
||||||
|
4. The range end in `CODE_RANGE` is `end + 1` (Python `range` is exclusive).
|
||||||
BIN
Autokem/autokem.safetensors
LFS
BIN
Autokem/autokem.safetensors
LFS
Binary file not shown.
@@ -28,7 +28,7 @@ from keming_machine import generate_kerning_pairs
|
|||||||
from opentype_features import generate_features, glyph_name
|
from opentype_features import generate_features, glyph_name
|
||||||
import sheet_config as SC
|
import sheet_config as SC
|
||||||
|
|
||||||
FONT_VERSION = "1.15"
|
FONT_VERSION = "1.16"
|
||||||
|
|
||||||
# Codepoints that get cmap entries (user-visible)
|
# Codepoints that get cmap entries (user-visible)
|
||||||
# PUA forms used internally by GSUB get glyphs but NO cmap entries
|
# PUA forms used internally by GSUB get glyphs but NO cmap entries
|
||||||
@@ -332,6 +332,7 @@ def build_font(assets_dir, output_path, no_bitmap=False, no_features=False):
|
|||||||
charstrings[".notdef"] = pen.getCharString()
|
charstrings[".notdef"] = pen.getCharString()
|
||||||
|
|
||||||
_unihan_cps = set(SC.CODE_RANGE[SC.SHEET_UNIHAN])
|
_unihan_cps = set(SC.CODE_RANGE[SC.SHEET_UNIHAN])
|
||||||
|
_emoji1_cps = set(SC.CODE_RANGE[SC.SHEET_EMOJI1])
|
||||||
_base_offsets = {} # glyph_name -> (x_offset, y_offset) for COLR layers
|
_base_offsets = {} # glyph_name -> (x_offset, y_offset) for COLR layers
|
||||||
|
|
||||||
traced_count = 0
|
traced_count = 0
|
||||||
@@ -382,6 +383,10 @@ def build_font(assets_dir, output_path, no_bitmap=False, no_features=False):
|
|||||||
if cp in _unihan_cps:
|
if cp in _unihan_cps:
|
||||||
y_offset -= ((SC.H - SC.H_UNIHAN) // 2) * SCALE
|
y_offset -= ((SC.H - SC.H_UNIHAN) // 2) * SCALE
|
||||||
|
|
||||||
|
# Emoji1 glyphs are 16px tall in a 20px cell; same 2px top/bottom padding.
|
||||||
|
if cp in _emoji1_cps:
|
||||||
|
y_offset -= ((SC.H - SC.H_EMOJI1) // 2) * SCALE
|
||||||
|
|
||||||
# Hangul jungseong/jongseong PUA variants (rows 15-18) have zero
|
# Hangul jungseong/jongseong PUA variants (rows 15-18) have zero
|
||||||
# advance and overlay the preceding choseong. Shift their outlines
|
# advance and overlay the preceding choseong. Shift their outlines
|
||||||
# left by one syllable cell width so they render at the same position.
|
# left by one syllable cell width so they render at the same position.
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import sheet_config as SC
|
|||||||
|
|
||||||
# PUA range for Hangul jamo variant storage.
|
# PUA range for Hangul jamo variant storage.
|
||||||
# We need space for: max_col * max_row variants.
|
# We need space for: max_col * max_row variants.
|
||||||
# Using 0xF0600-0xF1E7F
|
# Using 0x100000-0x10187F
|
||||||
HANGUL_PUA_BASE = 0xF0600
|
HANGUL_PUA_BASE = 0x100000
|
||||||
|
|
||||||
|
|
||||||
def _compose_bitmaps(a, b, w, h):
|
def _compose_bitmaps(a, b, w, h):
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ def _generate_hangul_gsub(glyphs, has, jamo_data):
|
|||||||
continue
|
continue
|
||||||
for f in [0, 1]:
|
for f in [0, 1]:
|
||||||
try:
|
try:
|
||||||
row_ng = SC.get_han_initial_row(1, idx, f)
|
row_ng = SC.get_han_initial_row(2, idx, f)
|
||||||
except (ValueError, KeyError):
|
except (ValueError, KeyError):
|
||||||
continue
|
continue
|
||||||
jung_groups_general.setdefault((row_ng, f), []).append(jcp)
|
jung_groups_general.setdefault((row_ng, f), []).append(jcp)
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ Ported from TerrarumSansBitmap.kt companion object and SheetConfig.kt.
|
|||||||
# Font metrics
|
# Font metrics
|
||||||
H = 20
|
H = 20
|
||||||
H_UNIHAN = 16
|
H_UNIHAN = 16
|
||||||
|
H_EMOJI1 = 16
|
||||||
W_HANGUL_BASE = 13
|
W_HANGUL_BASE = 13
|
||||||
W_UNIHAN = 16
|
W_UNIHAN = 16
|
||||||
|
W_EMOJI1 = 17
|
||||||
W_LATIN_WIDE = 9
|
W_LATIN_WIDE = 9
|
||||||
W_VAR_INIT = 15
|
W_VAR_INIT = 15
|
||||||
W_WIDEVAR_INIT = 31
|
W_WIDEVAR_INIT = 31
|
||||||
@@ -78,6 +80,12 @@ SHEET_CYRILIC_EXTC_VARW = 44
|
|||||||
SHEET_LATIN_EXTE_VARW = 45
|
SHEET_LATIN_EXTE_VARW = 45
|
||||||
SHEET_LATIN_EXTF_VARW = 46
|
SHEET_LATIN_EXTF_VARW = 46
|
||||||
SHEET_LATIN_EXTG_VARW = 47
|
SHEET_LATIN_EXTG_VARW = 47
|
||||||
|
SHEET_OGHAM_VARW = 48
|
||||||
|
SHEET_COPTIC_VARW = 49
|
||||||
|
SHEET_CYRILIC_EXTD_VARW = 50
|
||||||
|
SHEET_MATHS1_VARW = 51
|
||||||
|
SHEET_EMOJI1 = 52
|
||||||
|
SHEET_ENCLOSED_ALPHNUM_VARW = 53
|
||||||
|
|
||||||
SHEET_UNKNOWN = 254
|
SHEET_UNKNOWN = 254
|
||||||
|
|
||||||
@@ -130,6 +138,12 @@ FILE_LIST = [
|
|||||||
"latinExtE_variable.tga",
|
"latinExtE_variable.tga",
|
||||||
"latinExtF_variable.tga",
|
"latinExtF_variable.tga",
|
||||||
"latinExtG_variable.tga",
|
"latinExtG_variable.tga",
|
||||||
|
"ogham_variable.tga",
|
||||||
|
"coptic_variable.tga",
|
||||||
|
"cyrilic_extD_variable.tga",
|
||||||
|
"maths1_extrawide_variable.tga",
|
||||||
|
"emoji1.tga",
|
||||||
|
"enclosed_alphanumeric_variable.tga",
|
||||||
]
|
]
|
||||||
|
|
||||||
CODE_RANGE = [
|
CODE_RANGE = [
|
||||||
@@ -173,7 +187,7 @@ CODE_RANGE = [
|
|||||||
list(range(0xF0520, 0xF0580)), # 37: Codestyle ASCII
|
list(range(0xF0520, 0xF0580)), # 37: Codestyle ASCII
|
||||||
list(range(0xFB00, 0xFB18)), # 38: Alphabetic Presentation
|
list(range(0xFB00, 0xFB18)), # 38: Alphabetic Presentation
|
||||||
list(range(0x1B000, 0x1B170)), # 39: Hentaigana
|
list(range(0x1B000, 0x1B170)), # 39: Hentaigana
|
||||||
list(range(0x2400, 0x2440)), # 40: Control Pictures
|
list(range(0x2400, 0x2450)), # 40: Control Pictures
|
||||||
list(range(0x1FB00, 0x1FC00)), # 41: Legacy Computing
|
list(range(0x1FB00, 0x1FC00)), # 41: Legacy Computing
|
||||||
list(range(0xA640, 0xA6A0)), # 42: Cyrillic Ext B
|
list(range(0xA640, 0xA6A0)), # 42: Cyrillic Ext B
|
||||||
list(range(0x2DE0, 0x2E00)), # 43: Cyrillic Ext A
|
list(range(0x2DE0, 0x2E00)), # 43: Cyrillic Ext A
|
||||||
@@ -181,6 +195,12 @@ CODE_RANGE = [
|
|||||||
list(range(0xAB30, 0xAB70)), # 45: Latin Ext E
|
list(range(0xAB30, 0xAB70)), # 45: Latin Ext E
|
||||||
list(range(0x10780, 0x107C0)), # 46: Latin Ext F
|
list(range(0x10780, 0x107C0)), # 46: Latin Ext F
|
||||||
list(range(0x1DF00, 0x1E000)), # 47: Latin Ext G
|
list(range(0x1DF00, 0x1E000)), # 47: Latin Ext G
|
||||||
|
list(range(0x1680, 0x16A0)), # 48: Ogham
|
||||||
|
list(range(0x2C80, 0x2D00)), # 49: Coptic
|
||||||
|
list(range(0x1E030, 0x1E090)), # 50: Cyrillic Ext D
|
||||||
|
list(range(0x2200, 0x2400)), # 51: Maths1
|
||||||
|
list(range(0x1F600, 0x1F650)), # 52: Emoji1
|
||||||
|
list(range(0x2460, 0x2500)), # 53: Enclosed Alphanum
|
||||||
]
|
]
|
||||||
|
|
||||||
CODE_RANGE_HANGUL_COMPAT = range(0x3130, 0x3190)
|
CODE_RANGE_HANGUL_COMPAT = range(0x3130, 0x3190)
|
||||||
@@ -262,6 +282,8 @@ def get_cell_width(sheet_index):
|
|||||||
return W_VAR_INIT + HGAP_VAR # 16
|
return W_VAR_INIT + HGAP_VAR # 16
|
||||||
if sheet_index == SHEET_UNIHAN:
|
if sheet_index == SHEET_UNIHAN:
|
||||||
return W_UNIHAN
|
return W_UNIHAN
|
||||||
|
if sheet_index == SHEET_EMOJI1:
|
||||||
|
return W_EMOJI1
|
||||||
if sheet_index == SHEET_HANGUL:
|
if sheet_index == SHEET_HANGUL:
|
||||||
return W_HANGUL_BASE
|
return W_HANGUL_BASE
|
||||||
if sheet_index == SHEET_CUSTOM_SYM:
|
if sheet_index == SHEET_CUSTOM_SYM:
|
||||||
@@ -274,6 +296,8 @@ def get_cell_width(sheet_index):
|
|||||||
def get_cell_height(sheet_index):
|
def get_cell_height(sheet_index):
|
||||||
if sheet_index == SHEET_UNIHAN:
|
if sheet_index == SHEET_UNIHAN:
|
||||||
return H_UNIHAN
|
return H_UNIHAN
|
||||||
|
if sheet_index == SHEET_EMOJI1:
|
||||||
|
return H_EMOJI1
|
||||||
if sheet_index == SHEET_CUSTOM_SYM:
|
if sheet_index == SHEET_CUSTOM_SYM:
|
||||||
return SIZE_CUSTOM_SYM
|
return SIZE_CUSTOM_SYM
|
||||||
return H
|
return H
|
||||||
@@ -563,5 +587,11 @@ def index_y(sheet_index, c):
|
|||||||
SHEET_LATIN_EXTE_VARW: lambda: (c - 0xAB30) // 16,
|
SHEET_LATIN_EXTE_VARW: lambda: (c - 0xAB30) // 16,
|
||||||
SHEET_LATIN_EXTF_VARW: lambda: (c - 0x10780) // 16,
|
SHEET_LATIN_EXTF_VARW: lambda: (c - 0x10780) // 16,
|
||||||
SHEET_LATIN_EXTG_VARW: lambda: (c - 0x1DF00) // 16,
|
SHEET_LATIN_EXTG_VARW: lambda: (c - 0x1DF00) // 16,
|
||||||
|
SHEET_OGHAM_VARW: lambda: (c - 0x1680) // 16,
|
||||||
|
SHEET_COPTIC_VARW: lambda: (c - 0x2C80) // 16,
|
||||||
|
SHEET_CYRILIC_EXTD_VARW: lambda: (c - 0x1E030) // 16,
|
||||||
|
SHEET_MATHS1_VARW: lambda: (c - 0x2200) // 16,
|
||||||
|
SHEET_EMOJI1: lambda: (c - 0x1F600) // 16,
|
||||||
|
SHEET_ENCLOSED_ALPHNUM_VARW: lambda: (c - 0x2460) // 16,
|
||||||
SHEET_HANGUL: lambda: 0,
|
SHEET_HANGUL: lambda: 0,
|
||||||
}.get(sheet_index, lambda: c // 16)()
|
}.get(sheet_index, lambda: c // 16)()
|
||||||
|
|||||||
Binary file not shown.
BIN
demo.PNG
BIN
demo.PNG
Binary file not shown.
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 180 KiB |
@@ -26,13 +26,13 @@ How multilingual? Real multilingual!
|
|||||||
Под южно дърво, цъфтящо в синьо, бягаше малко пухкаво зайче
|
Под южно дърво, цъфтящо в синьо, бягаше малко пухкаво зайче
|
||||||
ᎠᏍᎦᏯᎡᎦᎢᎾᎨᎢᎣᏍᏓᎤᎩᏍᏗᎥᎴᏓᎯᎲᎢᏔᎵᏕᎦᏟᏗᏖᎸᎳᏗᏗᎧᎵᎢᏘᎴᎩ ᏙᏱᏗᏜᏫᏗᏣᏚᎦᏫᏛᏄᏓᎦᏝᏃᎠᎾᏗᎭᏞᎦᎯᎦᏘᏓᏠᎨᏏᏕᏡᎬᏢᏓᏥᏩᏝᎡᎢᎪᎢ ᎠᎦᏂᏗᎮᎢᎫᎩᎬᏩᎴᎢᎠᏆᏅᏛᎫᏊᎾᎥᎠᏁᏙᎲᏐᏈᎵᎤᎩᎸᏓᏭᎷᏤᎢᏏᏉᏯᏌᏊ ᎤᏂᏋᎢᏡᎬᎢᎰᏩᎬᏤᎵᏍᏗᏱᎩᎱᎱᎤᎩᎴᎢᏦᎢᎠᏂᏧᏣᏨᎦᏥᎪᎥᏌᏊᎤᎶᏒᎢᎢᏡᎬᎢ ᎹᎦᎺᎵᏥᎻᎼᏏᎽᏗᏩᏂᎦᏘᎾᎿᎠᏁᎬᎢᏅᎩᎾᏂᎡᎢᏌᎶᎵᏎᎷᎠᏑᏍᏗᏪᎩ ᎠᎴ ᏬᏗᏲᏭᎾᏓᏍᏓᏴᏁᎢᎤᎦᏅᏮᏰᎵᏳᏂᎨᎢ
|
ᎠᏍᎦᏯᎡᎦᎢᎾᎨᎢᎣᏍᏓᎤᎩᏍᏗᎥᎴᏓᎯᎲᎢᏔᎵᏕᎦᏟᏗᏖᎸᎳᏗᏗᎧᎵᎢᏘᎴᎩ ᏙᏱᏗᏜᏫᏗᏣᏚᎦᏫᏛᏄᏓᎦᏝᏃᎠᎾᏗᎭᏞᎦᎯᎦᏘᏓᏠᎨᏏᏕᏡᎬᏢᏓᏥᏩᏝᎡᎢᎪᎢ ᎠᎦᏂᏗᎮᎢᎫᎩᎬᏩᎴᎢᎠᏆᏅᏛᎫᏊᎾᎥᎠᏁᏙᎲᏐᏈᎵᎤᎩᎸᏓᏭᎷᏤᎢᏏᏉᏯᏌᏊ ᎤᏂᏋᎢᏡᎬᎢᎰᏩᎬᏤᎵᏍᏗᏱᎩᎱᎱᎤᎩᎴᎢᏦᎢᎠᏂᏧᏣᏨᎦᏥᎪᎥᏌᏊᎤᎶᏒᎢᎢᏡᎬᎢ ᎹᎦᎺᎵᏥᎻᎼᏏᎽᏗᏩᏂᎦᏘᎾᎿᎠᏁᎬᎢᏅᎩᎾᏂᎡᎢᏌᎶᎵᏎᎷᎠᏑᏍᏗᏪᎩ ᎠᎴ ᏬᏗᏲᏭᎾᏓᏍᏓᏴᏁᎢᎤᎦᏅᏮᏰᎵᏳᏂᎨᎢ
|
||||||
Ѳеѡфа́нъ и҆ Алеѯі́й, ѕѣлѡ̀ возлюби́вше ѱалти́рь, воспѣ́ша при свѣ́тѣ ѕвѣ́здъ, помазꙋ́юще сщ҃е́нное мѵ́ро; серафими мн̑оꙮ҆читїи̑, ꙗ҆́кѡ ѻ҆́гнь, ѡ҆крꙋжа́хꙋ прⷭ҇то́лъ Бж҃їй, и҆ всѧ̀ землѧ̀ и҆спо́лнисѧ свѣ́та, ꙗ҆́кѡ ѕмі́й попра́нъ є҆́сть
|
Ѳеѡфа́нъ и҆ Алеѯі́й, ѕѣлѡ̀ возлюби́вше ѱалти́рь, воспѣ́ша при свѣ́тѣ ѕвѣ́здъ, помазꙋ́юще сщ҃е́нное мѵ́ро; серафими мн̑оꙮ҆читїи̑, ꙗ҆́кѡ ѻ҆́гнь, ѡ҆крꙋжа́хꙋ прⷭ҇то́лъ Бж҃їй, и҆ всѧ̀ землѧ̀ и҆спо́лнисѧ свѣ́та, ꙗ҆́кѡ ѕмі́й попра́нъ є҆́сть
|
||||||
|
ⲡⲓⲝⲉⲛⲟⲥ ⲅⲁⲣ ⲁϥϫⲉⲙ ⲟⲩⲫⲱⲥ ϧⲉⲛ ⲡⲓⲍⲏⲗⲟⲥ ⲛⲧⲉ ϯⲯⲩⲭⲏ· ⲁϥϣⲱⲡⲓ ⲇⲉ ⲕⲁⲧⲁ ⲡⲓⲑⲉⲗⲏⲙⲁ· ⲁϥϭⲓ ⲛϩⲱⲃ ⲛⲓⲃⲉⲛ ⲟⲩⲟϩ ⲁϥϯⲙⲟⲧ
|
||||||
Příliš žluťoučký kůň úpěl ďábelské ódy
|
Příliš žluťoučký kůň úpěl ďábelské ódy
|
||||||
Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon
|
Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Walther spillede på xylofon
|
||||||
PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS
|
Sphinx of black quartz, judge my vow
|
||||||
hƿæt ƿe ᵹardena inᵹear ꝺaᵹum þeoꝺ cynninᵹa þꞃym ᵹeꝼꞃumon
|
hƿæt ƿe ᵹardena inᵹear ꝺaᵹum þeoꝺ cynninᵹa þꞃym ᵹeꝼꞃumon
|
||||||
Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich GROẞEN GROẞE
|
Victor jagt zwölf Boxkämpfer quer über den GROẞEN Sylter Deich
|
||||||
ζαφείρι δέξου πάγκαλο, βαθῶν ψυχῆς τὸ σῆμα
|
ζαφείρι δέξου πάγκαλο, βαθῶν ψυχῆς τὸ σῆμα
|
||||||
ΔΙΑΦΥΛΆΞΤΕ ΓΕΝΙΚΆ ΤΗ ΖΩΉ ΣΑΣ ΑΠΌ ΒΑΘΕΙΆ ΨΥΧΙΚΆ ΤΡΑΎΜΑΤΑ
|
|
||||||
სწრაფი ყავისფერი მელა გადაახტა ზარმაც ძაღლს ᲘᲜᲢᲔᲚ ᲞᲔᲜᲢᲘᲣᲛᲘ ᲛᲘᲙᲠᲝᲞᲠᲝᲪᲔᲡᲝᲠᲘ
|
სწრაფი ყავისფერი მელა გადაახტა ზარმაც ძაღლს ᲘᲜᲢᲔᲚ ᲞᲔᲜᲢᲘᲣᲛᲘ ᲛᲘᲙᲠᲝᲞᲠᲝᲪᲔᲡᲝᲠᲘ
|
||||||
ऋषियों को सताने वाले दुष्ट राक्षसों के राजा रावण का सर्वनाश करने वाले विष्णुवतार भगवान श्रीराम अयोध्या के महाराज दशरथ के
|
ऋषियों को सताने वाले दुष्ट राक्षसों के राजा रावण का सर्वनाश करने वाले विष्णुवतार भगवान श्रीराम अयोध्या के महाराज दशरथ के
|
||||||
Kæmi ný öxi hér, ykist þjófum nú bæði víl og ádrepa
|
Kæmi ný öxi hér, ykist þjófum nú bæði víl og ádrepa
|
||||||
@@ -40,7 +40,8 @@ How multilingual? Real multilingual!
|
|||||||
あめつちほしそら やまかはみねたに くもきりむろこけ ひといぬうへすゑ ゆわさるおふせよ えの𛀁をなれゐて
|
あめつちほしそら やまかはみねたに くもきりむろこけ ひといぬうへすゑ ゆわさるおふせよ えの𛀁をなれゐて
|
||||||
トリナクコヱス ユメサマセ ミヨアケワタル ヒンカシヲ ソライロハエテ オキツヘニ ホフネムレヰヌ モヤノウチ
|
トリナクコヱス ユメサマセ ミヨアケワタル ヒンカシヲ ソライロハエテ オキツヘニ ホフネムレヰヌ モヤノウチ
|
||||||
田居に出で 菜摘むわれをぞ 君召すと 求食り追ひゆく 山城の 打酔へる子ら 藻葉干せよ え舟繋けぬ
|
田居に出で 菜摘むわれをぞ 君召すと 求食り追ひゆく 山城の 打酔へる子ら 藻葉干せよ え舟繋けぬ
|
||||||
정 참판 양반댁 규수 큰 교자 타고 혼례 치른 날 찦차를 타고 온 펲시맨과 쑛다리 똠방각하
|
콩고물과 우유가 들어간 빙수는 차게 먹어야 특별한 맛이 잘 표현된다 유쾌했던 땃쥐 토끼풀 쫓기 바쁨
|
||||||
|
찦차를 타고 온 펲시맨과 쑛다리 똠방각하 왜날뷁
|
||||||
쾅 ᄒᆞ는 소리 헨 “아이구 베락 털어져ᇝ인가?” 영 걷어진 쥥은 몰르곡 경헨 ᄇᆞᆰ도록 ᄌᆞᆷ ᄒᆞᆫᄌᆞᆷ들 안 잣수다
|
쾅 ᄒᆞ는 소리 헨 “아이구 베락 털어져ᇝ인가?” 영 걷어진 쥥은 몰르곡 경헨 ᄇᆞᆰ도록 ᄌᆞᆷ ᄒᆞᆫᄌᆞᆷ들 안 잣수다
|
||||||
Četri psihi faķīri vēlu vakarā zāģēja guļbūvei durvis, fonā šņācot mežam
|
Četri psihi faķīri vēlu vakarā zāģēja guļbūvei durvis, fonā šņācot mežam
|
||||||
Įlinkdama fechtuotojo špaga sublykčiojusi pragręžė apvalų arbūzą
|
Įlinkdama fechtuotojo špaga sublykčiojusi pragręžė apvalų arbūzą
|
||||||
@@ -58,7 +59,7 @@ How multilingual? Real multilingual!
|
|||||||
Pijamalı hasta yağız şoföre çabucak güvendi
|
Pijamalı hasta yağız şoföre çabucak güvendi
|
||||||
Жебракують філософи при ґанку церкви в Гадячі, ще й шатро їхнє п’яне знаємо
|
Жебракують філософи при ґанку церкви в Гадячі, ще й шатро їхнє п’яне знаємо
|
||||||
Do bạch kim rất quý nên sẽ dùng để lắp vô xương
|
Do bạch kim rất quý nên sẽ dùng để lắp vô xương
|
||||||
日堀油告観観藤村抄海評業庁経賃室弁市。太撮収改売週法所何都慣次現。価紙一無三洋日話転手治稿載末替付致治。
|
日堀油告観観藤村抄海評業庁経賃室弁市。太撮収改売週法所何都慣次現。
|
||||||
[pʰnɣɬɥi.m͡ŋχɫʍɨnaɸ.cθʊɫɯ.ɹɨɫʏ͡ɛx.ɯ͡ɣaxɲaɣɫ.ɸtʰɑɣɴ]
|
[pʰnɣɬɥi.m͡ŋχɫʍɨnaɸ.cθʊɫɯ.ɹɨɫʏ͡ɛx.ɯ͡ɣaxɲaɣɫ.ɸtʰɑɣɴ]
|
||||||
⠑⠥⠊⠵⠀⠟⠫⠒⠵⠀⠓⠗⠎⠉⠂⠀⠠⠊⠗⠘⠍⠓⠎⠀⠨⠣⠩⠐⠥⠍⠑⠱⠀⠈⠪⠀⠨⠷⠎⠢⠈⠧⠀⠈⠏⠒⠐⠕⠝⠀⠕⠌⠎⠀⠊⠿⠊⠪⠶⠚⠊
|
⠑⠥⠊⠵⠀⠟⠫⠒⠵⠀⠓⠗⠎⠉⠂⠀⠠⠊⠗⠘⠍⠓⠎⠀⠨⠣⠩⠐⠥⠍⠑⠱⠀⠈⠪⠀⠨⠷⠎⠢⠈⠧⠀⠈⠏⠒⠐⠕⠝⠀⠕⠌⠎⠀⠊⠿⠊⠪⠶⠚⠊
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ How multilingual? Real multilingual!
|
|||||||
‣ Unicode fractions, also known as super/subscripts
|
‣ Unicode fractions, also known as super/subscripts
|
||||||
|
|
||||||
ᄀᆞᄅᆞᇝ ᄀᆞᅀᅢ 자거늘 밀므리 사ᄋᆞ리로ᄃᆡ 나거ᅀᅡ ᄌᆞᄆᆞ니ᅌᅵ다 셤 안해 자시ᇙ 제 한비 사ᄋᆞ리로ᄃᆡ 뷔어ᅀᅡ ᄌᆞᄆᆞ니ᅌᅵ다
|
ᄀᆞᄅᆞᇝ ᄀᆞᅀᅢ 자거늘 밀므리 사ᄋᆞ리로ᄃᆡ 나거ᅀᅡ ᄌᆞᄆᆞ니ᅌᅵ다 셤 안해 자시ᇙ 제 한비 사ᄋᆞ리로ᄃᆡ 뷔어ᅀᅡ ᄌᆞᄆᆞ니ᅌᅵ다
|
||||||
쾅 ᄒᆞ는 소리 헨 “아이구, 베락 털어져ᇝ인가?” 영 걷어진 쥥은 몰르곡 경헨 나왕 보고들랑 영헤연 ᄇᆞᆰ도록 ᄌᆞᆷ ᄒᆞᆫᄌᆞᆷ들 안 잣수다 이 시간 동네 사람들.
|
쾅 ᄒᆞ는 소리 헨 “아이구, 베락 털어져ᇝ인가?” 영 걷어진 쥥은 몰르곡 경헨 나왕 보고들랑 영헤연 ᄇᆞᆰ도록 ᄌᆞᆷ ᄒᆞᆫᄌᆞᆷ들 안 잣수다
|
||||||
|
|
||||||
‣ Full support for Old Korean/Jeju dialect orthography
|
‣ Full support for Old Korean/Jeju dialect orthography
|
||||||
|
|
||||||
@@ -121,15 +122,17 @@ How multilingual? Real multilingual!
|
|||||||
⁃ Braille Patterns
|
⁃ Braille Patterns
|
||||||
⁃ Cherokeeᴬ
|
⁃ Cherokeeᴬ
|
||||||
⁃ CJK Symbols and Punctuation
|
⁃ CJK Symbols and Punctuation
|
||||||
⁃ CJK Unified Ideographs⁶
|
⁃ CJK Unified Ideographs
|
||||||
⁃ CJK Unified Ideographs Extension A¹²·¹
|
⁃ CJK Unified Ideographs Extension A
|
||||||
⁃ Combining Diacritical Marks
|
⁃ Combining Diacritical Marks
|
||||||
⁃ Control Pictures
|
⁃ Control Pictures
|
||||||
|
⁃ Coptic
|
||||||
⁃ Currency Symbols
|
⁃ Currency Symbols
|
||||||
⁃ Cyrillic
|
⁃ Cyrillic
|
||||||
⁃ Cyrillic Supplement
|
⁃ Cyrillic Supplement
|
||||||
⁃ Cyrillic Extended-A/B/C
|
⁃ Cyrillic Extended-A/B/C/D
|
||||||
⁃ Devanagari
|
⁃ Devanagari
|
||||||
|
⁃ Enclosed Alphanumerics
|
||||||
⁃ Enclosed Alphanumeric Supplement
|
⁃ Enclosed Alphanumeric Supplement
|
||||||
⁃ General Punctuations
|
⁃ General Punctuations
|
||||||
⁃ Georgianჼ
|
⁃ Georgianჼ
|
||||||
@@ -147,9 +150,13 @@ How multilingual? Real multilingual!
|
|||||||
⁃ Katakana Phonetic Extensions
|
⁃ Katakana Phonetic Extensions
|
||||||
⁃ Kana Supplement
|
⁃ Kana Supplement
|
||||||
⁃ Kana Extended-A
|
⁃ Kana Extended-A
|
||||||
⁃ Number Forms
|
|
||||||
⁃ Small Kana Extension
|
⁃ Small Kana Extension
|
||||||
⁃ Letterlike Symbols
|
⁃ Letterlike Symbols
|
||||||
|
⁃ Mathematical Operators
|
||||||
|
⁃ Miscellaneous Technical
|
||||||
|
⁃ Number Forms
|
||||||
|
⁃ Ogham
|
||||||
|
⁃ Optical Character Recognition
|
||||||
⁃ Phonetic Extensions
|
⁃ Phonetic Extensions
|
||||||
⁃ Phonetic Extensions Supplement
|
⁃ Phonetic Extensions Supplement
|
||||||
⁃ Runic
|
⁃ Runic
|
||||||
@@ -160,9 +167,9 @@ How multilingual? Real multilingual!
|
|||||||
⁃ Symbols for Legacy Computing
|
⁃ Symbols for Legacy Computing
|
||||||
⁃ Tamil
|
⁃ Tamil
|
||||||
⁃ Thai
|
⁃ Thai
|
||||||
|
⁃ Yijing Hexagram Symbols
|
||||||
|
|
||||||
ᶠⁱ No support for ligatures
|
ᶠⁱ No support for ligatures
|
||||||
ᴬ Uppercase only ჼ Mkhedruli only
|
ᴬ Uppercase only ჼ Mkhedruli only
|
||||||
⁶ ¹²·¹ Up to the specified Unicode version
|
|
||||||
|
|
||||||
GitHub’s issue page is open! You can report any errors, or leave suggestions. You can help this font to be more versatile. (for more languages, more frameworks) Clone this repo, make changes, and make a pull request! I appreciate any and all supports.
|
GitHub’s issue page is open! You can report any errors, or leave suggestions. You can help this font to be more versatile. (for more languages, more frameworks) Clone this repo, make changes, and make a pull request! I appreciate any and all supports.
|
||||||
BIN
src/assets/ascii_variable.tga
LFS
BIN
src/assets/ascii_variable.tga
LFS
Binary file not shown.
BIN
src/assets/bengali_variable.tga
LFS
BIN
src/assets/bengali_variable.tga
LFS
Binary file not shown.
BIN
src/assets/cjkpunct_variable.tga
LFS
BIN
src/assets/cjkpunct_variable.tga
LFS
Binary file not shown.
Binary file not shown.
BIN
src/assets/coptic_variable.tga
LFS
Normal file
BIN
src/assets/coptic_variable.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/assets/cyrilic_extD_variable.tga
LFS
Normal file
BIN
src/assets/cyrilic_extD_variable.tga
LFS
Normal file
Binary file not shown.
BIN
src/assets/cyrilic_variable.tga
LFS
BIN
src/assets/cyrilic_variable.tga
LFS
Binary file not shown.
Binary file not shown.
BIN
src/assets/emoji1.tga
LFS
Normal file
BIN
src/assets/emoji1.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/enclosed_alphanumeric_variable.tga
LFS
Normal file
BIN
src/assets/enclosed_alphanumeric_variable.tga
LFS
Normal file
Binary file not shown.
BIN
src/assets/greek_variable.tga
LFS
BIN
src/assets/greek_variable.tga
LFS
Binary file not shown.
BIN
src/assets/hayeren_variable.tga
LFS
BIN
src/assets/hayeren_variable.tga
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/assets/maths1_extrawide_variable.tga
LFS
Normal file
BIN
src/assets/maths1_extrawide_variable.tga
LFS
Normal file
Binary file not shown.
BIN
src/assets/ogham_variable.tga
LFS
Normal file
BIN
src/assets/ogham_variable.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/puae000-e0ff.tga
LFS
BIN
src/assets/puae000-e0ff.tga
LFS
Binary file not shown.
BIN
src/assets/unipunct_variable.tga
LFS
BIN
src/assets/unipunct_variable.tga
LFS
Binary file not shown.
BIN
src/assets/wenquanyi.tga
LFS
BIN
src/assets/wenquanyi.tga
LFS
Binary file not shown.
@@ -13,7 +13,7 @@ data class AtlasRegion(
|
|||||||
|
|
||||||
class GlyphAtlas(val atlasWidth: Int, val atlasHeight: Int) {
|
class GlyphAtlas(val atlasWidth: Int, val atlasHeight: Int) {
|
||||||
|
|
||||||
val pixmap = Pixmap(atlasWidth, atlasHeight, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.None }
|
val pixmap = Pixmap(atlasWidth, atlasHeight, Pixmap.Format.RGBA8888).also { it.blending = Pixmap.Blending.SourceOver }
|
||||||
|
|
||||||
private val regions = HashMap<Long, AtlasRegion>()
|
private val regions = HashMap<Long, AtlasRegion>()
|
||||||
|
|
||||||
@@ -21,25 +21,78 @@ class GlyphAtlas(val atlasWidth: Int, val atlasHeight: Int) {
|
|||||||
private var cursorY = 0
|
private var cursorY = 0
|
||||||
private var shelfHeight = 0
|
private var shelfHeight = 0
|
||||||
|
|
||||||
|
private val pendingCells = ArrayList<PendingCell>()
|
||||||
|
|
||||||
|
private class PendingCell(
|
||||||
|
val sheetID: Int,
|
||||||
|
val cellX: Int,
|
||||||
|
val cellY: Int,
|
||||||
|
val cropped: Pixmap,
|
||||||
|
val offsetX: Int,
|
||||||
|
val offsetY: Int
|
||||||
|
)
|
||||||
|
|
||||||
private fun atlasKey(sheetID: Int, cellX: Int, cellY: Int): Long =
|
private fun atlasKey(sheetID: Int, cellX: Int, cellY: Int): Long =
|
||||||
sheetID.toLong().shl(32) or cellX.toLong().shl(16) or cellY.toLong()
|
sheetID.toLong().shl(32) or cellX.toLong().shl(16) or cellY.toLong()
|
||||||
|
|
||||||
fun packCell(sheetID: Int, cellX: Int, cellY: Int, cellPixmap: Pixmap) {
|
/** Scans the cell for its non-transparent bounding box, crops, and queues for deferred packing. */
|
||||||
val w = cellPixmap.width
|
fun queueCell(sheetID: Int, cellX: Int, cellY: Int, cellPixmap: Pixmap) {
|
||||||
val h = cellPixmap.height
|
var minX = cellPixmap.width
|
||||||
|
var minY = cellPixmap.height
|
||||||
|
var maxX = -1
|
||||||
|
var maxY = -1
|
||||||
|
|
||||||
if (cursorX + w > atlasWidth) {
|
for (y in 0 until cellPixmap.height) {
|
||||||
cursorX = 0
|
for (x in 0 until cellPixmap.width) {
|
||||||
cursorY += shelfHeight
|
if (cellPixmap.getPixel(x, y) and 0xFF != 0) {
|
||||||
shelfHeight = 0
|
if (x < minX) minX = x
|
||||||
|
if (y < minY) minY = y
|
||||||
|
if (x > maxX) maxX = x
|
||||||
|
if (y > maxY) maxY = y
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixmap.drawPixmap(cellPixmap, cursorX, cursorY)
|
if (maxX < 0) return // entirely transparent, skip
|
||||||
|
|
||||||
regions[atlasKey(sheetID, cellX, cellY)] = AtlasRegion(cursorX, cursorY, w, h)
|
val cropW = maxX - minX + 1
|
||||||
|
val cropH = maxY - minY + 1
|
||||||
|
val cropped = Pixmap(cropW, cropH, Pixmap.Format.RGBA8888)
|
||||||
|
cropped.drawPixmap(cellPixmap, 0, 0, minX, minY, cropW, cropH)
|
||||||
|
|
||||||
cursorX += w
|
pendingCells.add(PendingCell(sheetID, cellX, cellY, cropped, minX, minY))
|
||||||
if (h > shelfHeight) shelfHeight = h
|
}
|
||||||
|
|
||||||
|
/** Sorts queued cells by height desc then width desc, and packs into shelves. */
|
||||||
|
fun packAllQueued() {
|
||||||
|
pendingCells.sortWith(
|
||||||
|
compareByDescending<PendingCell> { it.cropped.height }
|
||||||
|
.thenByDescending { it.cropped.width }
|
||||||
|
)
|
||||||
|
|
||||||
|
for (cell in pendingCells) {
|
||||||
|
val w = cell.cropped.width
|
||||||
|
val h = cell.cropped.height
|
||||||
|
|
||||||
|
// start new shelf if cell doesn't fit horizontally
|
||||||
|
if (cursorX + w > atlasWidth) {
|
||||||
|
cursorX = 0
|
||||||
|
cursorY += shelfHeight
|
||||||
|
shelfHeight = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap.drawPixmap(cell.cropped, cursorX, cursorY)
|
||||||
|
|
||||||
|
regions[atlasKey(cell.sheetID, cell.cellX, cell.cellY)] =
|
||||||
|
AtlasRegion(cursorX, cursorY, w, h, cell.offsetX, cell.offsetY)
|
||||||
|
|
||||||
|
cursorX += w
|
||||||
|
if (h > shelfHeight) shelfHeight = h
|
||||||
|
|
||||||
|
cell.cropped.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingCells.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun blitSheet(sheetID: Int, sheetPixmap: Pixmap, cellW: Int, cellH: Int, cols: Int, rows: Int) {
|
fun blitSheet(sheetID: Int, sheetPixmap: Pixmap, cellW: Int, cellH: Int, cols: Int, rows: Int) {
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ class TerrarumSansBitmap(
|
|||||||
init {
|
init {
|
||||||
atlas = GlyphAtlas(4096, 4096)
|
atlas = GlyphAtlas(4096, 4096)
|
||||||
var unihanPixmap: Pixmap? = null
|
var unihanPixmap: Pixmap? = null
|
||||||
|
var emoji1Pixmap: Pixmap? = null
|
||||||
|
|
||||||
// first we create pixmap to read pixels, then pack into atlas
|
// first we create pixmap to read pixels, then pack into atlas
|
||||||
fileList.forEachIndexed { index, it ->
|
fileList.forEachIndexed { index, it ->
|
||||||
@@ -373,6 +374,10 @@ class TerrarumSansBitmap(
|
|||||||
// defer wenquanyi packing to after all other sheets
|
// defer wenquanyi packing to after all other sheets
|
||||||
unihanPixmap = pixmap
|
unihanPixmap = pixmap
|
||||||
}
|
}
|
||||||
|
else if (index == SHEET_EMOJI1) {
|
||||||
|
// defer emoji1 packing to after all other sheets
|
||||||
|
emoji1Pixmap = pixmap
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
val texRegPack = if (isExtraWide)
|
val texRegPack = if (isExtraWide)
|
||||||
PixmapRegionPack(pixmap, W_WIDEVAR_INIT, H, HGAP_VAR, 0, xySwapped = isXYSwapped)
|
PixmapRegionPack(pixmap, W_WIDEVAR_INIT, H, HGAP_VAR, 0, xySwapped = isXYSwapped)
|
||||||
@@ -386,9 +391,19 @@ class TerrarumSansBitmap(
|
|||||||
PixmapRegionPack(pixmap, W_LATIN_WIDE, H)
|
PixmapRegionPack(pixmap, W_LATIN_WIDE, H)
|
||||||
else throw IllegalArgumentException("Unknown sheet index: $index")
|
else throw IllegalArgumentException("Unknown sheet index: $index")
|
||||||
|
|
||||||
|
// this code causes initial deva chars to be skipped from rendering
|
||||||
|
// val illegalCells = HashSet<Long>()
|
||||||
|
// for (code in codeRange[index]) {
|
||||||
|
// if (glyphProps[code]?.isIllegal == true) {
|
||||||
|
// val pos = getSheetwisePosition(0, code)
|
||||||
|
// illegalCells.add(pos[0].toLong().shl(16) or pos[1].toLong())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
for (cy in 0 until texRegPack.verticalCount) {
|
for (cy in 0 until texRegPack.verticalCount) {
|
||||||
for (cx in 0 until texRegPack.horizontalCount) {
|
for (cx in 0 until texRegPack.horizontalCount) {
|
||||||
atlas.packCell(index, cx, cy, texRegPack.get(cx, cy))
|
// if (cx.toLong().shl(16) or cy.toLong() in illegalCells) continue
|
||||||
|
atlas.queueCell(index, cx, cy, texRegPack.get(cx, cy))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,6 +412,9 @@ class TerrarumSansBitmap(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort and pack all queued cells (tight-cropped, sorted by height then width)
|
||||||
|
atlas.packAllQueued()
|
||||||
|
|
||||||
// pack wenquanyi (SHEET_UNIHAN) last as a contiguous blit
|
// pack wenquanyi (SHEET_UNIHAN) last as a contiguous blit
|
||||||
unihanPixmap?.let {
|
unihanPixmap?.let {
|
||||||
val cols = it.width / W_UNIHAN
|
val cols = it.width / W_UNIHAN
|
||||||
@@ -405,6 +423,14 @@ class TerrarumSansBitmap(
|
|||||||
it.dispose()
|
it.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pack emoji1 as a contiguous blit (fixed 17x16 cells, 2px top/bottom padding)
|
||||||
|
emoji1Pixmap?.let {
|
||||||
|
val cols = it.width / W_EMOJI1
|
||||||
|
val rows = it.height / H_EMOJI1
|
||||||
|
atlas.blitSheet(SHEET_EMOJI1, it, W_EMOJI1, H_EMOJI1, cols, rows)
|
||||||
|
it.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
// make sure null char is actually null (draws nothing and has zero width)
|
// make sure null char is actually null (draws nothing and has zero width)
|
||||||
atlas.getRegion(SHEET_ASCII_VARW, 0, 0)?.let { atlas.clearRegion(it) }
|
atlas.getRegion(SHEET_ASCII_VARW, 0, 0)?.let { atlas.clearRegion(it) }
|
||||||
glyphProps[0] = GlyphProps(0)
|
glyphProps[0] = GlyphProps(0)
|
||||||
@@ -433,6 +459,7 @@ class TerrarumSansBitmap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val offsetUnihan = (H - H_UNIHAN) / 2
|
private val offsetUnihan = (H - H_UNIHAN) / 2
|
||||||
|
private val offsetEmoji1 = (H - H_EMOJI1) / 2
|
||||||
private val offsetCustomSym = (H - SIZE_CUSTOM_SYM) / 2
|
private val offsetCustomSym = (H - SIZE_CUSTOM_SYM) / 2
|
||||||
|
|
||||||
private var flagFirstRun = true
|
private var flagFirstRun = true
|
||||||
@@ -566,6 +593,9 @@ class TerrarumSansBitmap(
|
|||||||
renderCol = getColour(c)
|
renderCol = getColour(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isNoDrawChar(c) || glyphProps[c]?.isIllegal == true) {
|
||||||
|
// whitespace/control/internal/invalid — no visible glyph, just advance position
|
||||||
|
}
|
||||||
else if (sheetID == SHEET_HANGUL) {
|
else if (sheetID == SHEET_HANGUL) {
|
||||||
// Flookahead for {I, P, F}
|
// Flookahead for {I, P, F}
|
||||||
|
|
||||||
@@ -601,6 +631,8 @@ class TerrarumSansBitmap(
|
|||||||
val posY = posmap.y[index].flipY() +
|
val posY = posmap.y[index].flipY() +
|
||||||
if (sheetID == SHEET_UNIHAN) // evil exceptions
|
if (sheetID == SHEET_UNIHAN) // evil exceptions
|
||||||
offsetUnihan
|
offsetUnihan
|
||||||
|
else if (sheetID == SHEET_EMOJI1)
|
||||||
|
offsetEmoji1
|
||||||
else if (sheetID == SHEET_CUSTOM_SYM)
|
else if (sheetID == SHEET_CUSTOM_SYM)
|
||||||
offsetCustomSym
|
offsetCustomSym
|
||||||
else 0
|
else 0
|
||||||
@@ -674,6 +706,9 @@ class TerrarumSansBitmap(
|
|||||||
renderCol = getColour(c)
|
renderCol = getColour(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isNoDrawChar(c) || glyphProps[c]?.isIllegal == true) {
|
||||||
|
// whitespace/control/internal/invalid — no visible glyph, just advance position
|
||||||
|
}
|
||||||
else if (sheetID == SHEET_HANGUL) {
|
else if (sheetID == SHEET_HANGUL) {
|
||||||
// Flookahead for {I, P, F}
|
// Flookahead for {I, P, F}
|
||||||
|
|
||||||
@@ -709,6 +744,8 @@ class TerrarumSansBitmap(
|
|||||||
val posY = posmap.y[index].flipY() +
|
val posY = posmap.y[index].flipY() +
|
||||||
if (sheetID == SHEET_UNIHAN) // evil exceptions
|
if (sheetID == SHEET_UNIHAN) // evil exceptions
|
||||||
offsetUnihan
|
offsetUnihan
|
||||||
|
else if (sheetID == SHEET_EMOJI1)
|
||||||
|
offsetEmoji1
|
||||||
else if (sheetID == SHEET_CUSTOM_SYM)
|
else if (sheetID == SHEET_CUSTOM_SYM)
|
||||||
offsetCustomSym
|
offsetCustomSym
|
||||||
else 0
|
else 0
|
||||||
@@ -862,6 +899,12 @@ class TerrarumSansBitmap(
|
|||||||
SHEET_LATIN_EXTE_VARW -> latinExtEIndexY(ch)
|
SHEET_LATIN_EXTE_VARW -> latinExtEIndexY(ch)
|
||||||
SHEET_LATIN_EXTF_VARW -> latinExtFIndexY(ch)
|
SHEET_LATIN_EXTF_VARW -> latinExtFIndexY(ch)
|
||||||
SHEET_LATIN_EXTG_VARW -> latinExtGIndexY(ch)
|
SHEET_LATIN_EXTG_VARW -> latinExtGIndexY(ch)
|
||||||
|
SHEET_OGHAM_VARW -> oghamIndexY(ch)
|
||||||
|
SHEET_COPTIC_VARW -> copticIndexY(ch)
|
||||||
|
SHEET_CYRILIC_EXTD_VARW -> cyrilicExtDIndexY(ch)
|
||||||
|
SHEET_MATHS1_VARW -> maths1IndexY(ch)
|
||||||
|
SHEET_EMOJI1 -> emoji1IndexY(ch)
|
||||||
|
SHEET_ENCLOSED_ALPHNUM_VARW -> enclosedAlphnumIndexY(ch)
|
||||||
else -> ch / 16
|
else -> ch / 16
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,6 +1031,7 @@ class TerrarumSansBitmap(
|
|||||||
codeRangeHangulCompat.forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE) }
|
codeRangeHangulCompat.forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE) }
|
||||||
codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9) }
|
codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9) }
|
||||||
codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN) }
|
codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN) }
|
||||||
|
codeRange[SHEET_EMOJI1].forEach { glyphProps[it] = GlyphProps(W_EMOJI1) }
|
||||||
(0xD800..0xDFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
(0xD800..0xDFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
||||||
(0x100000..0x10FFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
(0x100000..0x10FFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
||||||
(0xFFFA0..0xFFFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
(0xFFFA0..0xFFFFF).forEach { glyphProps[it] = GlyphProps(0) }
|
||||||
@@ -2537,6 +2581,8 @@ class TerrarumSansBitmap(
|
|||||||
|
|
||||||
internal const val H = 20
|
internal const val H = 20
|
||||||
internal const val H_UNIHAN = 16
|
internal const val H_UNIHAN = 16
|
||||||
|
internal const val W_EMOJI1 = 17
|
||||||
|
internal const val H_EMOJI1 = 16
|
||||||
|
|
||||||
internal const val H_DIACRITICS = 3
|
internal const val H_DIACRITICS = 3
|
||||||
|
|
||||||
@@ -2593,6 +2639,12 @@ class TerrarumSansBitmap(
|
|||||||
internal const val SHEET_LATIN_EXTE_VARW = 45
|
internal const val SHEET_LATIN_EXTE_VARW = 45
|
||||||
internal const val SHEET_LATIN_EXTF_VARW = 46
|
internal const val SHEET_LATIN_EXTF_VARW = 46
|
||||||
internal const val SHEET_LATIN_EXTG_VARW = 47
|
internal const val SHEET_LATIN_EXTG_VARW = 47
|
||||||
|
internal const val SHEET_OGHAM_VARW = 48
|
||||||
|
internal const val SHEET_COPTIC_VARW = 49
|
||||||
|
internal const val SHEET_CYRILIC_EXTD_VARW = 50
|
||||||
|
internal const val SHEET_MATHS1_VARW = 51
|
||||||
|
internal const val SHEET_EMOJI1 = 52
|
||||||
|
internal const val SHEET_ENCLOSED_ALPHNUM_VARW = 53
|
||||||
|
|
||||||
internal const val SHEET_UNKNOWN = 254
|
internal const val SHEET_UNKNOWN = 254
|
||||||
|
|
||||||
@@ -2663,6 +2715,12 @@ class TerrarumSansBitmap(
|
|||||||
"latinExtE_variable.tga",
|
"latinExtE_variable.tga",
|
||||||
"latinExtF_variable.tga",
|
"latinExtF_variable.tga",
|
||||||
"latinExtG_variable.tga",
|
"latinExtG_variable.tga",
|
||||||
|
"ogham_variable.tga",
|
||||||
|
"coptic_variable.tga",
|
||||||
|
"cyrilic_extD_variable.tga",
|
||||||
|
"maths1_extrawide_variable.tga",
|
||||||
|
"emoji1.tga",
|
||||||
|
"enclosed_alphanumeric_variable.tga",
|
||||||
)
|
)
|
||||||
internal val codeRange = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
|
internal val codeRange = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
|
||||||
0..0xFF, // SHEET_ASCII_VARW
|
0..0xFF, // SHEET_ASCII_VARW
|
||||||
@@ -2705,7 +2763,7 @@ class TerrarumSansBitmap(
|
|||||||
0xF0520..0xF057F, // SHEET_CODESTYLE_ASCII_VARW
|
0xF0520..0xF057F, // SHEET_CODESTYLE_ASCII_VARW
|
||||||
0xFB00..0xFB17, // SHEET_ALPHABETIC_PRESENTATION_FORMS
|
0xFB00..0xFB17, // SHEET_ALPHABETIC_PRESENTATION_FORMS
|
||||||
0x1B000..0x1B16F, // SHEET_HENTAIGANA_VARW
|
0x1B000..0x1B16F, // SHEET_HENTAIGANA_VARW
|
||||||
0x2400..0x243F, // SHEET_CONTROL_PICTURES_VARW
|
0x2400..0x244F, // SHEET_CONTROL_PICTURES_VARW
|
||||||
0x1FB00..0x1FBFF, // SHEET_LEGACY_COMPUTING_VARW
|
0x1FB00..0x1FBFF, // SHEET_LEGACY_COMPUTING_VARW
|
||||||
0xA640..0xA69F, // SHEET_CYRILIC_EXTB_VARW
|
0xA640..0xA69F, // SHEET_CYRILIC_EXTB_VARW
|
||||||
0x2DE0..0x2DFF, // SHEET_CYRILIC_EXTA_VARW
|
0x2DE0..0x2DFF, // SHEET_CYRILIC_EXTA_VARW
|
||||||
@@ -2713,6 +2771,12 @@ class TerrarumSansBitmap(
|
|||||||
0xAB30..0xAB6F, // SHEET_LATIN_EXTE_VARW
|
0xAB30..0xAB6F, // SHEET_LATIN_EXTE_VARW
|
||||||
0x10780..0x107BF, // SHEET_LATIN_EXTF_VARW
|
0x10780..0x107BF, // SHEET_LATIN_EXTF_VARW
|
||||||
0x1DF00..0x1DFFF, // SHEET_LATIN_EXTG_VARW
|
0x1DF00..0x1DFFF, // SHEET_LATIN_EXTG_VARW
|
||||||
|
0x1680..0x169F, // SHEET_OGHAM_VARW
|
||||||
|
0x2C80..0x2CFF, // SHEET_COPTIC_VARW
|
||||||
|
0x1E030..0x1E08F, // SHEET_CYRILIC_EXTD_VARW
|
||||||
|
0x2200..0x23FF, // SHEET_MATHS1_VARW
|
||||||
|
0x1F600..0x1F64F, // SHEET_EMOJI1
|
||||||
|
0x2460..0x24FF, // SHEET_ENCLOSED_ALPHNUM_VARW
|
||||||
)
|
)
|
||||||
private val codeRangeHangulCompat = 0x3130..0x318F
|
private val codeRangeHangulCompat = 0x3130..0x318F
|
||||||
|
|
||||||
@@ -3008,6 +3072,13 @@ class TerrarumSansBitmap(
|
|||||||
private fun isBulgarian(c: CodePoint) = c in 0xF0000..0xF005F
|
private fun isBulgarian(c: CodePoint) = c in 0xF0000..0xF005F
|
||||||
private fun isSerbian(c: CodePoint) = c in 0xF0060..0xF00BF
|
private fun isSerbian(c: CodePoint) = c in 0xF0060..0xF00BF
|
||||||
fun isColourCode(c: CodePoint) = c == 0x100000 || c in 0x10F000..0x10FFFF
|
fun isColourCode(c: CodePoint) = c == 0x100000 || c in 0x10F000..0x10FFFF
|
||||||
|
private fun isNoDrawChar(c: CodePoint): Boolean =
|
||||||
|
c <= 0x20 || c == NBSP || c == SHY || c == OBJ ||
|
||||||
|
c in 0x2000..0x200D ||
|
||||||
|
c in 0xD800..0xDFFF ||
|
||||||
|
c in 0xF800..0xF8FF ||
|
||||||
|
c in 0xFFF70..0xFFF9F ||
|
||||||
|
c >= 0xFFFA0
|
||||||
private fun isCharsetOverride(c: CodePoint) = c in 0xFFFC0..0xFFFCF
|
private fun isCharsetOverride(c: CodePoint) = c in 0xFFFC0..0xFFFCF
|
||||||
private fun isDevanagari(c: CodePoint) = c in codeRange[SHEET_DEVANAGARI_VARW]
|
private fun isDevanagari(c: CodePoint) = c in codeRange[SHEET_DEVANAGARI_VARW]
|
||||||
private fun isHangulCompat(c: CodePoint) = c in codeRangeHangulCompat
|
private fun isHangulCompat(c: CodePoint) = c in codeRangeHangulCompat
|
||||||
@@ -3064,6 +3135,12 @@ class TerrarumSansBitmap(
|
|||||||
private fun latinExtEIndexY(c: CodePoint) = (c - 0xAB30) / 16
|
private fun latinExtEIndexY(c: CodePoint) = (c - 0xAB30) / 16
|
||||||
private fun latinExtFIndexY(c: CodePoint) = (c - 0x10780) / 16
|
private fun latinExtFIndexY(c: CodePoint) = (c - 0x10780) / 16
|
||||||
private fun latinExtGIndexY(c: CodePoint) = (c - 0x1DF00) / 16
|
private fun latinExtGIndexY(c: CodePoint) = (c - 0x1DF00) / 16
|
||||||
|
private fun oghamIndexY(c: CodePoint) = (c - 0x1680) / 16
|
||||||
|
private fun copticIndexY(c: CodePoint) = (c - 0x2C80) / 16
|
||||||
|
private fun cyrilicExtDIndexY(c: CodePoint) = (c - 0x1E030) / 16
|
||||||
|
private fun maths1IndexY(c: CodePoint) = (c - 0x2200) / 16
|
||||||
|
private fun emoji1IndexY(c: CodePoint) = (c - 0x1F600) / 16
|
||||||
|
private fun enclosedAlphnumIndexY(c: CodePoint) = (c - 0x2460) / 16
|
||||||
|
|
||||||
val charsetOverrideDefault = Character.toChars(CHARSET_OVERRIDE_DEFAULT).toSurrogatedString()
|
val charsetOverrideDefault = Character.toChars(CHARSET_OVERRIDE_DEFAULT).toSurrogatedString()
|
||||||
val charsetOverrideBulgarian = Character.toChars(CHARSET_OVERRIDE_BG_BG).toSurrogatedString()
|
val charsetOverrideBulgarian = Character.toChars(CHARSET_OVERRIDE_BG_BG).toSurrogatedString()
|
||||||
|
|||||||
BIN
work_files/ascii_variable.psd
LFS
BIN
work_files/ascii_variable.psd
LFS
Binary file not shown.
BIN
work_files/bengali_variable.psd
LFS
BIN
work_files/bengali_variable.psd
LFS
Binary file not shown.
BIN
work_files/cjkpunct_variable.psd
LFS
BIN
work_files/cjkpunct_variable.psd
LFS
Binary file not shown.
Binary file not shown.
BIN
work_files/coptic_variable.kra
LFS
Normal file
BIN
work_files/coptic_variable.kra
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
work_files/cyrilic_extD_variable.kra
LFS
Normal file
BIN
work_files/cyrilic_extD_variable.kra
LFS
Normal file
Binary file not shown.
BIN
work_files/cyrilic_variable.psd
LFS
BIN
work_files/cyrilic_variable.psd
LFS
Binary file not shown.
Binary file not shown.
BIN
work_files/emoji1.kra
LFS
Normal file
BIN
work_files/emoji1.kra
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
work_files/enclosed_alphanumeric_variable.kra
LFS
Normal file
BIN
work_files/enclosed_alphanumeric_variable.kra
LFS
Normal file
Binary file not shown.
BIN
work_files/greek_variable.psd
LFS
BIN
work_files/greek_variable.psd
LFS
Binary file not shown.
BIN
work_files/hayeren_variable.psd
LFS
BIN
work_files/hayeren_variable.psd
LFS
Binary file not shown.
Binary file not shown.
BIN
work_files/kana_variable.kra
LFS
BIN
work_files/kana_variable.kra
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
work_files/ogham_variable.kra
LFS
Normal file
BIN
work_files/ogham_variable.kra
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
work_files/puae000-e0ff.psd
LFS
BIN
work_files/puae000-e0ff.psd
LFS
Binary file not shown.
BIN
work_files/unipunct_variable.psd
LFS
BIN
work_files/unipunct_variable.psd
LFS
Binary file not shown.
BIN
work_files/wenquanyi_addendum.kra
LFS
Normal file
BIN
work_files/wenquanyi_addendum.kra
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user