Skip to content

Port FreeType font rendering library to meniOS #398

Description

@pbalduino

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


Related Issues

See docs/road/road_to_gui.md for the complete GUI roadmap.


Resources


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:


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

Metadata

Metadata

Assignees

Labels

GUIGraphical user interface componentsenhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions