¿Cómo uso Source Han Sans JP con gpdf?
Registra la variante TTF de Source Han Sans JP desde la release de GitHub de Adobe con gpdf.WithFont. Siete pesos, SIL OFL, mismos glifos que Noto Sans JP.
La pregunta, en otras palabras
Quieres usar Source Han Sans JP — el sans-serif pan-CJK open source de Adobe, lanzado en 2014 como fruto de la colaboración Adobe–Google — en un documento gpdf. Puede ser porque tu equipo fija las fuentes a tags de release de GitHub para tener reproducibilidad, porque heredaste un design system que se estandarizó en Source Han hace años, o porque simplemente te gusta más la cadencia de releases de Adobe. Cualquier motivo vale. Antes de descargar nada, conviene tener claras tres cosas: qué archivo coger, cuál es la relación real con Noto Sans JP, y qué formato puede leer gpdf.
TL;DR
Descarga SourceHanSansJP-Regular.ttf desde la página de releases de adobe-fonts/source-han-sans (el paquete TTF, no el OTF por defecto), pásalo a gpdf.WithFont("SourceHanSansJP", bytes) y ponlo como fuente por defecto. Source Han Sans JP y Noto Sans JP comparten los mismos contornos de glifo — si no tienes preferencia por el tooling de Adobe, Noto es una descarga más directa.
El ejemplo completo
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("SourceHanSansJP-Regular.ttf")
if err != nil {
log.Fatal(err)
}
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
gpdf.WithFont("SourceHanSansJP", font),
gpdf.WithDefaultFont("SourceHanSansJP", 11),
)
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("Source Han Sans JP — fuente CJK gratuita distribuida por Adobe.")
})
})
data, err := doc.Generate()
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("report.pdf", data, 0o644); err != nil {
log.Fatal(err)
}
}
Deja el TTF junto a main.go, corre go run main.go y tendrás un PDF de una página con japonés en report.pdf.
Source Han Sans JP es Noto Sans CJK JP
El hecho que te ahorra horas de lectura: Source Han Sans y Noto Sans CJK son las mismas fuentes. Adobe hizo el diseño de glifos, las tablas de métricas y la cobertura de caracteres. Google se encargó de un canal de distribución paralelo bajo el paraguas Noto. Ambas se lanzaron el 2014-07-15. Los contornos, la tabla hmtx y la cobertura de JIS X 0213 / Adobe-Japan1-6 son idénticos bit a bit. Cuando Adobe publica una versión nueva, los cambios de glifo llegan a Noto en semanas.
Lo que sí cambia es el branding y el empaquetado:
| Source Han Sans JP | Noto Sans JP | |
|---|---|---|
| Publica | Adobe | |
| Fuente canónica | adobe-fonts/source-han-sans | notofonts.github.io + Google Fonts |
| Formato por defecto | OTF (contornos CFF) | TTF (estático) + variable |
| Modelo de release | Tags de GitHub, versionado manual | CDN de Google Fonts + repos git |
| Bundling por idioma | TTF por idioma + OTC pan-CJK | Solo JP |
Vete a Source Han Sans JP si tu equipo fija las fuentes a tags de GitHub de Adobe, ya tienes mirror interno de github.com/adobe-fonts, o necesitas el OTC pan-CJK en otro pipeline. Vete a Noto Sans JP si lo que quieres es la ruta más corta a un TTF. Esa ruta está detallada en la receta de Noto Sans JP.
Por qué TTF, y no OTF
El asset por defecto de Adobe para Source Han Sans es .otf — concretamente OpenType basado en CFF. El parser de fuentes de gpdf vive en un único archivo (pdf/font/truetype.go) y lee glyf, loca, cmap, hmtx y glifos compuestos. No lee contornos CFF / CFF2. Si le pasas un .otf con CFF, el parser rechaza el archivo al construir el documento, mucho antes de renderizar nada.
La página de releases de Adobe publica tanto OTF como TTF. Coge el paquete TTF. Si un release puntual solo incluye OTF (pasa de vez en cuando), dos alternativas limpias:
- Cámbiate a Noto Sans JP. Google Fonts sirve los TTF estáticos directamente; los datos de glifo son idénticos. Cero conversión, mismo resultado.
- Convierte una vez y commitea el resultado.
fonttools(otf2ttf) produce un TTF en un minuto. Sube el resultado al repo o a un artifact server interno para que la conversión no forme parte del build.
Evita convertir en tiempo de build. Las herramientas de conversión de fuentes cambian de comportamiento entre versiones, y una tabla hmtx ligeramente distinta mueve los saltos de línea tras un simple pip install -U.
Los siete pesos
Source Han Sans JP publica de ExtraLight a Heavy, un archivo por peso:
SourceHanSansJP-ExtraLight.ttf
SourceHanSansJP-Light.ttf
SourceHanSansJP-Normal.ttf
SourceHanSansJP-Regular.ttf
SourceHanSansJP-Medium.ttf
SourceHanSansJP-Bold.ttf
SourceHanSansJP-Heavy.ttf
Para la mayoría de documentos de negocio, Regular y Bold cubren el uso:
reg, _ := os.ReadFile("SourceHanSansJP-Regular.ttf")
bold, _ := os.ReadFile("SourceHanSansJP-Bold.ttf")
doc := gpdf.NewDocument(
gpdf.WithFont("SourceHanSansJP", reg),
gpdf.WithFont("SourceHanSansJP-Bold", bold),
gpdf.WithDefaultFont("SourceHanSansJP", 11),
)
El sufijo -Bold es el contrato que conecta template.Bold() con el TTF Bold. Si no lo registras, template.Bold() cae en una negrita sintetizada — un trazo superpuesto sobre los glifos Regular. Legible para encabezados de tabla, pero a tamaño grande se nota más delgada que los contornos Bold reales.
Las fuentes CJK, por convención, no publican variantes itálicas, y Source Han Sans JP no es excepción. Si tu layout pide énfasis itálico en una línea japonesa, tira de peso o de color — una transformación oblicua sobre glifos CJK se ve rota, no enfática.
Pan-CJK, solo JP, o el Super OTC
Adobe publica Source Han Sans en varios niveles de granularidad. No son intercambiables para un generador de PDF en Go:
- SourceHanSans.ttc (Super OTC) — todos los idiomas CJK en un TrueType Collection de más de 20 MB. gpdf no selecciona el face index dentro de un
.ttc; tendrías que extraer primero el face JP confonttoolsy registrar el resultado. Sáltatelo. - OTF regional (ej.
SourceHanSans-Regular.otf) — scripts CJK unificados, contornos CFF. gpdf no lo lee. - TTF por idioma (
SourceHanSansJP-Regular.ttf) — solo JP, contornosglyf. Éste es el que quieres.
Si tu documento mezcla japonés con coreano o chino en la misma página, registra familias específicas por idioma en paralelo: SourceHanSansJP y SourceHanSansKR. Cambia de familia explícitamente con template.FontFamily donde cambia el script. Recurrir al OTF pan-CJK lo "arregla" con Han unification, pero introduce sus propias sorpresas para lectores que esperan kanji con formas JP en texto JP.
Cuándo elegir Source Han en vez de Noto
Mismos contornos, distinto canal de distribución. Source Han Sans JP tiene sentido cuando:
- Tu equipo de ops prefiere fijar fuentes a tags de release de Adobe por reproducibilidad
- Ya hacéis mirror interno de
github.com/adobe-fonts(común en empresas con políticas estrictas de artifacts) - El bundle OTC pan-CJK es útil en otro paso del pipeline — un flujo DTP, un handoff a diseño, un sistema de marca que se estandariza con el nombre de Adobe
Noto Sans JP gana cuando:
- Quieres la ruta más corta a un TTF (
fonts.google.com/noto/specimen/Noto+Sans+JP→ zip → listo) - No quieres meter conversiones OTF→TTF en tu build
- Tu proyecto ya tira de otras Google Fonts con un workflow existente
El PDF renderizado se ve igual. La decisión es operativa — dónde vive el archivo, cómo versionas, cómo lo siente tu equipo de ops — no estética.
Lecturas relacionadas
- ¿Cómo uso Noto Sans JP con gpdf? — los mismos glifos, publicados en TTF de caja
- ¿Cómo incrusto una fuente japonesa en gpdf? — la receta general de incrustación CJK
- ¿Cómo uso IPAex Gothic en gpdf? — la alternativa con licencia IPA para envíos institucionales japoneses
- ¿Por qué mi PDF muestra rectángulos en lugar de japonés? — troubleshooting cuando los glifos no aparecen
Prueba gpdf
gpdf es una librería Go para generar PDFs. Licencia MIT, cero dependencias externas, soporte CJK nativo.
go get github.com/gpdf-dev/gpdf