gpdf에서 IPAex 고딕(IPAex Gothic)을 사용하려면?
ipaexg.ttf를 gpdf.WithFont로 등록한다. IPAex는 Regular 한 가지 굵기만 제공하므로 볼드는 합성하거나 명조와 페어링한다.
질문을 다시 말하면
gpdf 문서에서 IPAex Gothic — 일본 정보처리추진기구(IPA)가 관리하는 프로포셔널 서양 문자 고딕체 — 를 쓰고 싶다. 전형적인 사용처: e-Tax PDF 첨부, 정부 제출 서류, 2010년대 초부터 IPAex로 통일해 온 사내 스타일. 매번 걸리는 곳은 세 군데다. 어떤 파일을 고를지, Bold가 없는 문제를 어떻게 다룰지, IPA Font License가 실제로 무엇을 요구하는지.
빠른 답
ipaexg.ttf를 gpdf.WithFont("IPAexGothic", bytes)로 등록하고 기본 폰트로 설정한다. Bold는 template.Bold()로 합성하거나 IPAex 명조와 페어링한다. IPAex는 Regular 한 가지 굵기만 제공하기 때문이다. 바이너리 배포 시 라이선스 전문을 동봉한다.
완성된 예제
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)
}
}
moji.or.jp/ipafont에서 IPAex00401.zip을 받아 ipaexg.ttf를 main.go 옆에 두고 go run main.go.
어느 IPA 파일이 맞는가
zip을 열면 TTF 세 개와 라이선스가 들어 있다. 이름이 비슷해 혼동하기 쉽다:
| 파일 | 내용 |
|---|---|
ipaexg.ttf | IPAex Gothic — 산세리프, 서양 문자는 프로포셔널. 일반 문서는 이것. |
ipaexm.ttf | IPAex Mincho — 세리프(명조), 서양 문자는 프로포셔널. 본문 길거나 고딕과 짝지어 강조할 때. |
ipag.ttf | IPA Gothic ("ex" 없음) — 산세리프, 서양 문자가 고정폭. 요즘은 잘 안 쓴다. |
IPAex의 "ex"는 extended proportional의 약어다. 원본 IPA 폰트는 서양 문자를 CJK 전각 격자에 맞춰 배치하기 때문에 영문·국문 혼용 시 늘어져 보인다. IPAex는 서양 문자를 프로포셔널로 만들면서 CJK는 기본 격자에 유지한다. 영문 단어, URL, 숫자가 들어가는 거의 모든 업무 문서에서 IPAex가 맞다.
기존 프로젝트가 ipag.ttf를 쓴다면 대개 역사적 이유다(원본 IPA Gothic 2003년, IPAex 2010년 출시). 패밀리명을 IPAexGothic으로 유지하고 파일만 ipaexg.ttf로 바꾸면 코드는 한 줄만 수정하면 된다.
Bold 파일이 없는 문제
IPAex는 패밀리당 Regular 한 굵기만 배포된다. 9단 굵기를 내는 Noto Sans JP에 비하면 눈에 띄는 단점이고, IPAex를 고려했다가 접는 가장 흔한 이유이기도 하다.
gpdf에서 대응법은 둘이다.
합성 볼드. template.Bold()가 Regular 글리프 위에 스트로크를 덧입힌다. 타이포그래피 관점에서는 치트다 — 진짜 볼드 굵기는 두꺼운 획으로 새로 그려진 윤곽을 가진다. 하지만 10 pt 이상 인보이스 제목이나 표 라벨이라면 독자 대부분에게는 구분되지 않는다:
c.Text("合計金額", template.Bold())
IPAex 명조와 페어링. 일본 조판의 고전적인 강조법은 볼드화가 아니라 세리프/산세리프 전환이다. 두 패밀리를 함께 등록한다:
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("ご請求内容は下記の通りです。")
})
})
일본의 청첩장, 공식 보고서에서 흔히 보이는 조합이다 — 제목은 명조, 본문은 고딕. 문서가 관공서로 갈 예정이라면 이 조합이 저쪽에서 기대하는 모양새일 가능성이 높다.
IPA Font License 간단히
IPAex는 SIL OFL이 아니라 IPA Font License Agreement v1.0이다 (OSI 승인). 전반적으로 관대하지만 짚어둘 두 가지:
- 라이선스 전문을 폰트 바이너리와 함께 유지한다.
//go:embed로 TTF를 Go 바이너리에 넣는다면 라이선스 파일도 같이 넣는다. 프로젝트 루트에LICENSES/IPA-FONT-1.0.txt를 두면 대부분의 배포 상황에서 충분하다. - 폰트 이름을 바꾸지 않는다. TTF 자체를 수정해 재배포하는 경우, 파생물에는 "IPA"나 "IPAex"를 포함하지 않는 다른 이름을 붙여야 한다. 단, 이 제약은 렌더링 시의 글리프 서브셋에는 적용되지 않는다. 라이선스 제3조 4항이 폰트로 생성한 "출력 문서"를 명명 제약에서 명시적으로 제외한다.
정리하자면, doc.Generate()에서 gpdf가 서브셋을 만드는 것은 라이선스상 안전하다. PDF에 포함되는 서브셋은 다른 이름을 필요로 하지 않고 "파생 폰트 프로그램" 조항을 트리거하지도 않는다. 폰트를 재배포하는 것이 아니라 문서를 만드는 것이다.
덧붙이자면, gpdf 코어 OSS 저장소에는 IPAex를 넣지 않는다 (golden 테스트는 Noto 계열 SIL OFL 폰트를 쓴다). 하위 사용자가 자기 프로젝트 최상위 LICENSE와 IPA 라이선스 호환성을 일일이 따지지 않도록 하기 위해서다. 애플리케이션에서 IPAex를 쓰는 것은 그 프로젝트의 판단이지 우리의 결정이 아니다.
IPAex vs Noto Sans JP, 어느 쪽을 고르나
| 축 | IPAex Gothic | Noto Sans JP |
|---|---|---|
| 굵기 수 | 1 (Regular) | 9 (Thin → Black) |
| 라이선스 | IPA Font License v1.0 | SIL OFL 1.1 |
| 서양 문자 | 프로포셔널(IPAex) 또는 고정폭(IPA) | 프로포셔널 |
| 기본 설치 | 일부 일본 Linux 배포판, TeX Live ptex-fonts | Android, ChromeOS |
| 전형적 용도 | 일본 정부, 법률, 학술 | 소비자 웹, 국제용 |
| 파일 크기 | 7.5 MB (Gothic) | 5 MB (Regular 단독) |
출력이 일본의 제도적 경계를 넘는 경우 — e-Tax PDF 첨부, 법원 제출 문서, 일본 저널로의 학술 논문 제출 — 에는 IPAex를 고른다. 그 생태계의 평가자, 심사자, OCR 도구가 IPA에 맞춰져 있기 때문이다. 그 외에는 Noto Sans JP로 충분하다. 렌더링 결과는 실용상 거의 같고, 선택 기준은 미감이 아니라 "어느 생태계에 출력하느냐"다.
관련 레시피
- gpdf에서 일본어 폰트를 임베드하려면? — 모든 CJK TTF에 적용되는 일반 레시피
- gpdf에서 Noto Sans JP를 사용하려면? — SIL OFL에 9굵기가 있는 대안
- gpdf로 만든 PDF에서 일본어가 네모로 나올 때 — 글리프가 표시되지 않을 때의 트러블슈팅
- 폰트 가이드 —
WithFont전체 레퍼런스
gpdf를 써보자
gpdf는 Go용 PDF 생성 라이브러리다. MIT 라이선스, 외부 의존성 0, 네이티브 CJK 지원.
go get github.com/gpdf-dev/gpdf