Guia

Fontes

Trabalhando com fontes e texto CJK no gpdf

Registrando Fontes

Registre fontes TrueType ao criar um documento:

fontData, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")

doc := template.New(
    template.WithPageSize(document.A4),
    template.WithFont("NotoSansJP", fontData),
    template.WithDefaultFont("NotoSansJP", 12),
)

Multiplas Familias de Fontes

Registre multiplas fontes para diferentes casos de uso:

regular, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")
bold, _ := os.ReadFile("fonts/NotoSansJP-Bold.ttf")
mono, _ := os.ReadFile("fonts/RobotoMono-Regular.ttf")

doc := template.New(
    template.WithFont("NotoSansJP", regular),
    template.WithFont("NotoSansJP-Bold", bold),
    template.WithFont("RobotoMono", mono),
    template.WithDefaultFont("NotoSansJP", 12),
)

Use FontFamily() para alternar fontes nos elementos de texto:

c.Text("Regular text")  // uses default NotoSansJP
c.Text("Bold heading", template.FontFamily("NotoSansJP-Bold"), template.FontSize(18))
c.Text("Code snippet", template.FontFamily("RobotoMono"), template.FontSize(10))

Suporte CJK

gpdf tem suporte de primeira classe para texto em japones, chines e coreano. Os recursos CJK incluem quebra de linha automatica com regras kinsoku (proibicao de certos caracteres no inicio/fim das linhas).

fontData, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")

doc := template.New(
    template.WithPageSize(document.A4),
    template.WithMargins(document.UniformEdges(document.Mm(20))),
    template.WithFont("NotoSansJP", fontData),
    template.WithDefaultFont("NotoSansJP", 12),
)

page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(12, func(c *template.ColBuilder) {
        c.Text("日本語テキストのサンプル", template.FontSize(18))
        c.Text("gpdfは純Go・ゼロ依存のPDF生成ライブラリです。")
        c.Text("CJKテキストの改行やレイアウトを正しく処理します。")
    })
})

Documentos CJK multilíngues

Para documentos com várias línguas CJK, registre cada fonte separadamente e alterne com FontFamily():

jpFont, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")
scFont, _ := os.ReadFile("fonts/NotoSansSC-Regular.ttf")
krFont, _ := os.ReadFile("fonts/NotoSansKR-Regular.ttf")

doc := template.New(
    template.WithPageSize(document.A4),
    template.WithFont("NotoSansJP", jpFont),
    template.WithFont("NotoSansSC", scFont),
    template.WithFont("NotoSansKR", krFont),
    template.WithDefaultFont("NotoSansJP", 12),
)

page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
    r.Col(4, func(c *template.ColBuilder) {
        c.Text("こんにちは", template.FontFamily("NotoSansJP"))
    })
    r.Col(4, func(c *template.ColBuilder) {
        c.Text("你好", template.FontFamily("NotoSansSC"))
    })
    r.Col(4, func(c *template.ColBuilder) {
        c.Text("안녕하세요", template.FontFamily("NotoSansKR"))
    })
})

QR Codes com Conteudo CJK

QR codes suportam conteudo Unicode incluindo japones:

c.QRCode("こんにちは世界", template.QRSize(document.Mm(30)))

Subsetting de Fontes

gpdf automaticamente faz subset de fontes TrueType — apenas os glifos realmente utilizados no documento sao incorporados. Isso reduz significativamente o tamanho do arquivo, especialmente para fontes CJK que podem conter dezenas de milhares de glifos.

Formatos de Fonte Suportados

FormatoSuporte
TrueType (.ttf)Totalmente suportado
OpenType (.otf)Suporte parcial (contornos TrueType)
WOFF / WOFF2Nao suportado
Type 1Nao suportado

Limitacoes de conformacao de texto

gpdf mapeia cada caractere para um glifo um a um e nao inclui um motor de conformacao de texto (text shaping). Sistemas de escrita que exigem substituicao contextual de glifos ou reordenacao bidirecional nao sao diagramados corretamente.

Sistema de escritaEstado
Latino, cirilico, gregoTotalmente suportado
CJK (japones, chines, coreano)Totalmente suportado
Arabe, hebraico, persa, urduOs glifos sao incorporados corretamente, mas sem ligacao cursiva nem reordenacao RTL
Devanagari, tailandes e outras escritas complexasSem conformacao contextual

Em arabe e outras escritas cursivas, as letras sao desenhadas em sua forma isolada da esquerda para a direita, em vez de ligadas e da direita para a esquerda. Ligaduras e kerning definidos nas tabelas GSUB / GPOS da fonte tambem nao sao aplicados.

Isso nao afeta a extracao de texto. Os caracteres sao incorporados com um CMap ToUnicode, entao copiar do PDF ou executar pdftotext retorna a string original. Se voce so precisa que o texto seja pesquisavel e selecionavel — por exemplo ao sobrepor resultados de OCR em uma pagina digitalizada — a limitacao nao afeta o resultado.

Fontes Recomendadas

FonteCaso de Uso
Noto Sans JPTexto em japones
Noto Sans SCChines simplificado
Noto Sans KRTexto em coreano
Noto SansTexto latino/ocidental
InterDocumentos com estilo moderno de UI
Roboto MonoCodigo e texto monospacado

Uso de Fontes no JSON Schema

Ao usar JSON schema, as fontes sao registradas via opcoes Go:

fontData, _ := os.ReadFile("fonts/NotoSansJP-Regular.ttf")

schema := []byte(`{
    "page": {"size": "A4"},
    "body": [
        {"row": {"cols": [
            {"span": 12, "text": "日本語テキスト", "style": {"font": "NotoSansJP"}}
        ]}}
    ]
}`)

doc, err := template.FromJSON(schema, nil,
    template.WithFont("NotoSansJP", fontData),
)

Proximos Passos