All posts

How do I use IPAex Gothic in gpdf?

Register ipaexg.ttf with gpdf.WithFont. IPAex Gothic ships a single Regular weight under the IPA Font License — bold emphasis has to be synthesized or paired.

by gpdf team

The question, in other words

You want to use IPAex Gothic — the proportional Gothic font the Japanese Information-technology Promotion Agency (IPA) maintains — in a gpdf document. The typical reasons: e-Tax PDF submissions, government-facing paperwork, or just a house style that's been on IPAex since the early 2010s. Three things trip people up: which file to grab, how to deal with there being no Bold, and what the IPA Font License actually asks of you.

TL;DR

Register ipaexg.ttf with gpdf.WithFont("IPAexGothic", bytes). Set it as the default. Bold emphasis has to be synthesized with template.Bold() or paired with IPAex Mincho since IPAex ships only Regular. Keep the license text next to the binary.

The complete example

package main

import (
    "log"
    "os"

    "github.com/gpdf-dev/gpdf"
    "github.com/gpdf-dev/gpdf/document"
    "github.com/gpdf-dev/gpdf/template"
)

func main() {
    font, err := os.ReadFile("ipaexg.ttf")
    if err != nil {
        log.Fatal(err)
    }

    doc := gpdf.NewDocument(
        gpdf.WithPageSize(gpdf.A4),
        gpdf.WithMargins(document.UniformEdges(document.Mm(25))),
        gpdf.WithFont("IPAexGothic", font),
        gpdf.WithDefaultFont("IPAexGothic", 10.5),
    )

    page := doc.AddPage()
    page.AutoRow(func(r *template.RowBuilder) {
        r.Col(12, func(c *template.ColBuilder) {
            c.Text("請求書", template.FontSize(24), template.Bold())
            c.Text("令和8年4月17日発行")
            c.Text("金額: ¥100,000 (税込)")
        })
    })

    data, err := doc.Generate()
    if err != nil {
        log.Fatal(err)
    }
    if err := os.WriteFile("invoice.pdf", data, 0o644); err != nil {
        log.Fatal(err)
    }
}

Download the IPAex00401.zip from moji.or.jp/ipafont, extract ipaexg.ttf, drop it next to main.go, and go run main.go.

Which IPA file is the right one

Open the zip and you get three TTFs plus a license. People mix these up constantly:

FileWhat it is
ipaexg.ttfIPAex Gothic — sans-serif, proportional Latin. Use this for most documents.
ipaexm.ttfIPAex Mincho — serif, proportional Latin. Use for body text in long-form documents or to pair with Gothic for emphasis.
ipag.ttfIPA Gothic (no "ex") — sans-serif, monospace Latin. Rarely what you want today.

The "ex" in IPAex stands for "extended proportional." The original IPA fonts put Latin characters on fixed CJK-width grids, which made mixed J/E text look stretched. IPAex fixes that by making Latin characters proportional while keeping CJK characters on the normal grid. For any document with English loan words, URLs, or numbers — which is basically every business document in Japan — you want IPAex.

If you inherited a project using ipag.ttf because the engineer who picked the font did it before IPAex existed (original IPA Gothic: 2003, IPAex: 2010), the switch is one file swap. Same family name, same everything else.

No Bold file — now what

IPAex ships exactly one weight per family: Regular. That's unusual compared to Noto Sans JP (nine weights) and it's the single biggest reason people look at IPAex and decide it won't work for their design.

Two ways to handle it in gpdf:

Synthesized bold. template.Bold() applies a stroke overlay on Regular glyphs. Typographically it's a cheat — real bold weights have redrawn outlines with thicker strokes, not Regular traced twice. But for invoice headings and table labels at 10 pt or larger, synthesized bold is indistinguishable to most readers:

c.Text("合計金額", template.Bold())

Pair with IPAex Mincho. The classic Japanese typography move for emphasis isn't bold — it's a serif/sans switch. Register both families:

gothic,  _ := os.ReadFile("ipaexg.ttf")
mincho, _ := os.ReadFile("ipaexm.ttf")

doc := gpdf.NewDocument(
    gpdf.WithFont("IPAexGothic", gothic),
    gpdf.WithFont("IPAexMincho", mincho),
    gpdf.WithDefaultFont("IPAexGothic", 10.5),
)

page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        c.Text("請求書", template.FontFamily("IPAexMincho"), template.FontSize(24))
        c.Text("ご請求内容は下記の通りです。")
    })
})

That's the look you see on Japanese wedding invitations and formal reports — Mincho for titles, Gothic for body. If your document is going to a government office, this is probably the expected combination anyway.

The IPA Font License, briefly

IPAex is not SIL OFL. It's the IPA Font License Agreement v1.0, which is OSI-approved and mostly permissive but has two asks worth naming:

  1. Preserve the license text wherever you ship the font binary. If you //go:embed the TTF, also embed the license file. A project-root LICENSES/IPA-FONT-1.0.txt satisfies this for most distributions.
  2. Don't rename the font. If you modify the TTF itself and redistribute it, you must give the derivative a different name (not containing "IPA" or "IPAex"). Note: this restriction does not apply to glyph subsetting performed at render time. Article 3.4 of the license explicitly exempts output documents created using the font from the naming restriction.

Meaning: gpdf's subsetting at doc.Generate() is fine. The subset font embedded in your PDF doesn't need a different name and doesn't trigger the "Derivative Font Program" clauses. You are creating a document, not redistributing a font.

One thing to flag for contributors building gpdf itself: we avoid shipping IPAex in the gpdf repo (golden file tests use SIL OFL fonts like Noto) precisely so downstream users never have to think about license compatibility with their repo's top-level LICENSE. If you use IPAex in your application, that's your project's choice, not ours.

When to pick IPAex over Noto Sans JP

DimensionIPAex GothicNoto Sans JP
Weights shipped1 (Regular)9 (Thin → Black)
LicenseIPA Font License v1.0SIL OFL 1.1
Latin handlingProportional (IPAex) or monospace (IPA)Proportional
Pre-installed onSome JP Linux distros, TeX Live ptex-fontsAndroid, ChromeOS
Typical audienceJapanese government, legal, academicConsumer web, international
File size7.5 MB (Gothic)5 MB (Regular only)

Pick IPAex when your output crosses a Japanese institutional boundary — e-Tax PDF submissions, court filings, academic paper submissions to a Japanese journal — because graders, reviewers, and OCR tools in those ecosystems are calibrated against IPA. Pick Noto Sans JP for everything else. They render very similarly; the choice is about ecosystem fit, not aesthetics.

Try gpdf

gpdf is a Go library for generating PDFs. MIT licensed, zero external dependencies, native CJK support.

go get github.com/gpdf-dev/gpdf

⭐ Star on GitHub · Read the docs