Guía

Fuentes

Trabajar con fuentes y texto CJK en gpdf

Registrar fuentes

Registre fuentes TrueType al crear un documento:

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

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

Multiples familias de fuentes

Registre multiples fuentes 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 cambiar de fuente en los 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))

Soporte CJK

gpdf tiene soporte de primera clase para texto en japones, chino y coreano. Las caracteristicas CJK incluyen salto de linea automatico con reglas kinsoku (prohibicion de ciertos caracteres al inicio/final de linea).

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 multilingues

Para documentos con multiples idiomas CJK, registre cada fuente por separado y cambie con 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"))
    })
})

Codigos QR con contenido CJK

Los codigos QR admiten contenido Unicode, incluido japones:

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

Subconjunto de fuentes

gpdf realiza automaticamente el subconjunto de fuentes TrueType — solo se incrustan los glifos realmente utilizados en el documento. Esto reduce significativamente el tamano del archivo, especialmente para fuentes CJK que pueden contener decenas de miles de glifos.

Formatos de fuente soportados

FormatoSoporte
TrueType (.ttf)Totalmente soportado
OpenType (.otf)Soporte parcial (contornos TrueType)
WOFF / WOFF2No soportado
Type 1No soportado

Limitaciones de conformado de texto

gpdf asigna cada caracter a un glifo uno a uno y no incluye un motor de conformado de texto (text shaping). Los sistemas de escritura que requieren sustitucion contextual de glifos o reordenamiento bidireccional no se maquetan correctamente.

Sistema de escrituraEstado
Latino, cirilico, griegoTotalmente soportado
CJK (japones, chino, coreano)Totalmente soportado
Arabe, hebreo, persa, urduLos glifos se incrustan correctamente, pero sin union cursiva ni reordenamiento RTL
Devanagari, tailandes y otras escrituras complejasSin conformado contextual

En arabe y otras escrituras cursivas, las letras se dibujan en su forma aislada de izquierda a derecha en lugar de unidas y de derecha a izquierda. Las ligaduras y el kerning definidos en las tablas GSUB / GPOS de la fuente tampoco se aplican.

Esto no afecta a la extraccion de texto. Los caracteres se incrustan con un CMap ToUnicode, por lo que copiar desde el PDF o ejecutar pdftotext devuelve la cadena original. Si solo necesitas que el texto sea buscable y seleccionable — por ejemplo al superponer resultados de OCR sobre una pagina escaneada — esta limitacion no afecta al resultado.

Fuentes recomendadas

FuenteCaso de uso
Noto Sans JPTexto en japones
Noto Sans SCChino simplificado
Noto Sans KRTexto en coreano
Noto SansTexto latino/occidental
InterDocumentos con estilo UI moderno
Roboto MonoCodigo y texto monoespaciado

Uso de fuentes con esquema JSON

Al usar el esquema JSON, las fuentes se registran mediante opciones de 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),
)

Siguientes pasos