embedded-graphics-profont 0.2.2

Bitmap font rendering for embedded-graphics with anchor and tracking support
Documentation
# Font Generation Tools

Complete workflow for creating and converting bitmap fonts for use with `embedded-graphics-profont`.

## Workflow Overview

```
1. Font Creation/Selection
   2. Export from GLCD Font Creator (.c format)
   3. Convert with main.py
   4. Use in Rust project
```

## Step 1: GLCD Font Creator

**GLCD Font Creator** is a bitmap font editor designed for embedded displays.

### Download & Install

- **Website:** https://www.mikroe.com/glcd-font-creator
- **Platform:** Windows (standalone executable) and Linux with Wine
- **Cost:** Free

### Creating/Editing Fonts

1. **Open GLCD Font Creator**
2. Create new font or open existing font file
3. Design/edit glyphs as needed
4. Adjust font parameters (height, baseline, etc.)

### Exporting Font

**Critical:** Correct export format is essential.

1. Click **Export for TFT and new GLCD**
2. Set export option:
   - **Format:** MikroC (TFT)
3. Save file (e.g., `myfont.c`)

**Wrong format will not work with conversion script!**

## Step 2: Convert with main.py

### Prerequisites

```bash
# Ensure Python 3.6+ is installed
python3 --version
```

### Conversion Script

The `main.py` script converts GLCD-exported `.c` files to Rust constants.

**Location:** Project root or fonts directory

### Usage

```bash
python3 main.py input_font.c -o output_fonts.rs
```

**Options:**
- `-o, --output` - Output file name (default: `fonts.rs`)
- `-n, --name` - Font constant name (default: auto from filename)

### Example

```bash
# Convert myfont.c → fonts.rs
python3 main.py myfont.c

# Custom output name
python3 main.py myfont.c -o my_custom_fonts.rs

# Custom constant name
python3 main.py myfont.c -n "ARIAL_8"
```

### Script Workflow

The conversion script:

1. **Parses** the GLCD C export file
2. **Extracts** glyph bitmap data
3. **Generates** Rust constants:
   - `GLYPHS` - Array of GlyphEntry (width, offset)
   - `FONT_DATA` - Binary bitmap data
   - `FONT` - Const Font instance
4. **Writes** Rust source file

### Output Example

```rust
// Generated fonts.rs
use embedded_graphics_profont::GlyphEntry;

pub const GLYPHS: [GlyphEntry; 95] = [
    GlyphEntry { width: 5, offset: 0 },
    GlyphEntry { width: 4, offset: 40 },
    // ... more entries
];

pub const FONT_DATA: [u8; 4000] = [
    0x60, 0x90, 0xF0, 0x90,  // Glyph data
    // ... more data
];

pub const FONT: Font = Font::new(
    &GLYPHS,
    &FONT_DATA,
    32,    // ASCII start
    126,   // ASCII end
    8,     // Height
    false, // Monospace
);
```

## Step 3: Integrate into Project

### Option A: Direct Copy

1. Run conversion script to generate `fonts.rs`
2. Place `fonts.rs` in `src/fonts/` directory
3. Use in code:

```rust
// In main.rs
use embedded_graphics::{
    pixelcolor::Rgb666,
    prelude::*,
};

use embedded_graphics_profont::{
    Anchor, 
    Text, 
    WithAnchor
};

mod fonts;
use fonts::D_DIN41X44 as D_DIN;

// In main loop
let center = Point::new(100, 100);

Text::new("test", center, &D_DIN, Rgb666::BLACK)
    .with_anchor(Anchor::MiddleLeft)
    .draw(&mut display).ok();
```

### Option B: Multiple Fonts

Generate multiple fonts and organize:

```bash
# Create separate files in src/fonts/
python3 main.py arial.c -o src/fonts/arial.rs
python3 main.py courier.c -o src/fonts/courier.rs
python3 main.py gothic.c -o src/fonts/gothic.rs
```

Then in code:

```rust
// In main.rs
mod fonts;

use fonts::arial::FONT as ARIAL_FONT;
use fonts::courier::FONT as COURIER_FONT;

// Use as needed
Text::new("Arial Text", Point::new(0, 0), &ARIAL_FONT, Rgb666::BLACK)
    .draw(&mut display).ok();

Text::new("Courier Text", Point::new(0, 20), &COURIER_FONT, Rgb666::BLACK)
    .draw(&mut display).ok();
```

## Troubleshooting

### "Script fails to parse .c file"

**Cause:** Wrong export format from GLCD Font Creator

**Fix:**
- Verify you used "Export for tft" with MikroC format
- Check file contains `#include <stdint.h>` at top
- Ensure file has `uint8_t` data arrays (not other formats)

### "Generated font looks wrong"

**Cause:** Glyph dimensions mismatch

**Fix:**
- Check GLCD export height matches `max_height` in generated code
- Verify monospace/proportional flag matches font type
- Test with simpler font first

### "Text doesn't render"

**Cause:** Font data not included or character out of range

**Fix:**
```rust
// Debug: Check font properties
defmt::info!("Font height: {}", font.max_height);
defmt::info!("Range: {}-{}", font.ascii_begin, font.ascii_end);
defmt::info!("Can render 'A': {}", font.get_glyph('A').is_some());
```

### "Characters are missing"

**Cause:** ASCII range mismatch between exported range and what's needed

**Fix:**
- Regenerate font with extended range
- Or check if character is printable ASCII (32-126)

## Font Recommendations

### Small Fonts (8-10px)
- Good for system/status text
- Limited detail, still readable
- Small generated code size

### Medium Fonts (12-14px)
- Balanced readability and size
- Good for UI labels
- Recommended for most applications

### Large Fonts (16-24px)
- High readability
- Larger code/data footprint
- Use for titles or critical information

## Complete Workflow Example

```bash
# 1. Export from GLCD Font Creator as myfont.c
# 2. Convert to Rust
python3 main.py myfont.c -o src/fonts/myfont.rs

# 3. In Rust code (main.rs)
use embedded_graphics::{
    pixelcolor::Rgb666,
    prelude::*,
};
use embedded_graphics_profont::{Text, Anchor, WithAnchor};

mod fonts;
use fonts::FONT;

// Render centered text in main loop
let center = Point::new(160, 120);
Text::new("Hello STM32", center, &FONT, Rgb666::BLACK)
    .with_anchor(Anchor::MiddleCenter)
    .draw(&mut display).ok();
```

## Best Practices

1. **Keep font files versioned** - Track `.c` and generated `.rs` files
2. **Test fonts early** - Verify rendered output before committing
3. **Use standard sizes** - 8, 12, 16px for consistency
4. **Document font purpose** - Comment what each font is for
5. **Minimize font count** - Use 1-2 fonts per project when possible