{"id":"mewious/editable-font","name":"editable-font","scope":"mewious","platform":"roblox","description":"Pure-Luau TTF font parser and renderer using EditableImage. Bakes TrueType glyphs into texture atlases for fast ImageLabel-based text rendering with support for kerning, rich text, custom charsets, and font weight.","version":"0.1.6","latest":"0.1.6","versions":["0.1.0","0.1.1","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"ed9123a113f6d569d555a9ff18014c84788eae6fd5070f14f6dc52f9ceecf5bf","likes":0,"downloads":0,"install":"forest install mewious/editable-font","url":"https://forest.dev/p/roblox/mewious/editable-font","files":"https://api.forest.dev/ai/package/roblox/mewious/editable-font/files","readme":"# EditableFont\n\nA pure-Luau TrueType font parser and renderer for Roblox, powered by `EditableImage`. Parses `.ttf` binaries at runtime, bakes glyph atlases, and renders text via `ImageLabel` — no asset uploads required.\n\n## Features\n\n- **TTF Parsing** — Reads TrueType font files directly from a buffer. Supports simple and composite glyphs, kerning pairs, and Unicode BMP cmap lookup.\n- **Atlas Baking** — Rasterizes glyphs into a single `EditableImage` texture atlas with 4× vertical anti-aliasing. Bake once at startup, render unlimited text at zero cost.\n- **Font Weight** — Synthetic bold via a `fontWeight` parameter that thickens strokes horizontally and vertically during baking.\n- **Rich Text** — Supports inline `<font>` tags for color, transparency, and size changes within a single text line.\n- **Custom Charsets** — Bake only the codepoints you need to keep atlas size minimal.\n- **Kerning** — Automatic kern pair lookup for tight, professional letter spacing.\n- **Text Alignment** — Left, center, and right alignment out of the box.\n- **In-Place Updates** — Update text content, color, or size without recreating instances.\n\n## Installation\n\n### Wally\n\nAdd to your `wally.toml`:\n\n```toml\n[dependencies]\nEditableFont = \"mewious/editable-font@0.1.0\"\n```\n\nThen run:\n\n```bash\nwally install\n```\n\n### Rojo\n\nClone the repo and build:\n\n```bash\nrojo build -o \"EditableFont.rbxlx\"\n```\n\nOr sync directly into Studio:\n\n```bash\nrojo serve\n```\n\n## Quick Start\n\n```lua\nlocal EditableFont = require(path.to.EditableFont)\n\n-- Create a font instance from a .ttf buffer\nlocal font = EditableFont.new(fontBuffer, 48)\n\n-- Render text into a Frame\nlocal frame = font:renderText({\n    text = \"Hello, world!\",\n    color = Color3.fromRGB(255, 255, 255),\n    fontSize = 48,\n    parent = screenGui,\n})\n\n-- Update text in-place (no re-creation)\nfont:updateText(frame, {\n    text = \"Score: 9999\",\n    color = Color3.fromRGB(255, 215, 0),\n})\n```\n\n## API\n\n### `EditableFont.new(data: buffer, fontSize: number?, charset: {number}?)`\n\nCreates a new EditableFont instance from raw `.ttf` bytes.\n\n| Parameter  | Type        | Description                                          |\n| ---------- | ----------- | ---------------------------------------------------- |\n| `data`     | `buffer`    | Raw TTF file bytes                                   |\n| `fontSize` | `number?`   | Default font size in pixels (default 100)            |\n| `charset`  | `{number}?` | Default codepoints to bake (default ASCII 0x20–0x7E) |\n\n### `font:renderText(config: RenderConfig): Frame`\n\nRenders text and returns a `Frame` ready to parent into your UI.\n\n### `font:updateText(frame: Frame, config: RenderConfig)`\n\nUpdates an existing rendered frame in-place with new config values.\n\n### `font:getAtlas(fontSize: number?, charset: {number}?, fontWeight: number?): AtlasResult`\n\nReturns (or bakes) an atlas for the given parameters. Cached automatically.\n\n### `font:destroy()`\n\nCleans up all cached atlases.\n\n### RenderConfig\n\n```lua\n{\n    text: string | { RichTextSegment },\n    fontSize: number?,\n    charset: { number }?,\n    color: Color3?,\n    padding: number?,\n    baseline: number?,\n    fillDirection: Enum.FillDirection?,\n    scale: number?,\n    textSizeMultiplier: number?,\n    xAlignment: Enum.TextXAlignment?,\n    position: UDim2?,\n    anchorPoint: Vector2?,\n    xPadding: number?,\n    yPadding: number?,\n    parent: Instance?,\n    fontWeight: number?,\n}\n```\n\n## Rich Text\n\nSupports a subset of rich text tags within string values:\n\n```lua\nfont:renderText({\n    text = '<font color=\"#FF0000\">Red</font> and <font color=\"#00FF00\">Green</font>',\n    fontSize = 32,\n})\n```\n\nOr pass structured segments for full control:\n\n```lua\nfont:renderText({\n    text = {\n        { text = \"Normal \", color = Color3.new(1, 1, 1) },\n        { text = \"Bold\",   color = Color3.new(1, 0.8, 0) },\n    },\n    fontSize = 32,\n})\n```\n\n## Font Weight\n\nApply synthetic boldness during atlas baking:\n\n```lua\nlocal frame = font:renderText({\n    text = \"Bold Text\",\n    fontWeight = 2,  -- extra stroke width in pixels\n})\n```\n\nA weight of `0` is normal. Higher values produce thicker strokes. Each unique weight creates a separately cached atlas.\n","readmeTruncated":false}