{"id":51609603,"url":"https://github.com/vdustr/ptt-font-tool","last_synced_at":"2026-07-12T06:02:32.354Z","repository":{"id":365175220,"uuid":"1270777999","full_name":"VdustR/ptt-font-tool","owner":"VdustR","description":"Desktop, CLI, and library tools for adapting fonts to term.ptt.cc terminal cell metrics.","archived":false,"fork":false,"pushed_at":"2026-06-16T06:49:53.000Z","size":20,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T08:22:54.230Z","etag":null,"topics":["cli","desktop-app","font","fonttools","ptt","python","term-ptt"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/VdustR.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-16T03:31:01.000Z","updated_at":"2026-06-16T06:49:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/VdustR/ptt-font-tool","commit_stats":null,"previous_names":["vdustr/ptt-font-tool"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/VdustR/ptt-font-tool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VdustR%2Fptt-font-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VdustR%2Fptt-font-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VdustR%2Fptt-font-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VdustR%2Fptt-font-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VdustR","download_url":"https://codeload.github.com/VdustR/ptt-font-tool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VdustR%2Fptt-font-tool/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35383520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","desktop-app","font","fonttools","ptt","python","term-ptt"],"created_at":"2026-07-12T06:02:27.097Z","updated_at":"2026-07-12T06:02:32.348Z","avatar_url":"https://github.com/VdustR.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PTT Font Tool\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/VdustR/ptt-font-tool/main/src/ptt_font_tool/assets/app_icon/ptt-font-tool.png\" width=\"160\" alt=\"PTT Font Tool icon\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/readme/term-ptt-custom-theme.png\" width=\"860\" alt=\"Term PTT Custom Theme color preview\"\u003e\n  \u003cbr\u003e\n  \u003csub\u003e截圖範例使用 \u003ca href=\"https://www.sentyfont.com/watermelon.htm\"\u003e新蒂西瓜体\u003c/a\u003e 搭配 \u003ca href=\"https://github.com/mbadolato/iTerm2-Color-Schemes/blob/61c5479/schemes/Night%20Owl.itermcolors\"\u003eNight Owl\u003c/a\u003e。顏色主題可搭配 \u003ca href=\"https://chromewebstore.google.com/detail/term-ptt-custom-theme/lmanknmemlpnjolgjoffdkmkkeibpfej\"\u003eTerm PTT Custom Theme\u003c/a\u003e 套用，原始碼見 \u003ca href=\"https://github.com/VdustR/term-ptt-custom-theme\"\u003eGitHub\u003c/a\u003e。\u003c/sub\u003e\n\u003c/p\u003e\n\n桌面版、CLI 與 Python library 工具，用來把字型調整成適合 term.ptt.cc 終端機格線的版本。\n\n## Desktop\n\n桌面版是主要的使用者介面。\n\n主要功能：\n\n- 開啟本機字型檔。\n- 用載入的字型即時編輯預覽文字。\n- 顯示字型 metadata、audit summary 與 fallback glyph coverage。\n- 管理 fallback font stack 與 Noto fallback cache。\n- 切換 `center` / `fit` 處理策略。\n- 建立並匯出適合 PTT 使用的本機輸出檔。\n\n桌面版 release artifacts 會把需要的 runtime dependencies 一起打包，讓使用者下載後可以直接執行，不需自行安裝 Python、fontTools、Brotli 等環境。\n\n下載桌面版請前往 [GitHub Releases](https://github.com/VdustR/ptt-font-tool/releases/latest)，選擇最新版中的 macOS、Windows 或 Linux artifact。\n\n本地開發版可以用 desktop extra 啟動：\n\n```bash\npython -m pip install -e '.[desktop]'\nptt-font-desktop\n```\n\n桌面版 Build 後會產生可預覽與匯出的完整處理字型；匯出時會再次驗證處理結果。\n\nNoto fallback 會由桌面版下載到應用程式自己的 cache，不會安裝到系統字型。使用者可以在 fallback 區塊下載、重新下載、清空，或打開 cache 資料夾，並選擇 `Noto Sans TC` 或 `Noto Serif TC` 作為文字 fallback。\n\n桌面版可以檢查 GitHub Releases 是否有新版；目前只會提示並開啟 release 頁面，不會自動下載、替換或執行更新檔。\n\nRelease 會由 GitHub Actions 自動產生桌面版 artifacts：\n\n- `ptt-font-tool-vX.Y.Z-macos-arm64.zip`\n- `ptt-font-tool-vX.Y.Z-macos-x64.zip`\n- `ptt-font-tool-vX.Y.Z-windows-x64.zip`\n- `ptt-font-tool-vX.Y.Z-linux-x64.tar.gz`\n\n每個 artifact 會一起上傳對應的 `.sha256` checksum 檔。\n\n目前桌面版 artifacts 尚未 code sign 或 notarize。macOS 與 Windows 第一次開啟下載版 app 時，可能會出現作業系統安全提醒；請只從本 repository 的 GitHub Releases 下載。\n\n下載後可以先驗證 checksum：\n\n```bash\nshasum -a 256 -c ptt-font-tool-vX.Y.Z-macos-arm64.zip.sha256\n```\n\nWindows PowerShell 可以用：\n\n```powershell\nGet-FileHash .\\ptt-font-tool-vX.Y.Z-windows-x64.zip -Algorithm SHA256\n```\n\n再與 `.sha256` 檔案內容比對。\n\n### macOS 手動開啟未簽章版本\n\n只對你信任來源的版本使用這個方式，例如本 repository 的 GitHub Releases。不要對不明來源下載的 app 套用例外。\n\n如果 macOS 阻擋開啟未簽章的 `PTT Font Tool.app`：\n\n1. 先雙擊 `PTT Font Tool.app`，讓 macOS 顯示一次安全提醒。\n2. 打開 **System Settings** → **Privacy \u0026 Security**。\n3. 往下找到 **Security** 區塊，按 **Open Anyway**。\n4. 再按 **Open** 確認。\n\n如果 **Open Anyway** 沒出現，可以只針對這個 app 移除 quarantine 屬性：\n\n```bash\nxattr -dr com.apple.quarantine \"$HOME/Downloads/PTT Font Tool.app\"\n```\n\n如果你已經把 app 移到 `/Applications`：\n\n```bash\nxattr -dr com.apple.quarantine \"/Applications/PTT Font Tool.app\"\n```\n\n不建議全域關閉 Gatekeeper。上面的方式只會替單一 app 建立例外。\n\n## CLI\n\nCLI 用於可重複執行的本機流程與自動化。\n\n目前指令：\n\n```bash\nptt-font audit input.otf\nptt-font patch input.otf --output output.otf --strategy center\nptt-font build primary.ttf fallback-a.ttf fallback-b.ttf --output output.ttf --noto sans\nptt-font verify output.otf\n```\n\n`audit` 會列出不符合 PTT cell 寬度的 glyph，但即使發現問題也會 exit `0`，適合人工檢查。\n\n`verify` 會輸出同樣的檢查結果；全部符合時 exit `0`，有 mismatch 或 missing glyph 時 exit `1`，適合 CI 或 script 使用。\n\n`audit`、`patch`、`verify` 都支援 `--sample-text`。不指定 `--sample-text` 時，會處理或檢查字型 cmap 映射到的所有 Unicode 字元。\n\n省略 `--output` 時，處理後的字型會輸出在輸入檔旁邊，檔名預設加上 `-ptt` 後綴。\n\n```bash\nptt-font patch lithue-1.1.otf --sample-text \"A漢ˇ\"\n# 產生 lithue-1.1-ptt.otf\n```\n\n`build` 是新的多字型流程。第一個 path 是主要字型，後面的 path 依序作為 fallback font。缺字會先從 fallback stack 補，最後才使用已下載的 Noto fallback。\n\n```bash\nptt-font build SentyWatermelon.ttf MingLiU-PTT.ttf \\\n  --output SentyWatermelon-ptt.ttf \\\n  --strategy center \\\n  --noto sans\n```\n\n`--noto` 支援 `sans`、`serif`、`off`。預設不會自動下載 Noto，避免 CLI 在 build 時產生未預期的 network side effect。需要 build 前自動補齊 Noto cache 時，可以加上：\n\n```bash\nptt-font build input.ttf fallback.ttf --download-noto\n```\n\nNoto cache 可以獨立管理：\n\n```bash\nptt-font noto status --noto sans\nptt-font noto download --noto sans\nptt-font noto clear --noto sans\nptt-font noto path\n```\n\n設定來源優先序是 CLI args 優先，接著才讀 env var，最後使用作業系統預設值。\n\n可用 env var：\n\n- `PTT_FONT_TOOL_FONTS_DIR`：app-managed fonts root；Noto 會放在底下的 `noto/`。\n- `PTT_FONT_TOOL_NOTO_STYLE`：`sans`、`serif` 或 `off`。\n- `PTT_FONT_TOOL_FALLBACK_FONTS`：fallback font path list，使用作業系統 path separator 分隔，例如 macOS/Linux 用 `:`、Windows 用 `;`。\n\nCLI 的 `--strategy` 使用桌面版與 library 共用的處理策略，見 [Processing Strategy 處理策略](#processing-strategy-處理策略)。\n\n處理後的字型會移除 OpenType `GPOS` pair positioning/kerning，避免瀏覽器 shaping 時微調字距而破壞終端機固定格線。\n\n## Library\n\nPython library 提供桌面版與 CLI 共用的核心邏輯。\n\n目前模組：\n\n- `ptt_font_tool.profile`：將 Unicode 字元映射到 Term PTT cell 寬度。\n- `ptt_font_tool.audit`：讀取字型，檢查 glyph advance width 是否符合 Term PTT profile。\n- `ptt_font_tool.patch`：修改 glyph advance width，並套用 `center` 或 `fit` outline 策略。\n- `ptt_font_tool.fallback`：依照 fallback chain 合併缺少的 glyph。\n- `ptt_font_tool.noto_cache`：管理 app cache 中的 Noto fallback 下載、狀態與清除。\n- `ptt_font_tool.font_stack`：提供 CLI 與桌面版共用的多字型 stack、Noto resolver 與 build entrypoint。\n\n## Font Width Model 字寬模型\n\nterm.ptt.cc 使用終端機常見的 2:1 cell 寬度：\n\n- ASCII 與半形字元使用一個 cell。\n- CJK、全形、寬字元，以及 East Asian Ambiguous 字元使用兩個 cell。\n- 1000 UPEM 字型中，一個 cell 預期是 500 font units，兩個 cell 預期是 1000 font units。\n- 1200 UPEM 字型中，一個 cell 預期是 600 font units，兩個 cell 預期是 1200 font units。\n\n預設 profile 使用 Python 的 Unicode East Asian Width 資料，並且針對 term.ptt.cc 將 ambiguous-width 字元視為寬字元。\n\n## Processing Strategy 處理策略\n\n桌面版、CLI 與 Python library 使用同一套 glyph outline 處理策略。兩種策略都會先把 glyph advance width 調整成 PTT cell 寬度；差異在於 glyph 外形如何放進 cell。\n\n- `center`：保留 glyph 外形與尺寸，將 glyph 置中放進 PTT cell。這最保留原字型風格，適合特色字型；但過寬 glyph 可能視覺溢出或和鄰字重疊。\n- `fit`：只對超出 PTT cell 的 glyph 做水平縮放，再置中。這比較不容易破壞終端機格線；但部分字形比例會被壓縮。\n\n若目標是保留字型味道，建議先試 `center`；如果終端機畫面仍有明顯 overlap，再改用 `fit`。\n\n## Current Limits 目前限制\n\n- Audit 與 advance patching 依照 fontTools 支援的 OpenType 與 TrueType 輸入格式。\n- Outline strategies 目前支援 TrueType `glyf` 與 CFF-based OTF 字型。\n- CFF2、variable font 行為、color glyph outlines 還需要更多相容性測試，才會視為正式支援路徑。\n\n## Development\n\n建立隔離的 Python environment 並安裝 package：\n\n```bash\npython -m venv .venv\n. .venv/bin/activate\npython -m pip install -e .\n```\n\n執行測試：\n\n```bash\npython -m unittest discover -s tests\n```\n\n## Release 發布\n\n這個 repository 使用 Release Please 管理版本與自動化 release。\n\nRelease 建立後，GitHub Actions 會自動建置並上傳：\n\n- 已包含 runtime dependencies 的桌面版 artifacts。\n- 每個 artifact 對應的 `.sha256` checksum 檔。\n\n## License And Font Rights 授權與字型權利\n\n本專案使用 MIT 授權。\n\n輸入字型仍受原始字型授權約束。產生後的字型只能依照原始輸入字型授權使用或散布。本工具不會授予第三方字型的再散布權利。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdustr%2Fptt-font-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvdustr%2Fptt-font-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdustr%2Fptt-font-tool/lists"}