Como usar Source Han Sans JP no gpdf?
Registre a variante TTF de Source Han Sans JP do release no GitHub da Adobe com gpdf.WithFont. Sete pesos, SIL OFL, mesmos glifos que Noto Sans JP.
A pergunta, em outras palavras
Você quer usar Source Han Sans JP — a sans-serif pan-CJK open source da Adobe, lançada em 2014 como resultado da parceria Adobe–Google — em um documento gpdf. Talvez seu time prefira fixar fontes em tags de release do GitHub pela reprodutibilidade, talvez você tenha herdado um design system que se padronizou em Source Han anos atrás, talvez o ciclo de releases da Adobe seja mais conveniente. Qualquer motivo serve. Antes de baixar qualquer coisa, vale deixar três coisas claras: qual arquivo pegar, qual é a relação real com Noto Sans JP e qual formato o gpdf consegue ler.
TL;DR
Baixe SourceHanSansJP-Regular.ttf na página de releases de adobe-fonts/source-han-sans (o pacote TTF, não o OTF padrão), passe para gpdf.WithFont("SourceHanSansJP", bytes) e defina como fonte padrão. Source Han Sans JP e Noto Sans JP compartilham os mesmos contornos de glifo — se a história de tooling da Adobe não importa para você, Noto é um download mais simples.
O exemplo 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 — fonte CJK gratuita distribuída pela Adobe.")
})
})
data, err := doc.Generate()
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("report.pdf", data, 0o644); err != nil {
log.Fatal(err)
}
}
Coloque o TTF ao lado de main.go, rode go run main.go e você terá um PDF de uma página com japonês em report.pdf.
Source Han Sans JP é Noto Sans CJK JP
O fato que poupa horas de leitura: Source Han Sans e Noto Sans CJK são as mesmas fontes. A Adobe fez o desenho dos glifos, as tabelas de métricas e a cobertura de caracteres. O Google tocou um canal de distribuição paralelo sob o guarda-chuva Noto. Ambos foram lançados em 2014-07-15. Os contornos, a tabela hmtx e a cobertura de JIS X 0213 / Adobe-Japan1-6 são idênticos, bit a bit. Quando a Adobe publica uma nova versão, as mudanças de glifo chegam ao Noto em poucas semanas.
A diferença está na marca e no empacotamento:
| Source Han Sans JP | Noto Sans JP | |
|---|---|---|
| Publica | Adobe | |
| Fonte canônica | adobe-fonts/source-han-sans | notofonts.github.io + Google Fonts |
| Formato padrão | OTF (contornos CFF) | TTF (estático) + variável |
| Modelo de release | Tags do GitHub, versionamento manual | CDN do Google Fonts + repositórios git |
| Bundling por idioma | TTF por idioma + OTC pan-CJK | Apenas JP |
Use Source Han Sans JP se seu time fixa fontes em tags do GitHub da Adobe, já mantém um mirror interno de github.com/adobe-fonts, ou precisa do bundle OTC pan-CJK em outro pipeline. Use Noto Sans JP se quiser o caminho mais curto para um TTF. Esse caminho está descrito na receita de Noto Sans JP.
Por que TTF, e não OTF
O ativo padrão da Adobe para Source Han Sans é .otf — especificamente OpenType baseado em CFF. O parser de fontes do gpdf vive em um único arquivo (pdf/font/truetype.go) e lê glyf, loca, cmap, hmtx e glifos compostos. Ele não lê contornos CFF / CFF2. Passe um .otf baseado em CFF e o parser rejeita o arquivo já na construção do documento, bem antes de renderizar.
A página de releases da Adobe publica tanto OTF quanto TTF. Pegue o pacote TTF. Se em algum release pontual só houver OTF (acontece de vez em quando), duas alternativas limpas:
- Troque para Noto Sans JP. O Google Fonts serve os TTFs estáticos direto; os dados de glifo são idênticos. Zero conversão, mesmo resultado.
- Converta uma vez e faça commit do resultado.
fonttools(otf2ttf) produz um TTF em um minuto. Suba o resultado para o repo ou para um artifact server interno; a conversão nunca passa pelo seu pipeline de build.
Evite converter em tempo de build. Ferramentas de conversão de fonte mudam de comportamento entre versões, e uma tabela hmtx ligeiramente diferente desloca suas quebras de linha depois de um simples pip install -U.
Os sete pesos
Source Han Sans JP publica de ExtraLight a Heavy, um arquivo por peso:
SourceHanSansJP-ExtraLight.ttf
SourceHanSansJP-Light.ttf
SourceHanSansJP-Normal.ttf
SourceHanSansJP-Regular.ttf
SourceHanSansJP-Medium.ttf
SourceHanSansJP-Bold.ttf
SourceHanSansJP-Heavy.ttf
Para a maioria dos documentos de negócio, Regular e Bold dão conta:
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),
)
O sufixo -Bold é o contrato que liga template.Bold() ao TTF Bold. Sem esse registro, template.Bold() cai no negrito sintetizado — um traço sobreposto sobre os glifos Regular. Legível para cabeçalhos de tabela, mas em corpos grandes fica visivelmente mais fino do que o contorno Bold real.
Fontes CJK, por convenção, não publicam variantes itálicas, e Source Han Sans JP não é exceção. Se seu layout pede ênfase itálica em uma linha em japonês, vá de peso ou cor — uma transformação oblíqua em glifos CJK parece quebrada, não ênfase.
Pan-CJK, só JP, ou o Super OTC
A Adobe publica Source Han Sans em vários níveis de granularidade. Eles não são intercambiáveis para um gerador de PDF em Go:
- SourceHanSans.ttc (Super OTC) — todos os idiomas CJK em um TrueType Collection de 20 MB+. O gpdf não seleciona o face index dentro de um
.ttc; você teria que fatiar a face JP primeiro comfonttoolse registrar o resultado. Ignore o Super OTC. - OTF regional (ex.:
SourceHanSans-Regular.otf) — scripts CJK unificados, contornos CFF. O gpdf não lê. - TTF por idioma (
SourceHanSansJP-Regular.ttf) — só JP, contornosglyf. É o que você quer.
Se seu documento mistura japonês com coreano ou chinês na mesma página, registre famílias específicas por idioma lado a lado: SourceHanSansJP e SourceHanSansKR. Troque explicitamente com template.FontFamily onde o script muda. Apelar para o OTF pan-CJK "resolveria" com Han unification, mas isso traz suas próprias surpresas para leitores que esperam kanji com forma JP em texto JP.
Quando escolher Source Han em vez de Noto
Mesmos contornos, canal de distribuição diferente. Source Han Sans JP faz sentido quando:
- Seu time de ops prefere prender fontes a tags de release da Adobe por reprodutibilidade
- Você já mantém mirror interno de
github.com/adobe-fonts(comum em empresas com políticas restritas de artefatos) - O bundle OTC pan-CJK é útil em outra etapa do pipeline — um fluxo DTP, um handoff para design, um sistema de marca padronizado no nome da Adobe
Noto Sans JP é melhor quando:
- Você quer o caminho mais curto para um TTF (
fonts.google.com/noto/specimen/Noto+Sans+JP→ zip → pronto) - Não quer meter conversão OTF → TTF no seu build
- Seu projeto já puxa outras Google Fonts por um workflow existente
O PDF renderizado fica igual dos dois jeitos. A decisão é operacional — onde o arquivo mora, como você versiona, como o time de ops se sente com isso — não estética.
Leituras relacionadas
- Como usar Noto Sans JP com o gpdf? — os mesmos glifos, já publicados como TTF
- Como incorporar uma fonte japonesa no gpdf? — a receita geral de incorporação CJK
- Como usar IPAex Gothic no gpdf? — a alternativa com licença IPA para envios institucionais japoneses
- Por que meu PDF mostra retângulos no lugar de japonês? — troubleshooting quando os glifos não aparecem
Experimente o gpdf
gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, zero dependências externas, suporte nativo a CJK.
go get github.com/gpdf-dev/gpdf