{"id":49060642,"url":"https://github.com/mateffy/pretext-php","last_synced_at":"2026-07-04T16:01:53.465Z","repository":{"id":355978930,"uuid":"1195319924","full_name":"mateffy/pretext-php","owner":"mateffy","description":"A PHP port of the chenglou/pretext text layout and measurement library. Provides fast, accurate text layout calculation using ICU (Intl) for segmentation and an injectable font measurement interface.","archived":false,"fork":false,"pushed_at":"2026-03-29T14:25:46.000Z","size":47,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T06:02:58.512Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mateffy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-29T14:25:33.000Z","updated_at":"2026-03-29T14:25:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"abb31917-20b8-4009-b083-5ff1a3ed5c5f","html_url":"https://github.com/mateffy/pretext-php","commit_stats":null,"previous_names":["mateffy/pretext-php"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mateffy/pretext-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fpretext-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fpretext-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fpretext-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fpretext-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mateffy","download_url":"https://codeload.github.com/mateffy/pretext-php/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fpretext-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35127443,"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-04T02:00:05.987Z","response_time":113,"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":[],"created_at":"2026-04-20T02:00:28.099Z","updated_at":"2026-07-04T16:01:53.460Z","avatar_url":"https://github.com/mateffy.png","language":"PHP","funding_links":[],"categories":["Community Projects","Selected Community Projects"],"sub_categories":["Emerging Projects","Testing, DevTools, and CI"],"readme":"# Pretext PHP 8\n\nA PHP 8 port of the **pretext** text layout and measurement library. Provides fast, accurate text layout calculation using ICU (Intl) for segmentation and an injectable font measurement interface.\n\n## Features\n\n- **Fast text layout** - O(n) complexity for measuring and laying out text\n- **Internationalization** - Full Unicode support via ICU (Intl extension)\n- **Word segmentation** - Proper handling of CJK, Thai, Arabic, Devanagari, and Myanmar\n- **Bidirectional text** - Bidi algorithm support for mixed LTR/RTL text\n- **Injectable font measurement** - Use stub measurer for testing or GD/FreeType for production\n- **Comprehensive test suite** - Full feature parity with the original TypeScript implementation\n\n\u003e [!IMPORTANT]\n\u003e This is a **PHP port** of the brilliant [chenglou/pretext](https://github.com/chenglou/pretext) TypeScript library by **Cheng Lou**.\n\u003e\n\u003e **All credit for the algorithms, design, and implementation goes to Cheng Lou and the original authors.** This port was created using **Kimi K2.5** and maintains feature parity with the original, adapting it for PHP 8's type system and ecosystem.\n\n## Installation\n\n```bash\ncomposer require pretext/pretext\n```\n\n## Requirements\n\n- PHP 8.0+\n- `ext-intl` (ICU for word/grapheme segmentation)\n- `ext-mbstring` (multibyte string functions)\n- `ext-gd` (optional, for production font measurement with FreeType)\n\n## Quick Start\n\n```php\nuse Pretext\\PretextFactory;\n\n// Prepare text for layout\n$prepared = PretextFactory::prepare('Hello world', '16px Arial');\n\n// Layout with specific max width and line height\n$result = PretextFactory::layout($prepared, 200, 24);\n\necho \"Lines: {$result-\u003elineCount}\\n\";\necho \"Height: {$result-\u003eheight}px\\n\";\n```\n\n## Usage\n\n### Basic Layout\n\n```php\nuse Pretext\\Pretext;\nuse Pretext\\Measurement\\GdFontMeasurer;\n\n// Production: Use GD/FreeType font measurement\n$measurer = new GdFontMeasurer('/path/to/fonts', [\n    'Arial' =\u003e 'arial.ttf',\n    'Inter' =\u003e 'Inter-Regular.ttf',\n]);\n$pretext = new Pretext($measurer);\n\n// Or use the static factory\n$prepared = PretextFactory::prepare('Hello world', '16px Arial');\n$result = PretextFactory::layout($prepared, 200, 24);\n```\n\n### Rich Layout (with line details)\n\n```php\n$prepared = $pretext-\u003eprepareWithSegments('Hello world this is a test', '16px Arial');\n$lines = $pretext-\u003elayoutWithLines($prepared, 100, 24);\n\nforeach ($lines-\u003elines as $line) {\n    echo \"Line: {$line-\u003etext}\\n\";\n    echo \"Width: {$line-\u003ewidth}px\\n\";\n    echo \"Start: segment {$line-\u003estart-\u003esegmentIndex}\\n\";\n}\n```\n\n### Streaming Layout\n\n```php\n$prepared = $pretext-\u003eprepareWithSegments('Long text here...', '16px Arial');\n$cursor = new LayoutCursor(0, 0);\n\nwhile (true) {\n    $line = $pretext-\u003elayoutNextLine($prepared, $cursor, 200);\n    if ($line === null) break;\n\n    echo \"Line: {$line-\u003etext}\\n\";\n    $cursor = $line-\u003eend;\n}\n```\n\n### Custom Font Measurement\n\n```php\nuse Pretext\\Measurement\\FontMeasurerInterface;\n\nclass MyFontMeasurer implements FontMeasurerInterface\n{\n    public function measureText(string $text, string $font): float\n    {\n        // Your custom measurement logic\n        return $width;\n    }\n\n    public function setFont(string $font): void\n    {\n        // Set current font\n    }\n}\n\n$pretext = new Pretext(new MyFontMeasurer());\n```\n\n### Internationalization\n\n```php\n// Set locale for proper word segmentation\n$pretext-\u003esetLocale('th');  // Thai\n$thaiText = $pretext-\u003eprepare('ภาษาไทย', '16px Arial');\n\n// Reset to default\n$pretext-\u003esetLocale(null);\n```\n\n## API Reference\n\n### Pretext Class\n\n- `prepare(string $text, string $font): PreparedText` - Prepare text for layout\n- `prepareWithSegments(string $text, string $font): PreparedTextWithSegments` - Prepare with segment details\n- `layout(PreparedText $prepared, float $maxWidth, float $lineHeight): LayoutResult` - Calculate line count and height\n- `layoutWithLines(...): LayoutLinesResult` - Layout with per-line details\n- `walkLineRanges(...): int` - Walk line ranges without materializing text\n- `layoutNextLine(...): ?LayoutLine` - Get next line from cursor position\n- `clearCache(): void` - Clear internal caches\n- `setLocale(?string $locale): void` - Set locale for word segmentation\n\n### PretextFactory Class\n\nStatic factory providing convenient access to all Pretext functionality.\n\n### Font Measurers\n\n- `StubFontMeasurer` - Testing/development (constant character widths)\n- `GdFontMeasurer` - Production (uses GD/FreeType with actual font files)\n\n## Architecture\n\nThe library follows a layered architecture:\n\n```\nPretext (Public API)\n  ↓\nAnalysis (Text segmentation \u0026 normalization)\n  ↓\nBidi (Bidirectional text algorithm)\n  ↓\nMeasurement (Text measurement via injectable interface)\n  ↓\nLineBreak (Line breaking algorithm)\n```\n\n## Differences from TypeScript Original\n\n1. **Font measurement** - File-based (GD/FreeType) instead of browser Canvas\n2. **Emoji correction** - Always 0 (no DOM comparison available)\n3. **EngineProfile** - Always uses server/headless profile (no browser detection)\n4. **Caching** - Per-request by default (no shared memory)\n5. **Bidi segment starts** - Codepoint-indexed (cleaner, all bidi ranges are BMP)\n\n## Testing\n\n```bash\n# Install dependencies\ncomposer install\n\n# Run tests\n./vendor/bin/phpunit\n\n# Run with coverage\n./vendor/bin/phpunit --coverage-html coverage\n```\n\n## License\n\nMIT\n\n## Credits\n\nBased on the original TypeScript implementation by Sebastian Markbage and contributors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateffy%2Fpretext-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmateffy%2Fpretext-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateffy%2Fpretext-php/lists"}