Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions Local_FONT_LOADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Font Loading Guide

This document explains how to use custom fonts with the City Map Poster Generator.

## Overview

The application supports three methods for loading fonts, in priority order:

1. **Google Fonts** (`--font-family`) - Highest priority
2. **Local Font Path** (`--font-path`) - Second priority
3. **Default Roboto** - Automatic fallback

## Using Local Fonts

### Single Font File

Load a specific font file for all text weights (bold, regular, light):

```bash
python create_map_poster.py -c "Paris" -C "France" --font-path "path/to/font.ttf"
```

Examples:
```bash
# Windows absolute path
python create_map_poster.py -c "Paris" -C "France" --font-path "D:\Fonts\CustomFont.ttf"

# Unix absolute path
python create_map_poster.py -c "Tokyo" -C "Japan" --font-path "/usr/share/fonts/truetype/myfont.ttf"

# Relative path
python create_map_poster.py -c "Berlin" -C "Germany" --font-path "./fonts/custom.ttf"
```

### Font Directory

Load multiple font files from a directory. The function intelligently detects font weights:

```bash
python create_map_poster.py -c "Barcelona" -C "Spain" --font-path "path/to/fonts/"
```

The function looks for the following patterns (case-insensitive):

**Bold weight patterns:**
- `*bold*` (e.g., `font-bold.ttf`, `Font_Bold.otf`)
- `*700*` (e.g., `font-700.ttf`)

**Regular weight patterns:**
- `*regular*` (e.g., `font-regular.ttf`)
- `*400*` (e.g., `font-400.ttf`)
- `*normal*` (e.g., `font-normal.ttf`)

**Light weight patterns:**
- `*light*` (e.g., `font-light.ttf`)
- `*300*` (e.g., `font-300.ttf`)
- `*thin*` (e.g., `font-thin.ttf`)

**Example directory structure:**
```
fonts/
├── myfont-bold.ttf
├── myfont-regular.ttf
├── myfont-light.ttf
└── alternate-300.otf
```

Then use:
```bash
python create_map_poster.py -c "Rome" -C "Italy" --font-path "fonts/"
```

### Path Handling

The function handles paths robustly:

- **Absolute paths**: `/path/to/font.ttf` or `C:\path\to\font.ttf`
- **Relative paths**: `./fonts/myfont.ttf` or `fonts/myfont.ttf`
- **Home directory expansion**: `~/fonts/myfont.ttf` (expands to user home)
- **Windows & Unix paths**: Automatically handled regardless of OS
- **Spaces in paths**: Fully supported with proper escaping

## Using Google Fonts

Download fonts directly from Google Fonts:

```bash
python create_map_poster.py -c "Berlin" -C "Germany" --font-family "Noto Sans JP"
python create_map_poster.py -c "Bangkok" -C "Thailand" --font-family "Noto Sans Thai"
```

Supports any family available on [Google Fonts](https://fonts.google.com/)

## Supported Font Formats

- `.ttf` - TrueType Font
- `.otf` - OpenType Font
- `.woff` - Web Open Font Format
- `.woff2` - Web Open Font Format 2 (compressed)

## Examples

### Using a custom display font

```bash
python create_map_poster.py \
-c "Tokyo" \
-C "Japan" \
-t japanese_ink \
--font-path "C:\MyFonts\NotoSansJP-Bold.ttf" \
-d 15000
```

### Using a font directory with multiple weights

```bash
python create_map_poster.py \
-c "Paris" \
-C "France" \
-t pastel_dream \
--font-path "./custom_fonts/" \
-d 10000
```

### Combining with other options

```bash
python create_map_poster.py \
-c "Barcelona" \
-C "Spain" \
--font-path "/usr/share/fonts/custom/" \
-t warm_beige \
-W 14 \
-H 18 \
--display-city "Barcelona" \
--display-country "España"
```

## Fallback Behavior

If font loading fails at any stage:

1. If `--font-family` is provided but fails → tries `--font-path` (if provided)
2. If `--font-path` is provided but fails → uses default Roboto
3. If both fail → uses default Roboto fonts

The console will show appropriate warning messages about what fallback was used.

## Troubleshooting

### "Font path does not exist"
- Check that the path is correct and file/directory exists
- Use absolute paths if relative paths don't work
- On Windows, use `\` or `\\` for path separators (or use forward slashes `/`)

### "Unsupported font format"
- Only `.ttf`, `.otf`, `.woff`, and `.woff2` are supported
- Convert your font to a supported format if needed

### "No font files found in directory"
- Make sure font files are directly in the specified directory
- Check that files have a supported extension (.ttf, .otf, etc.)

### Fonts not appearing in output
- The font file may be corrupt or incompatible
- Try a different font or the default fonts
- Check console output for specific error messages

## Font Policy

When using custom fonts:
- Ensure you have the right to use the font for your intended purpose
- Respect font licenses and attribution requirements
- For commercial use, verify font licensing terms
- The generated posters include OpenStreetMap attribution by default

23 changes: 23 additions & 0 deletions create_map_poster.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,13 @@ def print_examples():
python create_map_poster.py -c "London" -C "UK" -t noir -d 15000 # Thames curves
python create_map_poster.py -c "Budapest" -C "Hungary" -t copper_patina -d 8000 # Danube split

# Custom fonts from local path
python create_map_poster.py -c "Paris" -C "France" --font-path "D:\\Fonts\\BrownieStencil-8O8MJ.ttf"
python create_map_poster.py -c "Tokyo" -C "Japan" --font-path "/path/to/fonts/" -t japanese_ink

# Google Fonts
python create_map_poster.py -c "Berlin" -C "Germany" --font-family "Noto Sans JP"

# List themes
python create_map_poster.py --list-themes

Expand All @@ -819,13 +826,20 @@ def print_examples():
--theme, -t Theme name (default: terracotta)
--all-themes Generate posters for all themes
--distance, -d Map radius in meters (default: 18000)
--font-family Google Fonts family name (e.g., "Noto Sans JP", "Open Sans")
--font-path Path to local font file or directory (e.g., "fonts/custom.ttf" or "fonts/")
--list-themes List all available themes

Distance guide:
4000-6000m Small/dense cities (Venice, Amsterdam old center)
8000-12000m Medium cities, focused downtown (Paris, Barcelona)
15000-20000m Large metros, full city view (Tokyo, Mumbai)

Font loading priority:
1. --font-family (Google Fonts) - highest priority
2. --font-path (local file or directory) - second priority
3. Roboto fonts (default fallback)

Available themes can be found in the 'themes/' directory.
Generated posters are saved to 'posters/' directory.
""")
Expand Down Expand Up @@ -948,6 +962,11 @@ def list_themes():
type=str,
help='Google Fonts family name (e.g., "Noto Sans JP", "Open Sans"). If not specified, uses local Roboto fonts.',
)
parser.add_argument(
"--font-path",
type=str,
help="Path to local font file or directory containing fonts (e.g., /path/to/font.ttf or /path/to/fonts/)",
)
parser.add_argument(
"--format",
"-f",
Expand Down Expand Up @@ -1010,6 +1029,10 @@ def list_themes():
custom_fonts = load_fonts(args.font_family)
if not custom_fonts:
print(f"⚠ Failed to load '{args.font_family}', falling back to Roboto")
elif args.font_path:
custom_fonts = load_fonts(font_path=args.font_path)
if not custom_fonts:
print(f"⚠ Failed to load fonts from path '{args.font_path}', falling back to Roboto")

# Get coordinates and generate poster
try:
Expand Down
Loading