fontwidth
Version:
A TypeScript library for font width calculations
247 lines (175 loc) • 7.13 kB
Markdown
# FontWidth Library
[](https://github.com/zapkub/fontwidthjs/actions/workflows/ci.yml)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
> **⚠️ AI Generated Repository**: This repository is generated by AI
A TypeScript library for precise font size calculation that fits text within specified width constraints. Designed with first-class Thai language support and works in both browser and Node.js environments.
## ✨ Features
- **Precise Font Metrics**: Uses actual font glyph measurements for pixel-perfect width calculations
- **Thai Language Support**: Special handling for Thai combining characters, tone marks, and ligatures
- **Universal Compatibility**: Works in both browser and Node.js environments
- **Multiple Font Formats**: Supports TTF and OTF font files from Buffer, ArrayBuffer, or base64
- **Binary Search Optimization**: Efficient algorithm for finding optimal font sizes
- **TypeScript Ready**: Full TypeScript support with comprehensive type definitions
## 🚀 Installation
```bash
yarn add fontwidth
# or
npm install fontwidth
```
## 📖 Usage
### Basic Example
```typescript
import { calculateFontSize } from 'fontwidth';
import fs from 'fs';
// Load a font file
const fontBuffer = fs.readFileSync('path/to/your/font.ttf');
// Calculate optimal font size
const result = calculateFontSize(
'สวัสดีครับ', // Thai text
300, // Maximum width in pixels
fontBuffer // Font file buffer
);
console.log(`Optimal font size: ${result.fontSize}px`);
console.log(`Actual width: ${result.actualWidth}px`);
```
### Advanced Options
```typescript
const result = calculateFontSize(text, maxWidth, fontBuffer, {
minFontSize: 8, // Minimum font size (default: 8)
maxFontSize: 100, // Maximum font size (default: 100)
precision: 0.1, // Font size precision (default: 0.1)
});
```
### Browser Usage
```html
<!DOCTYPE html>
<html>
<head>
<script type="module">
import { calculateFontSize } from './dist/index.esm.js';
// Load font file from user input or fetch
const response = await fetch('fonts/NotoSansThai-Regular.ttf');
const fontBuffer = await response.arrayBuffer();
const result = calculateFontSize('การคำนวณฟอนต์', 250, fontBuffer);
// Apply to DOM element
const element = document.getElementById('text');
element.style.fontSize = result.fontSize + 'px';
element.textContent = 'การคำนวณฟอนต์';
</script>
</head>
<body>
<div id="text"></div>
</body>
</html>
```
## 🇹🇭 Thai Language Support
This library provides comprehensive support for Thai text rendering:
- **Unicode Normalization**: Automatically handles NFD normalization for proper character combining
- **Tone Marks & Vowels**: Correctly processes above/below base character positioning
- **Ligatures**: Accounts for Thai character ligature combinations
- **Mixed Languages**: Seamlessly handles Thai text mixed with Latin characters
### Thai Examples
```typescript
// Place names with complex characters
calculateFontSize('กรุงเทพมหานคร', 300, fontBuffer);
// Text with tone marks
calculateFontSize('เมื่อพรุ่งนี้', 250, fontBuffer);
// Mixed Thai-English
calculateFontSize('Hello สวัสดี World', 350, fontBuffer);
```
## 📋 API Reference
### `calculateFontSize(text, maxWidth, fontInput, options?)`
#### Parameters
- **`text`** (string): The text to measure
- **`maxWidth`** (number): Maximum width constraint in pixels
- **`fontInput`** (FontInput): Font file as Buffer, ArrayBuffer, or base64 string
- **`options`** (CalculateFontSizeOptions, optional): Configuration options
#### Options
```typescript
interface CalculateFontSizeOptions {
minFontSize?: number; // Minimum font size (default: 8)
maxFontSize?: number; // Maximum font size (default: 100)
precision?: number; // Font size precision (default: 0.1)
}
```
#### Returns
```typescript
interface FontSizeResult {
fontSize: number; // Optimal font size in pixels
actualWidth: number; // Calculated text width in pixels
maxWidth: number; // Input maximum width constraint
}
```
## 🎮 Demo Application
The library includes an interactive HTML demo showcasing its capabilities:
```bash
# Build the library
yarn build
# Start demo server
yarn demo
# Open browser to http://localhost:8000
```
The demo features:
- Real-time font size calculation
- Thai font loading (Noto Sans/Serif Thai)
- Visual preview with accurate width rendering
- Multiple Thai text examples
- Interactive controls for all parameters
## 🧪 Testing
```bash
# Run unit tests
yarn test
# Run browser integration tests
yarn test:browser
# Run tests with coverage
yarn test:coverage
```
### Browser Testing
The library includes comprehensive Playwright tests that verify:
- Font loading and rendering accuracy
- Width calculation precision across diverse Thai texts
- Visual regression testing with screenshot comparison
- Cross-browser compatibility
## 🛠️ Development
```bash
# Install dependencies
yarn install
# Build library
yarn build
# Run development server
yarn dev
# Lint and format code
yarn quality:fix
```
### Continuous Integration
The project uses GitHub Actions for automated testing and quality assurance:
- **Code Quality**: ESLint, Prettier, and TypeScript checks
- **Testing**: Unit tests and browser integration tests across Node.js 18, 20, 22
- **Build Verification**: Ensures all distribution files are generated correctly
- **Demo Validation**: Verifies the demo application works properly
All checks must pass before code can be merged. The CI pipeline automatically runs on every push and pull request.
### Build Output
- **`dist/index.js`**: CommonJS build for Node.js
- **`dist/index.esm.js`**: ES modules build for modern browsers
- **`dist/index.d.ts`**: TypeScript type definitions
## 📦 Font Requirements
The library works with:
- **TTF (TrueType)** fonts
- **OTF (OpenType)** fonts
- Fonts must contain proper metric tables for accurate measurements
- For Thai text, use fonts with comprehensive Thai Unicode support (recommended: Noto Sans Thai, Noto Serif Thai)
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request
## 📄 License
MIT License - see LICENSE file for details.
## ⚠️ Disclaimer
This library was generated with assistance from Claude (Anthropic's AI assistant). While thoroughly tested and functional, please validate the library meets your specific requirements before using in production environments.
## 🙏 Acknowledgments
- **Google Fonts** for providing high-quality Thai fonts used in testing
- **opentype.js** for font parsing capabilities
- **Playwright** for comprehensive browser testing infrastructure