[{"data":1,"prerenderedAt":1298},["ShallowReactive",2],{"blog-pt-tofu-boxes-japanese":3},{"id":4,"title":5,"author":6,"body":9,"date":1262,"description":1263,"draft":1264,"extension":1265,"howTo":1266,"image":1288,"meta":1289,"navigation":131,"path":1290,"seo":1291,"stem":1292,"tags":1293,"updated":1288,"__hash__":1297},"blogPt/pt/blog/008.tofu-boxes-japanese.md","Por que meu PDF mostra retângulos (tofu) no lugar de japonês?",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1250},"minimark",[12,17,21,25,33,36,97,101,104,707,721,734,738,741,761,781,787,791,798,943,977,981,992,995,998,1028,1031,1035,1041,1106,1120,1123,1155,1159,1175,1179,1209,1213,1216,1233,1246],[13,14,16],"h2",{"id":15},"a-pergunta-em-outras-palavras","A pergunta, em outras palavras",[18,19,20],"p",{},"Escrevi texto japonês com gpdf e o PDF resultante mostra retângulos vazios onde os caracteres deveriam estar. O que é isso e como faço para que os glifos japoneses reais apareçam no arquivo?",[13,22,24],{"id":23},"a-resposta-rápida","A resposta rápida",[18,26,27,28,32],{},"Isso é ",[29,30,31],"em",{},"tofu"," — o visualizador de PDF desenha um retângulo de marcador porque a fonte embutida no PDF não tem glifo para o code point Unicode que você pediu. Quatro coisas causam isso, e uma é muito mais comum que o restante.",[18,34,35],{},"Por ordem de frequência:",[37,38,39,56,73,87],"ol",{},[40,41,42,46,47,51,52,55],"li",{},[43,44,45],"strong",{},"Nenhuma fonte CJK registrada."," ",[48,49,50],"code",{},"gpdf.NewDocument"," não tem nenhuma chamada a ",[48,53,54],{},"WithFont",", então o documento recai nas fontes Base-14 do PDF (Helvetica, Times, Courier). Nenhuma cobre U+3040–U+9FFF.",[40,57,58,46,65,68,69,72],{},[43,59,60,61,64],{},"Fonte CJK registrada, mas o nome da família em ",[48,62,63],{},"c.Text"," está errado.",[48,66,67],{},"WithFont(\"NotoSansJP\", ...)"," está configurado, mas ",[48,70,71],{},"template.FontFamily(\"Arial\")"," no texto força o gpdf a procurar japonês em uma fonte latina.",[40,74,75,78,79,82,83,86],{},[43,76,77],{},"O arquivo de fonte não contém glifos CJK."," O TTF em disco é um subset latino (",[48,80,81],{},"NotoSans-Regular.ttf"," em vez de ",[48,84,85],{},"NotoSansJP-Regular.ttf","). O nome parece certo, a cobertura está vazia.",[40,88,89,92,93,96],{},[43,90,91],{},"Os bytes foram corrompidos antes do gpdf recebê-los."," A string foi decodificada como Shift-JIS ou Latin-1 em algum ponto anterior, e os code points já não são japoneses. Se você vê ",[48,94,95],{},"縺ゅ→縺"," em vez de retângulos, é essa.",[13,98,100],{"id":99},"a-correção-canônica-para-a-causa-1","A correção canônica para a causa #1",[18,102,103],{},"Nove em cada dez vezes é isto:",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    font, err := os.ReadFile(\"NotoSansJP-Regular.ttf\")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(gpdf.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n        gpdf.WithFont(\"NotoSansJP\", font),\n        gpdf.WithDefaultFont(\"NotoSansJP\", 12),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"こんにちは、世界。\")\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"hello.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[48,112,113,126,133,143,155,165,170,180,190,200,206,211,227,265,281,299,305,310,329,353,391,416,441,447,452,471,505,542,564,570,576,581,602,615,630,635,681,696,701],{"__ignoreMap":110},[114,115,118,122],"span",{"class":116,"line":117},"line",1,[114,119,121],{"class":120},"sMK4o","package",[114,123,125],{"class":124},"sBMFI"," main\n",[114,127,129],{"class":116,"line":128},2,[114,130,132],{"emptyLinePlaceholder":131},true,"\n",[114,134,136,140],{"class":116,"line":135},3,[114,137,139],{"class":138},"s7zQu","import",[114,141,142],{"class":120}," (\n",[114,144,146,149,152],{"class":116,"line":145},4,[114,147,148],{"class":120},"    \"",[114,150,151],{"class":124},"log",[114,153,154],{"class":120},"\"\n",[114,156,158,160,163],{"class":116,"line":157},5,[114,159,148],{"class":120},[114,161,162],{"class":124},"os",[114,164,154],{"class":120},[114,166,168],{"class":116,"line":167},6,[114,169,132],{"emptyLinePlaceholder":131},[114,171,173,175,178],{"class":116,"line":172},7,[114,174,148],{"class":120},[114,176,177],{"class":124},"github.com/gpdf-dev/gpdf",[114,179,154],{"class":120},[114,181,183,185,188],{"class":116,"line":182},8,[114,184,148],{"class":120},[114,186,187],{"class":124},"github.com/gpdf-dev/gpdf/document",[114,189,154],{"class":120},[114,191,193,195,198],{"class":116,"line":192},9,[114,194,148],{"class":120},[114,196,197],{"class":124},"github.com/gpdf-dev/gpdf/template",[114,199,154],{"class":120},[114,201,203],{"class":116,"line":202},10,[114,204,205],{"class":120},")\n",[114,207,209],{"class":116,"line":208},11,[114,210,132],{"emptyLinePlaceholder":131},[114,212,214,217,221,224],{"class":116,"line":213},12,[114,215,216],{"class":120},"func",[114,218,220],{"class":219},"s2Zo4"," main",[114,222,223],{"class":120},"()",[114,225,226],{"class":120}," {\n",[114,228,230,234,237,240,243,246,249,252,255,258,261,263],{"class":116,"line":229},13,[114,231,233],{"class":232},"sTEyZ","    font",[114,235,236],{"class":120},",",[114,238,239],{"class":232}," err ",[114,241,242],{"class":120},":=",[114,244,245],{"class":232}," os",[114,247,248],{"class":120},".",[114,250,251],{"class":219},"ReadFile",[114,253,254],{"class":120},"(",[114,256,257],{"class":120},"\"",[114,259,85],{"class":260},"sfazB",[114,262,257],{"class":120},[114,264,205],{"class":120},[114,266,268,271,273,276,279],{"class":116,"line":267},14,[114,269,270],{"class":138},"    if",[114,272,239],{"class":232},[114,274,275],{"class":120},"!=",[114,277,278],{"class":120}," nil",[114,280,226],{"class":120},[114,282,284,287,289,292,294,297],{"class":116,"line":283},15,[114,285,286],{"class":232},"        log",[114,288,248],{"class":120},[114,290,291],{"class":219},"Fatal",[114,293,254],{"class":120},[114,295,296],{"class":232},"err",[114,298,205],{"class":120},[114,300,302],{"class":116,"line":301},16,[114,303,304],{"class":120},"    }\n",[114,306,308],{"class":116,"line":307},17,[114,309,132],{"emptyLinePlaceholder":131},[114,311,313,316,318,321,323,326],{"class":116,"line":312},18,[114,314,315],{"class":232},"    doc ",[114,317,242],{"class":120},[114,319,320],{"class":232}," gpdf",[114,322,248],{"class":120},[114,324,325],{"class":219},"NewDocument",[114,327,328],{"class":120},"(\n",[114,330,332,335,337,340,342,345,347,350],{"class":116,"line":331},19,[114,333,334],{"class":232},"        gpdf",[114,336,248],{"class":120},[114,338,339],{"class":219},"WithPageSize",[114,341,254],{"class":120},[114,343,344],{"class":232},"gpdf",[114,346,248],{"class":120},[114,348,349],{"class":232},"A4",[114,351,352],{"class":120},"),\n",[114,354,356,358,360,363,365,368,370,373,375,377,379,382,384,388],{"class":116,"line":355},20,[114,357,334],{"class":232},[114,359,248],{"class":120},[114,361,362],{"class":219},"WithMargins",[114,364,254],{"class":120},[114,366,367],{"class":232},"document",[114,369,248],{"class":120},[114,371,372],{"class":219},"UniformEdges",[114,374,254],{"class":120},[114,376,367],{"class":232},[114,378,248],{"class":120},[114,380,381],{"class":219},"Mm",[114,383,254],{"class":120},[114,385,387],{"class":386},"sbssI","20",[114,389,390],{"class":120},"))),\n",[114,392,394,396,398,400,402,404,407,409,411,414],{"class":116,"line":393},21,[114,395,334],{"class":232},[114,397,248],{"class":120},[114,399,54],{"class":219},[114,401,254],{"class":120},[114,403,257],{"class":120},[114,405,406],{"class":260},"NotoSansJP",[114,408,257],{"class":120},[114,410,236],{"class":120},[114,412,413],{"class":232}," font",[114,415,352],{"class":120},[114,417,419,421,423,426,428,430,432,434,436,439],{"class":116,"line":418},22,[114,420,334],{"class":232},[114,422,248],{"class":120},[114,424,425],{"class":219},"WithDefaultFont",[114,427,254],{"class":120},[114,429,257],{"class":120},[114,431,406],{"class":260},[114,433,257],{"class":120},[114,435,236],{"class":120},[114,437,438],{"class":386}," 12",[114,440,352],{"class":120},[114,442,444],{"class":116,"line":443},23,[114,445,446],{"class":120},"    )\n",[114,448,450],{"class":116,"line":449},24,[114,451,132],{"emptyLinePlaceholder":131},[114,453,455,458,460,463,465,468],{"class":116,"line":454},25,[114,456,457],{"class":232},"    page ",[114,459,242],{"class":120},[114,461,462],{"class":232}," doc",[114,464,248],{"class":120},[114,466,467],{"class":219},"AddPage",[114,469,470],{"class":120},"()\n",[114,472,474,477,479,482,485,489,492,495,497,500,503],{"class":116,"line":473},26,[114,475,476],{"class":232},"    page",[114,478,248],{"class":120},[114,480,481],{"class":219},"AutoRow",[114,483,484],{"class":120},"(func(",[114,486,488],{"class":487},"sHdIc","r",[114,490,491],{"class":120}," *",[114,493,494],{"class":124},"template",[114,496,248],{"class":120},[114,498,499],{"class":124},"RowBuilder",[114,501,502],{"class":120},")",[114,504,226],{"class":120},[114,506,508,511,513,516,518,521,523,526,529,531,533,535,538,540],{"class":116,"line":507},27,[114,509,510],{"class":232},"        r",[114,512,248],{"class":120},[114,514,515],{"class":219},"Col",[114,517,254],{"class":120},[114,519,520],{"class":386},"12",[114,522,236],{"class":120},[114,524,525],{"class":120}," func(",[114,527,528],{"class":487},"c",[114,530,491],{"class":120},[114,532,494],{"class":124},[114,534,248],{"class":120},[114,536,537],{"class":124},"ColBuilder",[114,539,502],{"class":120},[114,541,226],{"class":120},[114,543,545,548,550,553,555,557,560,562],{"class":116,"line":544},28,[114,546,547],{"class":232},"            c",[114,549,248],{"class":120},[114,551,552],{"class":219},"Text",[114,554,254],{"class":120},[114,556,257],{"class":120},[114,558,559],{"class":260},"こんにちは、世界。",[114,561,257],{"class":120},[114,563,205],{"class":120},[114,565,567],{"class":116,"line":566},29,[114,568,569],{"class":120},"        })\n",[114,571,573],{"class":116,"line":572},30,[114,574,575],{"class":120},"    })\n",[114,577,579],{"class":116,"line":578},31,[114,580,132],{"emptyLinePlaceholder":131},[114,582,584,587,589,591,593,595,597,600],{"class":116,"line":583},32,[114,585,586],{"class":232},"    data",[114,588,236],{"class":120},[114,590,239],{"class":232},[114,592,242],{"class":120},[114,594,462],{"class":232},[114,596,248],{"class":120},[114,598,599],{"class":219},"Generate",[114,601,470],{"class":120},[114,603,605,607,609,611,613],{"class":116,"line":604},33,[114,606,270],{"class":138},[114,608,239],{"class":232},[114,610,275],{"class":120},[114,612,278],{"class":120},[114,614,226],{"class":120},[114,616,618,620,622,624,626,628],{"class":116,"line":617},34,[114,619,286],{"class":232},[114,621,248],{"class":120},[114,623,291],{"class":219},[114,625,254],{"class":120},[114,627,296],{"class":232},[114,629,205],{"class":120},[114,631,633],{"class":116,"line":632},35,[114,634,304],{"class":120},[114,636,638,640,642,644,646,648,651,653,655,658,660,662,665,667,670,673,675,677,679],{"class":116,"line":637},36,[114,639,270],{"class":138},[114,641,239],{"class":232},[114,643,242],{"class":120},[114,645,245],{"class":232},[114,647,248],{"class":120},[114,649,650],{"class":219},"WriteFile",[114,652,254],{"class":120},[114,654,257],{"class":120},[114,656,657],{"class":260},"hello.pdf",[114,659,257],{"class":120},[114,661,236],{"class":120},[114,663,664],{"class":232}," data",[114,666,236],{"class":120},[114,668,669],{"class":386}," 0o644",[114,671,672],{"class":120},");",[114,674,239],{"class":232},[114,676,275],{"class":120},[114,678,278],{"class":120},[114,680,226],{"class":120},[114,682,684,686,688,690,692,694],{"class":116,"line":683},37,[114,685,286],{"class":232},[114,687,248],{"class":120},[114,689,291],{"class":219},[114,691,254],{"class":120},[114,693,296],{"class":232},[114,695,205],{"class":120},[114,697,699],{"class":116,"line":698},38,[114,700,304],{"class":120},[114,702,704],{"class":116,"line":703},39,[114,705,706],{"class":120},"}\n",[18,708,709,710,713,714,717,718,720],{},"Duas linhas registram a fonte e a definem como padrão. Sem CGO. Sem a burocracia do ",[48,711,712],{},"AddUTF8Font",". Se você estava vendo ",[48,715,716],{},"□□□□□、□□。"," e rodar este programa com um ",[48,719,85],{}," real ao lado, os glifos reais aparecem.",[18,722,723,724,726,727,248],{},"Baixe ",[48,725,85],{}," no ",[728,729,733],"a",{"href":730,"rel":731},"https://fonts.google.com/noto/specimen/Noto+Sans+JP",[732],"nofollow","Google Fonts",[13,735,737],{"id":736},"como-saber-qual-causa-é-a-sua","Como saber qual causa é a sua",[18,739,740],{},"A maior parte é olhar três lugares: onde você constrói o documento, onde você escreve o texto e o próprio arquivo TTF.",[18,742,743,749,750,753,754,757,758,760],{},[43,744,745,746],{},"Se a saída são ",[48,747,748],{},"□□□"," (retângulos idênticos), é causa 1, 2 ou 3. O PDF embutiu ",[29,751,752],{},"uma"," fonte, mas ela não tem os glifos. Abra o PDF no Acrobat, vá em ",[48,755,756],{},"Arquivo → Propriedades → Fontes"," e veja quais fontes foram realmente embutidas. Se a lista só tem Helvetica / Times / Courier, causa 1. Se ",[48,759,406],{}," está listada e ainda há retângulos, causa 2 ou 3.",[18,762,763,772,773,776,777,780],{},[43,764,765,766,768,769],{},"Se a saída é ",[48,767,95],{}," ou ",[48,770,771],{},"ã\"ã‚\"ã«ã¡ã¯"," (latim embaralhado), é causa 4. Sua string japonesa foi recodificada antes de chegar ao gpdf. Culpado mais comum: um CSV salvo como Shift-JIS pelo Excel e lido com ",[48,774,775],{},"os.ReadFile"," como se fosse UTF-8, ou um endpoint HTTP que não declarou ",[48,778,779],{},"charset=utf-8",". Conserte o decodificador, não o PDF.",[18,782,783,786],{},[43,784,785],{},"Saída mista"," — alguns caracteres renderizam, outros viram retângulos — significa cobertura parcial da fonte. Uma fonte rotulada como \"japonesa\" pode incluir hiragana e katakana mas pular kanjis incomuns como 鬱 ou 龠. Troque para Noto Sans JP (cobre JIS X 0213) ou Source Han Sans JP se isso acontecer.",[13,788,790],{"id":789},"causa-2-em-detalhe-fonte-certa-nome-de-família-errado","Causa 2 em detalhe: fonte certa, nome de família errado",[18,792,793,794,797],{},"Essa é traiçoeira porque a fonte ",[29,795,796],{},"está"," embutida — simplesmente não é usada. Reprodução mínima:",[105,799,801],{"className":107,"code":800,"language":109,"meta":110,"style":110},"doc := gpdf.NewDocument(\n    gpdf.WithFont(\"NotoSansJP\", font),\n    // Sem WithDefaultFont.\n)\n\npage.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Text(\"こんにちは\") // Usa a fonte padrão: Helvetica.\n    })\n})\n",[48,802,803,818,841,847,851,855,880,911,934,938],{"__ignoreMap":110},[114,804,805,808,810,812,814,816],{"class":116,"line":117},[114,806,807],{"class":232},"doc ",[114,809,242],{"class":120},[114,811,320],{"class":232},[114,813,248],{"class":120},[114,815,325],{"class":219},[114,817,328],{"class":120},[114,819,820,823,825,827,829,831,833,835,837,839],{"class":116,"line":128},[114,821,822],{"class":232},"    gpdf",[114,824,248],{"class":120},[114,826,54],{"class":219},[114,828,254],{"class":120},[114,830,257],{"class":120},[114,832,406],{"class":260},[114,834,257],{"class":120},[114,836,236],{"class":120},[114,838,413],{"class":232},[114,840,352],{"class":120},[114,842,843],{"class":116,"line":135},[114,844,846],{"class":845},"sHwdD","    // Sem WithDefaultFont.\n",[114,848,849],{"class":116,"line":145},[114,850,205],{"class":120},[114,852,853],{"class":116,"line":157},[114,854,132],{"emptyLinePlaceholder":131},[114,856,857,860,862,864,866,868,870,872,874,876,878],{"class":116,"line":167},[114,858,859],{"class":232},"page",[114,861,248],{"class":120},[114,863,481],{"class":219},[114,865,484],{"class":120},[114,867,488],{"class":487},[114,869,491],{"class":120},[114,871,494],{"class":124},[114,873,248],{"class":120},[114,875,499],{"class":124},[114,877,502],{"class":120},[114,879,226],{"class":120},[114,881,882,885,887,889,891,893,895,897,899,901,903,905,907,909],{"class":116,"line":172},[114,883,884],{"class":232},"    r",[114,886,248],{"class":120},[114,888,515],{"class":219},[114,890,254],{"class":120},[114,892,520],{"class":386},[114,894,236],{"class":120},[114,896,525],{"class":120},[114,898,528],{"class":487},[114,900,491],{"class":120},[114,902,494],{"class":124},[114,904,248],{"class":120},[114,906,537],{"class":124},[114,908,502],{"class":120},[114,910,226],{"class":120},[114,912,913,916,918,920,922,924,927,929,931],{"class":116,"line":182},[114,914,915],{"class":232},"        c",[114,917,248],{"class":120},[114,919,552],{"class":219},[114,921,254],{"class":120},[114,923,257],{"class":120},[114,925,926],{"class":260},"こんにちは",[114,928,257],{"class":120},[114,930,502],{"class":120},[114,932,933],{"class":845}," // Usa a fonte padrão: Helvetica.\n",[114,935,936],{"class":116,"line":192},[114,937,575],{"class":120},[114,939,940],{"class":116,"line":202},[114,941,942],{"class":120},"})\n",[18,944,945,946,949,950,952,953,956,957,959,960,962,963,965,966,969,970,972,973,976],{},"Correção: adicione ",[48,947,948],{},"gpdf.WithDefaultFont(\"NotoSansJP\", 12)"," ao ",[48,951,325],{},", ou passe ",[48,954,955],{},"template.FontFamily(\"NotoSansJP\")"," em cada ",[48,958,63],{}," que precisa de japonês. O nome de família em ",[48,961,54],{}," e o em ",[48,964,63],{}," devem bater ",[43,967,968],{},"exatamente",", incluindo caixa. Para o gpdf, ",[48,971,406],{}," e ",[48,974,975],{},"notosansjp"," são duas fontes diferentes.",[13,978,980],{"id":979},"causa-3-em-detalhe-o-arquivo-ttf-errado","Causa 3 em detalhe: o arquivo TTF errado",[18,982,983,972,985,987,988,991],{},[48,984,81],{},[48,986,85],{}," são arquivos diferentes. O primeiro é uma fonte latina sem nenhuma cobertura CJK. O segundo é a versão japonesa, com cerca de 17.000 glifos. Eles ficam quase idênticos em um ",[48,989,990],{},"ls",", e o autocomplete do editor pega o errado com facilidade.",[18,993,994],{},"O gpdf não valida cobertura de glifos no registro. Se você entrega bytes, ele confia. A falha só aparece como tofu no momento do render.",[18,996,997],{},"Maneira rápida de conferir:",[999,1000,1001,1008,1015],"ul",{},[40,1002,1003,1004,1007],{},"macOS: ",[48,1005,1006],{},"Font Book"," → duplo-clique no arquivo → a prévia mostra uma grade de glifos",[40,1009,1010,1011,1014],{},"Linux: ",[48,1012,1013],{},"otfinfo -u NotoSans-Regular.ttf"," lista a cobertura Unicode",[40,1016,1017,1018,1023,1024,1027],{},"Multiplataforma: ",[728,1019,1022],{"href":1020,"rel":1021},"https://github.com/fonttools/fonttools",[732],"fontTools"," — ",[48,1025,1026],{},"ttx -t cmap NotoSans-Regular.ttf"," despeja a tabela cmap como XML",[18,1029,1030],{},"Se U+3042 (あ) não está na lista, você está com o subset latino.",[13,1032,1034],{"id":1033},"causa-4-em-detalhe-corrupção-de-encoding","Causa 4 em detalhe: corrupção de encoding",[18,1036,1037,1038,1040],{},"Essa na verdade não envolve o gpdf. A string entregue ao ",[48,1039,63],{}," já tinha os bytes errados. Imprima antes de renderizar:",[105,1042,1044],{"className":107,"code":1043,"language":109,"meta":110,"style":110},"text := loadLabelFromSomewhere()\nfmt.Printf(\"%q\\n\", text) // Mostra as runas reais\nc.Text(text)\n",[48,1045,1046,1058,1091],{"__ignoreMap":110},[114,1047,1048,1051,1053,1056],{"class":116,"line":117},[114,1049,1050],{"class":232},"text ",[114,1052,242],{"class":120},[114,1054,1055],{"class":219}," loadLabelFromSomewhere",[114,1057,470],{"class":120},[114,1059,1060,1063,1065,1068,1070,1072,1076,1079,1081,1083,1086,1088],{"class":116,"line":128},[114,1061,1062],{"class":232},"fmt",[114,1064,248],{"class":120},[114,1066,1067],{"class":219},"Printf",[114,1069,254],{"class":120},[114,1071,257],{"class":120},[114,1073,1075],{"class":1074},"swJcz","%q",[114,1077,1078],{"class":232},"\\n",[114,1080,257],{"class":120},[114,1082,236],{"class":120},[114,1084,1085],{"class":232}," text",[114,1087,502],{"class":120},[114,1089,1090],{"class":845}," // Mostra as runas reais\n",[114,1092,1093,1095,1097,1099,1101,1104],{"class":116,"line":135},[114,1094,528],{"class":232},[114,1096,248],{"class":120},[114,1098,552],{"class":219},[114,1100,254],{"class":120},[114,1102,1103],{"class":232},"text",[114,1105,205],{"class":120},[18,1107,1108,1109,1112,1113,82,1116,1119],{},"Se ",[48,1110,1111],{},"fmt.Printf(\"%q\\n\", text)"," imprime ",[48,1114,1115],{},"\"縺ゅ→縺\"",[48,1117,1118],{},"\"あいうえ\"",", a corrupção aconteceu antes. O gpdf não pode consertar — ache o ponto onde o UTF-8 foi decodificado errado.",[18,1121,1122],{},"Culpados habituais lá na frente:",[999,1124,1125,1134,1148],{},[40,1126,1127,1128,1130,1131],{},"Ler um CSV exportado do Excel (Windows Shift-JIS) com ",[48,1129,775],{}," e converter direto em ",[48,1132,1133],{},"string",[40,1135,1136,1137,768,1140,1143,1144,1147],{},"Uma coluna de banco declarada ",[48,1138,1139],{},"latin1",[48,1141,1142],{},"utf8mb3"," (não ",[48,1145,1146],{},"utf8mb4",") já guardando mojibake",[40,1149,1150,1151,1154],{},"Uma resposta HTTP sem ",[48,1152,1153],{},"Content-Type: application/json; charset=utf-8"," e um cliente que chutou Latin-1",[13,1156,1158],{"id":1157},"um-caso-de-borda-que-vale-mencionar","Um caso de borda que vale mencionar",[18,1160,1161,1162,1165,1166,1168,1169,1172,1173,248],{},"O gpdf faz subset silenciosamente. O subset congela no instante de ",[48,1163,1164],{},"Generate()",". Se durante a construção do documento você renderiza ",[48,1167,926],{}," e depois ",[48,1170,1171],{},"鬱陶しい",", o segundo também entra no subset corretamente. Mas se você gerar o PDF, abrir no Acrobat e digitar um kanji que não estava no texto original, aquele caractere virá como tofu — aquele glifo nunca entrou no subset. Não edite o PDF depois; rode o programa Go de novo e chame ",[48,1174,1164],{},[13,1176,1178],{"id":1177},"receitas-relacionadas","Receitas relacionadas",[999,1180,1181,1191,1202],{},[40,1182,1183,1187,1188,1190],{},[728,1184,1186],{"href":1185},"/pt/blog/embed-japanese-font","Como incorporar uma fonte japonesa no gpdf?"," — guia completo do ",[48,1189,54],{}," com variantes bold/italic e documentos multi-CJK",[40,1192,1193,1197,1198,1201],{},[728,1194,1196],{"href":1195},"/pt/blog/noto-sans-jp-with-gpdf","Como usar Noto Sans JP com o gpdf?"," — qual arquivo do Noto escolher e como o ",[48,1199,1200],{},"go:embed"," simplifica a distribuição",[40,1203,1204,1208],{},[728,1205,1207],{"href":1206},"/pt/blog/japanese-pdf-in-go","Guia definitivo de PDFs em japonês com Go (2026)"," — guia longo cobrindo fontes, texto vertical, ruby e layout específico de JP",[13,1210,1212],{"id":1211},"experimente-o-gpdf","Experimente o gpdf",[18,1214,1215],{},"gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, zero dependências externas, suporte nativo a CJK.",[105,1217,1221],{"className":1218,"code":1219,"language":1220,"meta":110,"style":110},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[48,1222,1223],{"__ignoreMap":110},[114,1224,1225,1227,1230],{"class":116,"line":117},[114,1226,109],{"class":124},[114,1228,1229],{"class":260}," get",[114,1231,1232],{"class":260}," github.com/gpdf-dev/gpdf\n",[18,1234,1235,1240,1241],{},[728,1236,1239],{"href":1237,"rel":1238},"https://github.com/gpdf-dev/gpdf",[732],"⭐ Star no GitHub"," · ",[728,1242,1245],{"href":1243,"rel":1244},"https://gpdf.dev/pt/docs/quickstart",[732],"Ler a documentação",[1247,1248,1249],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":110,"searchDepth":128,"depth":128,"links":1251},[1252,1253,1254,1255,1256,1257,1258,1259,1260,1261],{"id":15,"depth":128,"text":16},{"id":23,"depth":128,"text":24},{"id":99,"depth":128,"text":100},{"id":736,"depth":128,"text":737},{"id":789,"depth":128,"text":790},{"id":979,"depth":128,"text":980},{"id":1033,"depth":128,"text":1034},{"id":1157,"depth":128,"text":1158},{"id":1177,"depth":128,"text":1178},{"id":1211,"depth":128,"text":1212},"2026-04-17","Retângulos vazios em vez de caracteres japoneses significam que o PDF não encontrou glifos para esses code points. Quatro causas e como corrigir.",false,"md",{"name":1267,"totalTime":1268,"tools":1269,"steps":1272},"Diagnosticar e corrigir retângulos tofu em um documento gpdf","PT15M",[1270,1271],"Go 1.22+","Uma TTF com suporte a CJK, como NotoSansJP-Regular.ttf",[1273,1276,1279,1282,1285],{"name":1274,"text":1275},"Confirme se o sintoma é tofu ou mojibake","Abra o PDF. Caracteres japoneses aparecendo como retângulos vazios (□) indicam falha de lookup da fonte. Texto latino embaralhado como 縺ゅ→縺 indica UTF-8 decodificado errado antes de chegar ao gpdf.",{"name":1277,"text":1278},"Verifique se há uma fonte CJK registrada","Procure por gpdf.WithFont na construção do documento. Sem um TTF CJK registrado, o gpdf recai nas fontes Base-14 do PDF, e nenhuma cobre code points CJK.",{"name":1280,"text":1281},"Valide o nome da família em cada c.Text","Sem WithDefaultFont, todo c.Text que renderiza japonês precisa de template.FontFamily(\"NotoSansJP\") explícito. Um nome errado cai silenciosamente na fonte padrão.",{"name":1283,"text":1284},"Confirme que o arquivo TTF contém mesmo glifos CJK","NotoSans-Regular.ttf (subset Latin) e NotoSansJP-Regular.ttf são arquivos diferentes. O gpdf não valida cobertura de glifos no momento do registro.",{"name":1286,"text":1287},"Regenere e verifique em dois visualizadores","Abra o PDF no Adobe Acrobat e no Chrome. Ambos devem renderizar japonês. Se só um funciona, os glifos estão embutidos mas o subset registrado não bate com aquele code point.",null,{},"/pt/blog/tofu-boxes-japanese",{"title":5,"description":1263},"pt/blog/008.tofu-boxes-japanese",[1294,1295,1296],"recipe","troubleshooting","cjk","y_ip_ZS6ag1jRJItYThmCnO7fPJl7zFkrHkgVsI6fMQ",1776529275883]