Metadata-Version: 2.4
Name: fontident
Version: 0.1.0
Summary: Identify and use the font of any text in .doc, .pdf, images (png/jpg/gif) and more. Full toolkit: doc font extraction, image font identification, text recreation.
Author: fontident contributors
License: MIT
Keywords: font,ocr,pdf,docx,image,font-identification,whatthefont
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Text Processing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pillow>=9.0
Requires-Dist: numpy>=1.21
Requires-Dist: requests>=2.25
Requires-Dist: pymupdf>=1.23
Requires-Dist: python-docx>=1.0
Provides-Extra: api
Requires-Dist: fastapi>=0.100; extra == "api"
Requires-Dist: uvicorn>=0.23; extra == "api"
Requires-Dist: python-multipart>=0.0.6; extra == "api"
Provides-Extra: app
Requires-Dist: streamlit>=1.30; extra == "app"
Provides-Extra: identify
Requires-Dist: pytesseract>=0.3.10; extra == "identify"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Dynamic: license-file

# FontIdent 🔤

**Identify and use the font of any text** in `.doc`, `.docx`, `.odt`, `.rtf`,
`.pdf`, and raster images (`.png`, `.jpg`, `.gif`, `.bmp`, `.webp`, `.tiff`).

A single toolkit that ships as:
1. **A GitHub-ready Python library + CLI** (`fontident`)
2. **A drop-in REST API** (FastAPI → deploy to RapidAPI or any ASGI host)
3. **A Streamlit web app** (publishable to an app marketplace)

---

## What it does

| Capability | Digital documents (DOCX/PDF/ODT/RTF) | Raster images (PNG/JPG/GIF/...) |
|------------|------------------------------------|---------------------------------|
| **Identify font** | Reads embedded font files + per-run font metadata (exact) | Hybrid offline-first + online-fallback matching (approximate) |
| **Use the font** | Renders the extracted text back with the matched/embedded font | OCRs the text and renders it back with the identified font |

**Three building blocks:**

- **`extract`** — Pull text runs (each with font name/size/weight/style) and
  embedded font files out of digital documents.
- **`identify`** — Auto-detect which format a file is, then identify the fonts
  in it (document metadata **or** image matching).
- **`recreate`** — Take the text + identified font and render a new image with
  that font applied.

---

## Install

```bash
# Option A: install from this repo (editable)
pip install -e .

# Core runtime deps: pillow, numpy, requests, pymupdf, python-docx
```

Optional extras:

```bash
pip install -e ".[api]"       # fastapi + uvicorn for the REST server
pip install -e ".[app]"       # streamlit for the web app
pip install -e ".[identify]"  # pytesseract for OCR-based recreation
pip install -e ".[dev]"       # pytest for running the tests
```

> **OCR note:** image recreation uses `pytesseract`, which requires the
> [`tesseract`](https://github.com/tesseract-ocr/tesseract) binary:
> `apt-get install tesseract-ocr`

---

## Usage

### 1. Command line

```bash
# Identify fonts in any supported file
fontident identify report.pdf
fontident identify scanned.png --hint "SAMPLE" --top 5
fontident identify notes.docx --json

# Extract text runs + embedded fonts from a document
fontident extract report.pdf

# Recreate the file's text using its identified font
fontident recreate scanned.png -o recreated.png

# Run the HTTP API server
fontident serve --port 8000
```

### 2. As a Python library

```python
from fontident import FontIdent, identify_text, extract_document

engine = FontIdent()

# Identify fonts in an image (offline-first; online fallback if API key set)
analysis = engine.identify("poster.png", text_hint="GRAND OPENING")
for run in analysis.runs:
    print(run.font.name, run.font.score, run.font.source)

# Extract exact font metadata from a digital document
doc = extract_document("resume.pdf")
for run in doc.runs:
    print(run.text, "→", run.font.name, run.font.weight, run.size)

# Recreate the text with the identified font
from fontident.recreate import recreate_text
out = recreate_text("poster.png", output="recreated.png")
```

### 3. REST API (RapidAPI-ready)

Start the server:

```bash
uvicorn fontident.web.api:app --host 0.0.0.0 --port 8000
```

Or via the CLI: `fontident serve`.

```bash
curl -s -X POST http://localhost:8000/identify \
     -F "file=@poster.png" -F "hint=GRAND OPENING" -F "top=3"

curl -s -X POST http://localhost:8000/extract \
     -F "file=@resume.pdf"

curl -s -X POST http://localhost:8000/recreate \
     -F "file=@poster.png" -o recreated.png
```

Endpoints: `POST /identify`, `POST /extract`, `POST /recreate`, `GET /health`,
`GET /schemas` (publish metadata). Interactive docs at `/docs`.

To publish on **RapidAPI**, wrap this ASGI app in a RapidAPI endpoint function
(see `examples/rapidapi_handler.py`) that passes uploaded files to the same
`/identify` logic.

### 4. Streamlit web app (marketplace)

```bash
streamlit run fontident/web/app.py
```

Upload a file, see the identified fonts, and download the recreated PNG.

---

## How the identification works

### Digital documents (exact)

- **DOCX / DOC** — `python-docx` reads per-run font metadata; the OOXML zip is
  additionally scanned for embedded font files under `word/fonts/`.
- **PDF** — `pymupdf` extracts text spans (with font + size + color) **and**
  the actual embedded font data via `page.get_fonts()` / `doc.extract_font()`.
- **ODT / RTF / TXT** — best-effort style/font-table parsing.

### Images (hybrid)

1. **Offline (default):** The image is binarized and split into per-character
   glyphs. Each candidate font from a local catalog (system font dirs, or a
   `catalog_dir` you pass) renders the same characters and the glyph shapes are
   compared with normalized cross-correlation. Fully offline, no API cost.
2. **Online fallback:** If the offline score is too low (or you want more
   coverage) and an API key is configured, the image is sent to
   **Adobe/MyFonts WhatTheFont** (or a RapidAPI WhatTheFont wrapper) and the
   returned matches are merged in.

Configure the online backend with `FONTIDENT_API_KEY` / `ADOBE_WTF_API_KEY`
or the `api_key=` parameter.

---

## Project layout

```
fontident/
  fontident/
    __init__.py          # public API: FontIdent, identify_text, extract_document, ...
    io/
      __init__.py        # file-type detection
      document.py        # DOCX/PDF/ODT/RTF/TXT extractors + embedded fonts
    identify/
      _offline.py        # template-matching image font identifier + catalog
      _online.py         # WhatTheFont / RapidAPI online fallback
    recreate/
      __init__.py        # OCR + rendering text with an identified font
    cli/main.py          # `fontident` command line
    web/
      api.py             # FastAPI (RapidAPI-ready)
      app.py             # Streamlit web app
  tests/                 # pytest suite (+ fixture generators)
  examples/rapidapi_handler.py
  pyproject.toml
  README.md
  LICENSE
```

---

## Roadmap / ideas

- Swap the offline matcher for a deep-learning glyph-embedding model (e.g.
  `fontmatcher`) for higher image accuracy.
- Extract font files to real `.ttf`/`.otf` on disk from embedded document data
  (currently exposed in `analysis.embedded_fonts[*]['data']`).
- Add PDF→searchable-PDF (OCR) output.
- Multi-line image segmentation improvements.

## License

MIT — see [LICENSE](LICENSE).
