Port FreeType font rendering library to meniOS
Summary
Port the FreeType font rendering library to meniOS to enable high-quality TrueType and OpenType font rendering. FreeType is required by Cairo for text rendering in the GUI stack.
Background
FreeType is an industry-standard font rendering library that provides:
- TrueType (TTF) font rendering
- OpenType (OTF) font support
- Type 1 PostScript fonts
- Hinting and anti-aliasing
- Subpixel rendering (LCD optimization)
- Unicode support via character mapping
Version: FreeType 2.13.2 (latest stable) Language: C (~100,000 lines) License: FreeType License (BSD-like) or GPL v2 Dependencies: None (standalone, minimal libc)
Why FreeType?
FreeType is required by Cairo for text rendering. Without FreeType, Cairo can only render basic shapes but no text.
Used by:
- Cairo (our graphics library)
- GTK, Qt (GUI toolkits)
- Firefox, Chrome (web browsers)
- Android, iOS (mobile platforms)
- Most Linux desktop environments
Goals
Primary
- Port FreeType to compile on meniOS
- Support TrueType (TTF) font loading and rendering
- Enable basic glyph rendering to bitmaps
- Enable hinting for readable text at small sizes
- Integrate with Cairo's FT font backend
Secondary
- OpenType (OTF) support
- Subpixel rendering (LCD optimization)
- Font caching for performance
- Multiple font faces and styles
Implementation Plan
Phase 1: Build System Integration (3-5 days)
Goal: Get FreeType to compile
Tasks:
- [ ] Download FreeType 2.13.2 source
- [ ] Place in `vendor/freetype-2.13.2/`
- [ ] Create Makefile for meniOS build
- [ ] Configure build options
- [ ] Resolve compilation errors
Build Configuration: ```makefile
Makefile for FreeType
FREETYPE_SRC := vendor/freetype-2.13.2 FREETYPE_CFLAGS := -DFT2_BUILD_LIBRARY \ -I$(FREETYPE_SRC)/include \ -I$(FREETYPE_SRC)/include/freetype \ -I$(FREETYPE_SRC)/include/freetype/config
FREETYPE_SRCS := $(shell find $(FREETYPE_SRC)/src -name '*.c') FREETYPE_OBJS := $(FREETYPE_SRCS:.c=.o)
libfreetype.a: $(FREETYPE_OBJS) $(AR) rcs $@ $^ ```
FreeType Modules to Enable:
- ✅ TrueType (required)
- ✅ OpenType/CFF
- ✅ Hinting engine
- ✅ Rasterizer (smooth)
- ⏳ Subpixel rendering (optional)
- ❌ Type 1 (legacy, not needed initially)
Phase 2: Font Loading (1 week)
Goal: Load TrueType fonts from filesystem
Tasks:
- [ ] Implement FT_Init_FreeType()
- [ ] Load font file from disk
- [ ] Parse TTF font structure
- [ ] Verify font loading succeeds
- [ ] Test with multiple fonts
Test Code: ```c #include <ft2build.h> #include FT_FREETYPE_H #include <stdio.h> #include <assert.h>
int main() { FT_Library library; FT_Error error;
// Initialize FreeType
error = FT_Init_FreeType(&library);
if (error) {
printf("Failed to initialize FreeType: %d\\n", error);
return 1;
}
printf("FreeType initialized successfully!\\n");
printf("Version: %d.%d.%d\\n",
FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
// Load a font file
FT_Face face;
error = FT_New_Face(library, "/usr/share/fonts/DejaVuSans.ttf",
0, &face);
if (error) {
printf("Failed to load font: %d\\n", error);
return 1;
}
printf("Loaded font: %s\\n", face->family_name);
printf("Style: %s\\n", face->style_name);
printf("Glyphs: %ld\\n", face->num_glyphs);
FT_Done_Face(face);
FT_Done_FreeType(library);
return 0;
} ```
Font Files Needed:
# Create font directory
mkdir -p /usr/share/fonts
# Copy fonts to meniOS filesystem
# We'll need at least one TrueType font, such as:
# - DejaVu Sans (open source, good quality)
# - Liberation Sans (metric-compatible with Arial)
# - Noto Sans (Google's Unicode font)
Phase 3: Glyph Rendering (1 week)
Goal: Render glyphs to bitmaps
Tasks:
- [ ] Set font size
- [ ] Load character glyph
- [ ] Render glyph to bitmap
- [ ] Extract bitmap data
- [ ] Test with various characters
Test Code: ```c #include <ft2build.h> #include FT_FREETYPE_H
void render_glyph_to_console(FT_GlyphSlot slot) { FT_Bitmap *bitmap = &slot->bitmap;
for (int y = 0; y < bitmap->rows; y++) {
for (int x = 0; x < bitmap->width; x++) {
unsigned char pixel = bitmap->buffer[y * bitmap->pitch + x];
printf(pixel > 128 ? "#" : " ");
}
printf("\\n");
}
}
int main() { FT_Library library; FT_Face face;
FT_Init_FreeType(&library);
FT_New_Face(library, "/usr/share/fonts/DejaVuSans.ttf", 0, &face);
// Set font size to 48pt at 96 DPI
FT_Set_Char_Size(face,
0, // char_width (0 = same as height)
48 * 64, // char_height in 1/64th of points
96, // horizontal DPI
96); // vertical DPI
// Load and render 'A'
FT_Load_Char(face, 'A', FT_LOAD_RENDER);
printf("Rendered 'A' at 48pt:\\n");
render_glyph_to_console(face->glyph);
FT_Done_Face(face);
FT_Done_FreeType(library);
return 0;
} ```
Phase 4: Cairo Integration (1 week)
Goal: Integrate FreeType with Cairo text rendering
Tasks:
- [ ] Enable Cairo FT font backend
- [ ] Load fonts via Cairo API
- [ ] Render text with Cairo
- [ ] Verify text appears correctly
- [ ] Test various fonts and sizes
Cairo FT Integration: ```c #include <cairo/cairo.h> #include <cairo/cairo-ft.h> #include <ft2build.h> #include FT_FREETYPE_H
int main() { // Initialize FreeType FT_Library ft_library; FT_Init_FreeType(&ft_library);
FT_Face ft_face;
FT_New_Face(ft_library, "/usr/share/fonts/DejaVuSans.ttf",
0, &ft_face);
// Create Cairo font face from FreeType face
cairo_font_face_t *cairo_face =
cairo_ft_font_face_create_for_ft_face(ft_face, 0);
// Create Cairo surface
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, 640, 480);
cairo_t *cr = cairo_create(surface);
// Set the font
cairo_set_font_face(cr, cairo_face);
cairo_set_font_size(cr, 48);
// Render text
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_move_to(cr, 50, 100);
cairo_show_text(cr, "Hello, meniOS!");
// Cleanup
cairo_destroy(cr);
cairo_surface_destroy(surface);
cairo_font_face_destroy(cairo_face);
FT_Done_Face(ft_face);
FT_Done_FreeType(ft_library);
printf("Text rendering complete!\\n");
return 0;
} ```
Phase 5: Advanced Features (1-2 weeks)
Goal: Enable hinting, anti-aliasing, subpixel rendering
Tasks:
- [ ] Enable hinting for small sizes
- [ ] Test anti-aliasing (grayscale)
- [ ] Enable subpixel rendering (RGB LCD)
- [ ] Test various rendering modes
- [ ] Optimize glyph caching
Rendering Modes: ```c // Test different rendering modes
// 1. Monochrome (1-bit) FT_Load_Char(face, 'A', FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
// 2. Grayscale anti-aliasing (8-bit) FT_Load_Char(face, 'A', FT_LOAD_RENDER);
// 3. Subpixel rendering (LCD) FT_Library_SetLcdFilter(library, FT_LCD_FILTER_DEFAULT); FT_Load_Char(face, 'A', FT_LOAD_RENDER | FT_LOAD_TARGET_LCD);
// 4. With hinting FT_Load_Char(face, 'A', FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL);
// 5. Without hinting FT_Load_Char(face, 'A', FT_LOAD_RENDER | FT_LOAD_NO_HINTING); ```
Subpixel Rendering:
- Sharper text on LCD screens
- Uses RGB sub-pixels for better resolution
- Requires LCD filter (FreeType includes Harmony filter)
Phase 6: Testing & Optimization (3-5 days)
Goal: Ensure quality and performance
Tasks:
- [ ] Test Unicode characters (Latin, Greek, Cyrillic, etc.)
- [ ] Test various font sizes (6pt - 144pt)
- [ ] Test bold, italic, different weights
- [ ] Measure rendering performance
- [ ] Implement glyph caching if needed
- [ ] Memory leak testing
Performance Test: ```c void benchmark_text_rendering() { FT_Library library; FT_Face face;
FT_Init_FreeType(&library);
FT_New_Face(library, "/usr/share/fonts/DejaVuSans.ttf", 0, &face);
FT_Set_Char_Size(face, 0, 16*64, 96, 96);
clock_t start = clock();
// Render 1000 glyphs
for (int i = 0; i < 1000; i++) {
FT_Load_Char(face, 'A' + (i % 26), FT_LOAD_RENDER);
}
clock_t end = clock();
double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
printf("1000 glyphs rendered in %.2f ms\\n", elapsed * 1000);
printf("Throughput: %.0f glyphs/sec\\n", 1000 / elapsed);
FT_Done_Face(face);
FT_Done_FreeType(library);
} ```
Expected performance:
- ~10,000+ glyphs/sec on modern CPU
- Caching can improve interactive performance
Timeline
| Phase | Task | Duration |
|---|---|---|
| 1 | Build system integration | 3-5 days |
| 2 | Font loading | 1 week |
| 3 | Glyph rendering | 1 week |
| 4 | Cairo integration | 1 week |
| 5 | Advanced features | 1-2 weeks |
| 6 | Testing & optimization | 3-5 days |
Total: 5-7 weeks
Definition of Done
Core Requirements
- [ ] FreeType library compiles on meniOS
- [ ] Can initialize FreeType
- [ ] Can load TrueType fonts from disk
- [ ] Can render glyphs to bitmaps
- [ ] Basic text rendering works
- [ ] Test suite passes
Cairo Integration
- [ ] Cairo FT backend compiles
- [ ] Can render text via Cairo
- [ ] Multiple fonts work
- [ ] Various sizes work (6pt - 144pt)
- [ ] Unicode text renders correctly
Quality Requirements
- [ ] Hinting works for small sizes
- [ ] Anti-aliasing produces smooth glyphs
- [ ] Subpixel rendering works (optional)
- [ ] No memory leaks
- [ ] Performance acceptable (1000+ glyphs/sec)
Documentation
- [ ] Font installation guide
- [ ] FreeType API usage examples
- [ ] Cairo text rendering examples
- [ ] Performance tuning guide
Dependencies
Required
- None (FreeType is standalone)
Optional
- libpng - For PNG font formats (not critical)
- zlib - For compressed fonts (included in TrueType)
Enables
- #396: Port Cairo - Cairo text rendering requires FreeType
- All GUI applications that display text
- Terminal emulator with Unicode support
Related Issues
See docs/road/road_to_gui.md for the complete GUI roadmap.
- #129: Unicode text rendering - Complements FreeType text capabilities
- #396: Port Cairo - Depends on FreeType for text
Resources
- FreeType Website: https://freetype.org/
- Documentation: https://freetype.org/freetype2/docs/documentation.html
- Tutorial: https://freetype.org/freetype2/docs/tutorial/step1.html
- Source Code: https://gitlab.freedesktop.org/freetype/freetype
- API Reference: https://freetype.org/freetype2/docs/reference/index.html
Font Resources
Open Source Fonts (recommended):
- DejaVu Sans - Excellent Unicode coverage, readable
- Liberation Sans - Metric-compatible with Arial
- Noto Sans - Google's comprehensive Unicode font
- Source Code Pro - Monospace font for terminals
Where to get fonts:
- https://dejavu-fonts.github.io/
- https://github.com/liberationfonts/liberation-fonts
- https://fonts.google.com/noto
Priority
HIGH - FreeType is critical for text rendering. Without it, the GUI can only display shapes but no text.
Timeline: Target completion in 1.5-2 months