[{"data":1,"prerenderedAt":1609},["ShallowReactive",2],{"blog-es-noto-sans-jp-with-gpdf":3},{"id":4,"title":5,"author":6,"body":9,"date":1576,"description":1577,"draft":1578,"extension":1579,"howTo":1580,"image":1599,"meta":1600,"navigation":89,"path":1601,"seo":1602,"stem":1603,"tags":1604,"updated":1599,"__hash__":1608},"blogEs/es/blog/004.noto-sans-jp-with-gpdf.md","¿Cómo uso Noto Sans JP con gpdf?",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1563},"minimark",[12,17,34,38,58,62,710,730,734,741,768,775,802,805,809,812,881,902,915,919,922,1075,1092,1095,1167,1178,1182,1185,1188,1255,1258,1261,1265,1268,1274,1287,1296,1310,1314,1317,1476,1483,1487,1523,1527,1530,1547,1559],[13,14,16],"h2",{"id":15},"la-pregunta-reformulada","La pregunta, reformulada",[18,19,20,21,28,29,33],"p",{},"Quieres renderizar texto japonés en un documento de ",[22,23,27],"a",{"href":24,"rel":25},"https://github.com/gpdf-dev/gpdf",[26],"nofollow","gpdf"," y has elegido Noto Sans JP — la sans-serif gratuita de Google bajo SIL OFL que cubre el rango JIS completo. Ya has descargado el zip de Google Fonts. Lo que falta por aclarar son tres cosas: ",[30,31,32],"strong",{},"qué archivo elegir, qué pesos registrar y cuál es la única trampa escondida dentro del zip",".",[13,35,37],{"id":36},"tldr","TL;DR",[18,39,40,41,44,45,49,50,53,54,57],{},"Usa el TTF ",[30,42,43],{},"static"," ",[46,47,48],"code",{},"NotoSansJP-Regular.ttf"," que está dentro de la carpeta ",[46,51,52],{},"static/"," del zip. No uses la variable font de la raíz. Pásalo a ",[46,55,56],{},"gpdf.WithFont(\"NotoSansJP\", bytes)"," y márcalo como fuente por defecto. gpdf subsetea los ~17.000 glifos y deja solo los que realmente renderizaste — una factura típica acaba con 20–40 KB de datos de fuente en el PDF final.",[13,59,61],{"id":60},"ejemplo-completo","Ejemplo completo",[63,64,69],"pre",{"className":65,"code":66,"language":67,"meta":68,"style":68},"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\", 11),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"請求書\", template.FontSize(28), template.Bold())\n            c.Text(\"Noto Sans JP、これで十分。\")\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"invoice.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[46,70,71,84,91,101,113,123,128,138,148,158,164,169,185,222,238,256,262,267,286,309,347,373,398,404,409,428,462,499,547,567,573,579,584,605,618,633,638,684,699,704],{"__ignoreMap":68},[72,73,76,80],"span",{"class":74,"line":75},"line",1,[72,77,79],{"class":78},"sMK4o","package",[72,81,83],{"class":82},"sBMFI"," main\n",[72,85,87],{"class":74,"line":86},2,[72,88,90],{"emptyLinePlaceholder":89},true,"\n",[72,92,94,98],{"class":74,"line":93},3,[72,95,97],{"class":96},"s7zQu","import",[72,99,100],{"class":78}," (\n",[72,102,104,107,110],{"class":74,"line":103},4,[72,105,106],{"class":78},"    \"",[72,108,109],{"class":82},"log",[72,111,112],{"class":78},"\"\n",[72,114,116,118,121],{"class":74,"line":115},5,[72,117,106],{"class":78},[72,119,120],{"class":82},"os",[72,122,112],{"class":78},[72,124,126],{"class":74,"line":125},6,[72,127,90],{"emptyLinePlaceholder":89},[72,129,131,133,136],{"class":74,"line":130},7,[72,132,106],{"class":78},[72,134,135],{"class":82},"github.com/gpdf-dev/gpdf",[72,137,112],{"class":78},[72,139,141,143,146],{"class":74,"line":140},8,[72,142,106],{"class":78},[72,144,145],{"class":82},"github.com/gpdf-dev/gpdf/document",[72,147,112],{"class":78},[72,149,151,153,156],{"class":74,"line":150},9,[72,152,106],{"class":78},[72,154,155],{"class":82},"github.com/gpdf-dev/gpdf/template",[72,157,112],{"class":78},[72,159,161],{"class":74,"line":160},10,[72,162,163],{"class":78},")\n",[72,165,167],{"class":74,"line":166},11,[72,168,90],{"emptyLinePlaceholder":89},[72,170,172,175,179,182],{"class":74,"line":171},12,[72,173,174],{"class":78},"func",[72,176,178],{"class":177},"s2Zo4"," main",[72,180,181],{"class":78},"()",[72,183,184],{"class":78}," {\n",[72,186,188,192,195,198,201,204,206,209,212,215,218,220],{"class":74,"line":187},13,[72,189,191],{"class":190},"sTEyZ","    font",[72,193,194],{"class":78},",",[72,196,197],{"class":190}," err ",[72,199,200],{"class":78},":=",[72,202,203],{"class":190}," os",[72,205,33],{"class":78},[72,207,208],{"class":177},"ReadFile",[72,210,211],{"class":78},"(",[72,213,214],{"class":78},"\"",[72,216,48],{"class":217},"sfazB",[72,219,214],{"class":78},[72,221,163],{"class":78},[72,223,225,228,230,233,236],{"class":74,"line":224},14,[72,226,227],{"class":96},"    if",[72,229,197],{"class":190},[72,231,232],{"class":78},"!=",[72,234,235],{"class":78}," nil",[72,237,184],{"class":78},[72,239,241,244,246,249,251,254],{"class":74,"line":240},15,[72,242,243],{"class":190},"        log",[72,245,33],{"class":78},[72,247,248],{"class":177},"Fatal",[72,250,211],{"class":78},[72,252,253],{"class":190},"err",[72,255,163],{"class":78},[72,257,259],{"class":74,"line":258},16,[72,260,261],{"class":78},"    }\n",[72,263,265],{"class":74,"line":264},17,[72,266,90],{"emptyLinePlaceholder":89},[72,268,270,273,275,278,280,283],{"class":74,"line":269},18,[72,271,272],{"class":190},"    doc ",[72,274,200],{"class":78},[72,276,277],{"class":190}," gpdf",[72,279,33],{"class":78},[72,281,282],{"class":177},"NewDocument",[72,284,285],{"class":78},"(\n",[72,287,289,292,294,297,299,301,303,306],{"class":74,"line":288},19,[72,290,291],{"class":190},"        gpdf",[72,293,33],{"class":78},[72,295,296],{"class":177},"WithPageSize",[72,298,211],{"class":78},[72,300,27],{"class":190},[72,302,33],{"class":78},[72,304,305],{"class":190},"A4",[72,307,308],{"class":78},"),\n",[72,310,312,314,316,319,321,324,326,329,331,333,335,338,340,344],{"class":74,"line":311},20,[72,313,291],{"class":190},[72,315,33],{"class":78},[72,317,318],{"class":177},"WithMargins",[72,320,211],{"class":78},[72,322,323],{"class":190},"document",[72,325,33],{"class":78},[72,327,328],{"class":177},"UniformEdges",[72,330,211],{"class":78},[72,332,323],{"class":190},[72,334,33],{"class":78},[72,336,337],{"class":177},"Mm",[72,339,211],{"class":78},[72,341,343],{"class":342},"sbssI","20",[72,345,346],{"class":78},"))),\n",[72,348,350,352,354,357,359,361,364,366,368,371],{"class":74,"line":349},21,[72,351,291],{"class":190},[72,353,33],{"class":78},[72,355,356],{"class":177},"WithFont",[72,358,211],{"class":78},[72,360,214],{"class":78},[72,362,363],{"class":217},"NotoSansJP",[72,365,214],{"class":78},[72,367,194],{"class":78},[72,369,370],{"class":190}," font",[72,372,308],{"class":78},[72,374,376,378,380,383,385,387,389,391,393,396],{"class":74,"line":375},22,[72,377,291],{"class":190},[72,379,33],{"class":78},[72,381,382],{"class":177},"WithDefaultFont",[72,384,211],{"class":78},[72,386,214],{"class":78},[72,388,363],{"class":217},[72,390,214],{"class":78},[72,392,194],{"class":78},[72,394,395],{"class":342}," 11",[72,397,308],{"class":78},[72,399,401],{"class":74,"line":400},23,[72,402,403],{"class":78},"    )\n",[72,405,407],{"class":74,"line":406},24,[72,408,90],{"emptyLinePlaceholder":89},[72,410,412,415,417,420,422,425],{"class":74,"line":411},25,[72,413,414],{"class":190},"    page ",[72,416,200],{"class":78},[72,418,419],{"class":190}," doc",[72,421,33],{"class":78},[72,423,424],{"class":177},"AddPage",[72,426,427],{"class":78},"()\n",[72,429,431,434,436,439,442,446,449,452,454,457,460],{"class":74,"line":430},26,[72,432,433],{"class":190},"    page",[72,435,33],{"class":78},[72,437,438],{"class":177},"AutoRow",[72,440,441],{"class":78},"(func(",[72,443,445],{"class":444},"sHdIc","r",[72,447,448],{"class":78}," *",[72,450,451],{"class":82},"template",[72,453,33],{"class":78},[72,455,456],{"class":82},"RowBuilder",[72,458,459],{"class":78},")",[72,461,184],{"class":78},[72,463,465,468,470,473,475,478,480,483,486,488,490,492,495,497],{"class":74,"line":464},27,[72,466,467],{"class":190},"        r",[72,469,33],{"class":78},[72,471,472],{"class":177},"Col",[72,474,211],{"class":78},[72,476,477],{"class":342},"12",[72,479,194],{"class":78},[72,481,482],{"class":78}," func(",[72,484,485],{"class":444},"c",[72,487,448],{"class":78},[72,489,451],{"class":82},[72,491,33],{"class":78},[72,493,494],{"class":82},"ColBuilder",[72,496,459],{"class":78},[72,498,184],{"class":78},[72,500,502,505,507,510,512,514,517,519,521,524,526,529,531,534,537,539,541,544],{"class":74,"line":501},28,[72,503,504],{"class":190},"            c",[72,506,33],{"class":78},[72,508,509],{"class":177},"Text",[72,511,211],{"class":78},[72,513,214],{"class":78},[72,515,516],{"class":217},"請求書",[72,518,214],{"class":78},[72,520,194],{"class":78},[72,522,523],{"class":190}," template",[72,525,33],{"class":78},[72,527,528],{"class":177},"FontSize",[72,530,211],{"class":78},[72,532,533],{"class":342},"28",[72,535,536],{"class":78},"),",[72,538,523],{"class":190},[72,540,33],{"class":78},[72,542,543],{"class":177},"Bold",[72,545,546],{"class":78},"())\n",[72,548,550,552,554,556,558,560,563,565],{"class":74,"line":549},29,[72,551,504],{"class":190},[72,553,33],{"class":78},[72,555,509],{"class":177},[72,557,211],{"class":78},[72,559,214],{"class":78},[72,561,562],{"class":217},"Noto Sans JP、これで十分。",[72,564,214],{"class":78},[72,566,163],{"class":78},[72,568,570],{"class":74,"line":569},30,[72,571,572],{"class":78},"        })\n",[72,574,576],{"class":74,"line":575},31,[72,577,578],{"class":78},"    })\n",[72,580,582],{"class":74,"line":581},32,[72,583,90],{"emptyLinePlaceholder":89},[72,585,587,590,592,594,596,598,600,603],{"class":74,"line":586},33,[72,588,589],{"class":190},"    data",[72,591,194],{"class":78},[72,593,197],{"class":190},[72,595,200],{"class":78},[72,597,419],{"class":190},[72,599,33],{"class":78},[72,601,602],{"class":177},"Generate",[72,604,427],{"class":78},[72,606,608,610,612,614,616],{"class":74,"line":607},34,[72,609,227],{"class":96},[72,611,197],{"class":190},[72,613,232],{"class":78},[72,615,235],{"class":78},[72,617,184],{"class":78},[72,619,621,623,625,627,629,631],{"class":74,"line":620},35,[72,622,243],{"class":190},[72,624,33],{"class":78},[72,626,248],{"class":177},[72,628,211],{"class":78},[72,630,253],{"class":190},[72,632,163],{"class":78},[72,634,636],{"class":74,"line":635},36,[72,637,261],{"class":78},[72,639,641,643,645,647,649,651,654,656,658,661,663,665,668,670,673,676,678,680,682],{"class":74,"line":640},37,[72,642,227],{"class":96},[72,644,197],{"class":190},[72,646,200],{"class":78},[72,648,203],{"class":190},[72,650,33],{"class":78},[72,652,653],{"class":177},"WriteFile",[72,655,211],{"class":78},[72,657,214],{"class":78},[72,659,660],{"class":217},"invoice.pdf",[72,662,214],{"class":78},[72,664,194],{"class":78},[72,666,667],{"class":190}," data",[72,669,194],{"class":78},[72,671,672],{"class":342}," 0o644",[72,674,675],{"class":78},");",[72,677,197],{"class":190},[72,679,232],{"class":78},[72,681,235],{"class":78},[72,683,184],{"class":78},[72,685,687,689,691,693,695,697],{"class":74,"line":686},38,[72,688,243],{"class":190},[72,690,33],{"class":78},[72,692,248],{"class":177},[72,694,211],{"class":78},[72,696,253],{"class":190},[72,698,163],{"class":78},[72,700,702],{"class":74,"line":701},39,[72,703,261],{"class":78},[72,705,707],{"class":74,"line":706},40,[72,708,709],{"class":78},"}\n",[18,711,712,713,718,719,722,723,726,727,33],{},"Descarga el zip de Noto Sans JP desde ",[22,714,717],{"href":715,"rel":716},"https://fonts.google.com/noto/specimen/Noto+Sans+JP",[26],"Google Fonts",", extrae ",[46,720,721],{},"static/NotoSansJP-Regular.ttf",", ponlo junto a ",[46,724,725],{},"main.go"," y ejecuta ",[46,728,729],{},"go run main.go",[13,731,733],{"id":732},"usa-el-ttf-static-no-la-variable-font","Usa el TTF static, no la variable font",[18,735,736,737,740],{},"Abre la página de Google Fonts, pulsa ",[30,738,739],{},"Get font → Download all"," y descomprime. Dentro hay dos cosas que parecen intercambiables y no lo son:",[742,743,744,755],"ul",{},[745,746,747,750,751,754],"li",{},[46,748,749],{},"NotoSansJP-VariableFont_wght.ttf"," en la raíz — la ",[30,752,753],{},"variable font",", ~7 MB, lleva todos los pesos del 100 al 900 en un único archivo",[745,756,757,759,760,763,764,767],{},[46,758,52],{}," — nueve TTFs separados, de ",[46,761,762],{},"NotoSansJP-Thin.ttf"," a ",[46,765,766],{},"NotoSansJP-Black.ttf",", unos 5 MB cada uno",[18,769,770,33],{},[30,771,772,773],{},"Usa los de ",[46,774,52],{},[18,776,777,778,781,782,785,786,789,790,793,794,797,798,801],{},"El parser TrueType de gpdf está deliberadamente acotado. Maneja contornos de glifos, glifos compuestos, ",[46,779,780],{},"cmap"," y ",[46,783,784],{},"hmtx"," — las tablas necesarias para renderizar texto con un peso fijo. Pero no procesa ",[46,787,788],{},"fvar",", ",[46,791,792],{},"gvar"," ni ",[46,795,796],{},"HVAR",", que son las tablas OpenType que hacen que una variable font sea de verdad variable. Si le pasas ",[46,799,800],{},"VariableFont_wght.ttf"," ocurre una de dos cosas: o el parser falla de forma limpia, o — peor — usa los glifos de la instancia por defecto e ignora en silencio cualquier eje de peso que creías estar ajustando.",[18,803,804],{},"La aritmética del tamaño también juega a favor del static. Una variable font arrastra los contornos de todos los pesos en el mismo archivo — ese es justo el diseño. Si solo usas Regular, estás pagando ocho pesos que no se renderizan nunca. Static Regular pesa 5 MB; la variable, 7 MB. El subsetting recortará ambos, pero el static es una entrada más limpia.",[13,806,808],{"id":807},"las-cuatro-líneas-que-importan","Las cuatro líneas que importan",[18,810,811],{},"Todo lo interesante vive en las opciones del constructor:",[63,813,815],{"className":65,"code":814,"language":67,"meta":68,"style":68},"doc := gpdf.NewDocument(\n    gpdf.WithFont(\"NotoSansJP\", font),\n    gpdf.WithDefaultFont(\"NotoSansJP\", 11),\n)\n",[46,816,817,832,855,877],{"__ignoreMap":68},[72,818,819,822,824,826,828,830],{"class":74,"line":75},[72,820,821],{"class":190},"doc ",[72,823,200],{"class":78},[72,825,277],{"class":190},[72,827,33],{"class":78},[72,829,282],{"class":177},[72,831,285],{"class":78},[72,833,834,837,839,841,843,845,847,849,851,853],{"class":74,"line":86},[72,835,836],{"class":190},"    gpdf",[72,838,33],{"class":78},[72,840,356],{"class":177},[72,842,211],{"class":78},[72,844,214],{"class":78},[72,846,363],{"class":217},[72,848,214],{"class":78},[72,850,194],{"class":78},[72,852,370],{"class":190},[72,854,308],{"class":78},[72,856,857,859,861,863,865,867,869,871,873,875],{"class":74,"line":93},[72,858,836],{"class":190},[72,860,33],{"class":78},[72,862,382],{"class":177},[72,864,211],{"class":78},[72,866,214],{"class":78},[72,868,363],{"class":217},[72,870,214],{"class":78},[72,872,194],{"class":78},[72,874,395],{"class":342},[72,876,308],{"class":78},[72,878,879],{"class":74,"line":103},[72,880,163],{"class":78},[18,882,883,884,887,888,789,891,894,895,898,899,33],{},"El nombre de la familia (",[46,885,886],{},"\"NotoSansJP\"",") es arbitrario. gpdf lo usa como clave de búsqueda — no como ruta del sistema de archivos ni como campo leído de los metadatos de la fuente. Llámalo ",[46,889,890],{},"\"body\"",[46,892,893],{},"\"jp\""," o ",[46,896,897],{},"\"Noto\""," si en tu código suena más natural. Solo mantén la coherencia con el argumento que pases más adelante a ",[46,900,901],{},"template.FontFamily(...)",[18,903,904,906,907,910,911,914],{},[46,905,382],{}," es la opción que te ahorra escribir ",[46,908,909],{},"template.FontFamily(\"NotoSansJP\")"," en cada ",[46,912,913],{},"c.Text",". Si la omites, gpdf cae en Helvetica — que no cubre ni un solo codepoint CJK — y obtienes cuadraditos vacíos (tofu, □□□) en todo el texto sin familia explícita. Media hora buscando por qué \"solo los títulos salen bien\".",[13,916,918],{"id":917},"qué-pesos-necesitas-realmente","¿Qué pesos necesitas realmente?",[18,920,921],{},"La mayoría de facturas, recibos e informes necesitan dos: Regular y Bold. Registra los dos:",[63,923,925],{"className":65,"code":924,"language":67,"meta":68,"style":68},"reg,  _ := os.ReadFile(\"NotoSansJP-Regular.ttf\")\nbold, _ := os.ReadFile(\"NotoSansJP-Bold.ttf\")\n\ndoc := gpdf.NewDocument(\n    gpdf.WithFont(\"NotoSansJP\", reg),\n    gpdf.WithFont(\"NotoSansJP-Bold\", bold),\n    gpdf.WithDefaultFont(\"NotoSansJP\", 11),\n)\n",[46,926,927,955,984,988,1002,1025,1049,1071],{"__ignoreMap":68},[72,928,929,932,934,937,939,941,943,945,947,949,951,953],{"class":74,"line":75},[72,930,931],{"class":190},"reg",[72,933,194],{"class":78},[72,935,936],{"class":190},"  _ ",[72,938,200],{"class":78},[72,940,203],{"class":190},[72,942,33],{"class":78},[72,944,208],{"class":177},[72,946,211],{"class":78},[72,948,214],{"class":78},[72,950,48],{"class":217},[72,952,214],{"class":78},[72,954,163],{"class":78},[72,956,957,960,962,965,967,969,971,973,975,977,980,982],{"class":74,"line":86},[72,958,959],{"class":190},"bold",[72,961,194],{"class":78},[72,963,964],{"class":190}," _ ",[72,966,200],{"class":78},[72,968,203],{"class":190},[72,970,33],{"class":78},[72,972,208],{"class":177},[72,974,211],{"class":78},[72,976,214],{"class":78},[72,978,979],{"class":217},"NotoSansJP-Bold.ttf",[72,981,214],{"class":78},[72,983,163],{"class":78},[72,985,986],{"class":74,"line":93},[72,987,90],{"emptyLinePlaceholder":89},[72,989,990,992,994,996,998,1000],{"class":74,"line":103},[72,991,821],{"class":190},[72,993,200],{"class":78},[72,995,277],{"class":190},[72,997,33],{"class":78},[72,999,282],{"class":177},[72,1001,285],{"class":78},[72,1003,1004,1006,1008,1010,1012,1014,1016,1018,1020,1023],{"class":74,"line":115},[72,1005,836],{"class":190},[72,1007,33],{"class":78},[72,1009,356],{"class":177},[72,1011,211],{"class":78},[72,1013,214],{"class":78},[72,1015,363],{"class":217},[72,1017,214],{"class":78},[72,1019,194],{"class":78},[72,1021,1022],{"class":190}," reg",[72,1024,308],{"class":78},[72,1026,1027,1029,1031,1033,1035,1037,1040,1042,1044,1047],{"class":74,"line":125},[72,1028,836],{"class":190},[72,1030,33],{"class":78},[72,1032,356],{"class":177},[72,1034,211],{"class":78},[72,1036,214],{"class":78},[72,1038,1039],{"class":217},"NotoSansJP-Bold",[72,1041,214],{"class":78},[72,1043,194],{"class":78},[72,1045,1046],{"class":190}," bold",[72,1048,308],{"class":78},[72,1050,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069],{"class":74,"line":130},[72,1052,836],{"class":190},[72,1054,33],{"class":78},[72,1056,382],{"class":177},[72,1058,211],{"class":78},[72,1060,214],{"class":78},[72,1062,363],{"class":217},[72,1064,214],{"class":78},[72,1066,194],{"class":78},[72,1068,395],{"class":342},[72,1070,308],{"class":78},[72,1072,1073],{"class":74,"line":140},[72,1074,163],{"class":78},[18,1076,1077,1078,789,1081,1084,1085,781,1088,1091],{},"Al registrar con el sufijo ",[46,1079,1080],{},"-Bold",[46,1082,1083],{},"template.Bold()"," lo recoge automáticamente. Misma regla para ",[46,1086,1087],{},"-Italic",[46,1089,1090],{},"-BoldItalic",", aunque ten en cuenta que Noto Sans JP no trae cursiva — las fuentes CJK generalmente no publican variante oblicua porque el diseño de los glifos no tiene una inclinación natural. Si tu layout pide énfasis cursivo en una tirada japonesa, usa color, tamaño o peso en su lugar.",[18,1093,1094],{},"Folletos de marketing a veces piden Medium o SemiBold para citas destacadas. Perfectamente válido. Regístralos con cualquier sufijo y referencia por nombre de familia directamente:",[63,1096,1098],{"className":65,"code":1097,"language":67,"meta":68,"style":68},"gpdf.WithFont(\"NotoSansJP-Medium\", medium)\n// ...\nc.Text(\"見出し\", template.FontFamily(\"NotoSansJP-Medium\"))\n",[46,1099,1100,1124,1130],{"__ignoreMap":68},[72,1101,1102,1104,1106,1108,1110,1112,1115,1117,1119,1122],{"class":74,"line":75},[72,1103,27],{"class":190},[72,1105,33],{"class":78},[72,1107,356],{"class":177},[72,1109,211],{"class":78},[72,1111,214],{"class":78},[72,1113,1114],{"class":217},"NotoSansJP-Medium",[72,1116,214],{"class":78},[72,1118,194],{"class":78},[72,1120,1121],{"class":190}," medium",[72,1123,163],{"class":78},[72,1125,1126],{"class":74,"line":86},[72,1127,1129],{"class":1128},"sHwdD","// ...\n",[72,1131,1132,1134,1136,1138,1140,1142,1145,1147,1149,1151,1153,1156,1158,1160,1162,1164],{"class":74,"line":93},[72,1133,485],{"class":190},[72,1135,33],{"class":78},[72,1137,509],{"class":177},[72,1139,211],{"class":78},[72,1141,214],{"class":78},[72,1143,1144],{"class":217},"見出し",[72,1146,214],{"class":78},[72,1148,194],{"class":78},[72,1150,523],{"class":190},[72,1152,33],{"class":78},[72,1154,1155],{"class":177},"FontFamily",[72,1157,211],{"class":78},[72,1159,214],{"class":78},[72,1161,1114],{"class":217},[72,1163,214],{"class":78},[72,1165,1166],{"class":78},"))\n",[18,1168,1169,1170,1172,1173,1172,1175,1177],{},"El atajo de Bold/Italic por sufijo solo se conecta con los nombres literales ",[46,1171,1080],{}," / ",[46,1174,1087],{},[46,1176,1090],{},". Cualquier otra cosa se referencia por nombre de familia.",[13,1179,1181],{"id":1180},"el-tamaño-después-del-subsetting","El tamaño después del subsetting",[18,1183,1184],{},"Noto Sans JP Regular pesa ~5 MB en disco. Esa cifra empuja a algunos equipos a montar un CDN aparte para fuentes o a añadir postprocesado para quitar las fuentes del PDF. Con gpdf no hace falta ninguna de las dos cosas.",[18,1186,1187],{},"Esto es lo que acaba en el PDF:",[1189,1190,1191,1207],"table",{},[1192,1193,1194],"thead",{},[1195,1196,1197,1201,1204],"tr",{},[1198,1199,1200],"th",{},"Documento",[1198,1202,1203],{},"Glifos usados",[1198,1205,1206],{},"Datos de fuente en el PDF",[1208,1209,1210,1222,1233,1244],"tbody",{},[1195,1211,1212,1216,1219],{},[1213,1214,1215],"td",{},"Recibo de una línea (~15 caract.)",[1213,1217,1218],{},"~14",[1213,1220,1221],{},"~11 KB",[1195,1223,1224,1227,1230],{},[1213,1225,1226],{},"Factura habitual (~200 caract.)",[1213,1228,1229],{},"~80",[1213,1231,1232],{},"~28 KB",[1195,1234,1235,1238,1241],{},[1213,1236,1237],{},"Informe de 10 páginas (~8.000 caract.)",[1213,1239,1240],{},"~900",[1213,1242,1243],{},"~180 KB",[1195,1245,1246,1249,1252],{},[1213,1247,1248],{},"Volcado tipo diccionario (JIS Nivel 1 completo)",[1213,1250,1251],{},"~6.800",[1213,1253,1254],{},"~2,1 MB",[18,1256,1257],{},"(gpdf v1.0, subsetting estático activo. Los números varían unos KB según en qué parte de CFF y hmtx caigan los IDs de glifo.)",[18,1259,1260],{},"Para una factura final de 50 KB, más de la mitad son datos de fuente. Aun así es una fracción mínima frente a los 5 MB que incrustarías sin subsetting, y el visor abre el PDF al instante.",[13,1262,1264],{"id":1263},"noto-sans-jp-vs-noto-sans-cjk-jp-no-las-confundas","Noto Sans JP vs. Noto Sans CJK JP — no las confundas",[18,1266,1267],{},"Hay dos familias Noto que afirman manejar japonés y los nombres las hacen parecer intercambiables. No lo son.",[18,1269,1270,1273],{},[30,1271,1272],{},"Noto Sans JP"," es la que quieres. Se distribuye como TTF, apunta a un único idioma y cada peso es un archivo independiente. Es la descarga de Google Fonts.",[18,1275,1276,1279,1280,1283,1284,33],{},[30,1277,1278],{},"Noto Sans CJK JP"," es la superfamilia pan-CJK. Se distribuye como OpenType Collection (",[46,1281,1282],{},".ttc","), un solo archivo que contiene japonés, chino simplificado, chino tradicional y coreano unificados en un mismo paquete. Es lo que se entregaba en las primeras releases de Noto y lo que encontrarás en ",[46,1285,1286],{},"notofonts.github.io/noto-cjk",[18,1288,1289,1290,1292,1293,1295],{},"gpdf soporta TTF directamente. TTC es un formato contenedor — tendrías que elegir el índice de face correcto antes de entregar los bytes a ",[46,1291,356],{},", y el ",[46,1294,780],{}," de cada face está ajustado para una locale CJK específica, lo que significa que estás tomando decisiones implícitas sobre unificación Han. Es más claro tomarlas explícitamente eligiendo el TTF específico de JP.",[18,1297,1298,1299,1302,1303,894,1306,1309],{},"¿Empiezas hoy? Usa Noto Sans JP. ¿Ya tienes un ",[46,1300,1301],{},"NotoSansCJK-Regular.ttc"," en un proyecto heredado? Extrae el face JP con ",[46,1304,1305],{},"pyftsubset",[46,1307,1308],{},"fonttools"," y commitea el TTF resultante como artefacto canónico del repo.",[13,1311,1313],{"id":1312},"empaquetar-la-fuente-en-el-binario","Empaquetar la fuente en el binario",[18,1315,1316],{},"Los generadores de PDF suelen correr en contenedores, y la forma más limpia de distribuir la fuente es compilarla dentro:",[63,1318,1320],{"className":65,"code":1319,"language":67,"meta":68,"style":68},"package main\n\nimport (\n    _ \"embed\"\n\n    \"github.com/gpdf-dev/gpdf\"\n)\n\n//go:embed NotoSansJP-Regular.ttf\nvar notoJP []byte\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithFont(\"NotoSansJP\", notoJP),\n        gpdf.WithDefaultFont(\"NotoSansJP\", 11),\n    )\n    // ...\n}\n",[46,1321,1322,1328,1332,1338,1350,1354,1362,1366,1370,1375,1390,1394,1404,1418,1441,1463,1467,1472],{"__ignoreMap":68},[72,1323,1324,1326],{"class":74,"line":75},[72,1325,79],{"class":78},[72,1327,83],{"class":82},[72,1329,1330],{"class":74,"line":86},[72,1331,90],{"emptyLinePlaceholder":89},[72,1333,1334,1336],{"class":74,"line":93},[72,1335,97],{"class":96},[72,1337,100],{"class":78},[72,1339,1340,1343,1345,1348],{"class":74,"line":103},[72,1341,1342],{"class":190},"    _ ",[72,1344,214],{"class":78},[72,1346,1347],{"class":82},"embed",[72,1349,112],{"class":78},[72,1351,1352],{"class":74,"line":115},[72,1353,90],{"emptyLinePlaceholder":89},[72,1355,1356,1358,1360],{"class":74,"line":125},[72,1357,106],{"class":78},[72,1359,135],{"class":82},[72,1361,112],{"class":78},[72,1363,1364],{"class":74,"line":130},[72,1365,163],{"class":78},[72,1367,1368],{"class":74,"line":140},[72,1369,90],{"emptyLinePlaceholder":89},[72,1371,1372],{"class":74,"line":150},[72,1373,1374],{"class":1128},"//go:embed NotoSansJP-Regular.ttf\n",[72,1376,1377,1380,1383,1386],{"class":74,"line":160},[72,1378,1379],{"class":78},"var",[72,1381,1382],{"class":190}," notoJP ",[72,1384,1385],{"class":78},"[]",[72,1387,1389],{"class":1388},"spNyl","byte\n",[72,1391,1392],{"class":74,"line":166},[72,1393,90],{"emptyLinePlaceholder":89},[72,1395,1396,1398,1400,1402],{"class":74,"line":171},[72,1397,174],{"class":78},[72,1399,178],{"class":177},[72,1401,181],{"class":78},[72,1403,184],{"class":78},[72,1405,1406,1408,1410,1412,1414,1416],{"class":74,"line":187},[72,1407,272],{"class":190},[72,1409,200],{"class":78},[72,1411,277],{"class":190},[72,1413,33],{"class":78},[72,1415,282],{"class":177},[72,1417,285],{"class":78},[72,1419,1420,1422,1424,1426,1428,1430,1432,1434,1436,1439],{"class":74,"line":224},[72,1421,291],{"class":190},[72,1423,33],{"class":78},[72,1425,356],{"class":177},[72,1427,211],{"class":78},[72,1429,214],{"class":78},[72,1431,363],{"class":217},[72,1433,214],{"class":78},[72,1435,194],{"class":78},[72,1437,1438],{"class":190}," notoJP",[72,1440,308],{"class":78},[72,1442,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461],{"class":74,"line":240},[72,1444,291],{"class":190},[72,1446,33],{"class":78},[72,1448,382],{"class":177},[72,1450,211],{"class":78},[72,1452,214],{"class":78},[72,1454,363],{"class":217},[72,1456,214],{"class":78},[72,1458,194],{"class":78},[72,1460,395],{"class":342},[72,1462,308],{"class":78},[72,1464,1465],{"class":74,"line":258},[72,1466,403],{"class":78},[72,1468,1469],{"class":74,"line":264},[72,1470,1471],{"class":1128},"    // ...\n",[72,1473,1474],{"class":74,"line":269},[72,1475,709],{"class":78},[18,1477,1478,1479,1482],{},"El binario crece de ~8 MB a ~13 MB. A cambio, la imagen Docker tiene un único artefacto en lugar de dos, ",[46,1480,1481],{},"COPY --from=builder /app /app"," basta, y nadie puede publicar un contenedor roto por olvidar el archivo de fuente. Para un batch que genera miles de PDFs al día, este es el valor por defecto correcto.",[13,1484,1486],{"id":1485},"lectura-relacionada","Lectura relacionada",[742,1488,1489,1496,1506,1513],{},[745,1490,1491,1495],{},[22,1492,1494],{"href":1493},"/es/blog/embed-japanese-font","¿Cómo incrusto una fuente japonesa en gpdf?"," — la receta general, aplica a cualquier TTF CJK",[745,1497,1498,1502,1503],{},[22,1499,1501],{"href":1500},"/es/blog/gofpdf-migration","gofpdf está archivado. Guía de migración a gpdf"," — mapeo desde ",[46,1504,1505],{},"AddUTF8Font",[745,1507,1508,1512],{},[22,1509,1511],{"href":1510},"/es/blog/go-pdf-library-showdown-2026","Go PDF Library Showdown 2026"," — comparativa concreta sobre CJK",[745,1514,1515,1520,1521],{},[22,1516,1519],{"href":1517,"rel":1518},"https://gpdf.dev/docs/guide/fonts",[26],"Guía de fuentes"," — referencia completa de ",[46,1522,356],{},[13,1524,1526],{"id":1525},"prueba-gpdf","Prueba gpdf",[18,1528,1529],{},"gpdf es una librería Go para generar PDFs. Licencia MIT, cero dependencias externas, soporte nativo para CJK.",[63,1531,1535],{"className":1532,"code":1533,"language":1534,"meta":68,"style":68},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[46,1536,1537],{"__ignoreMap":68},[72,1538,1539,1541,1544],{"class":74,"line":75},[72,1540,67],{"class":82},[72,1542,1543],{"class":217}," get",[72,1545,1546],{"class":217}," github.com/gpdf-dev/gpdf\n",[18,1548,1549,1553,1554],{},[22,1550,1552],{"href":24,"rel":1551},[26],"⭐ Star en GitHub"," · ",[22,1555,1558],{"href":1556,"rel":1557},"https://gpdf.dev/docs/quickstart",[26],"Leer la documentación",[1560,1561,1562],"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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":68,"searchDepth":86,"depth":86,"links":1564},[1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575],{"id":15,"depth":86,"text":16},{"id":36,"depth":86,"text":37},{"id":60,"depth":86,"text":61},{"id":732,"depth":86,"text":733},{"id":807,"depth":86,"text":808},{"id":917,"depth":86,"text":918},{"id":1180,"depth":86,"text":1181},{"id":1263,"depth":86,"text":1264},{"id":1312,"depth":86,"text":1313},{"id":1485,"depth":86,"text":1486},{"id":1525,"depth":86,"text":1526},"2026-04-15","Registra el TTF static de NotoSansJP-Regular con gpdf.WithFont. No uses la variable font. gpdf subsetea los 17.000 glifos a menos de 40 KB por PDF.",false,"md",{"name":1581,"totalTime":1582,"tools":1583,"steps":1586},"Usar Noto Sans JP como fuente por defecto en un documento gpdf","PT10M",[1584,1585],"Go 1.22+","NotoSansJP-Regular.ttf (TTF static de Google Fonts)",[1587,1590,1593,1596],{"name":1588,"text":1589},"Descargar el TTF static desde Google Fonts","Descarga Noto Sans JP desde fonts.google.com, descomprime el zip y elige static/NotoSansJP-Regular.ttf. No uses el NotoSansJP-VariableFont_wght.ttf que está en la raíz.",{"name":1591,"text":1592},"Cargar los bytes al iniciar","Lee NotoSansJP-Regular.ttf con os.ReadFile, o compílalo dentro del binario con //go:embed si prefieres un único artefacto.",{"name":1594,"text":1595},"Registrar la fuente al construir el documento","Pasa gpdf.WithFont(\"NotoSansJP\", fontBytes) y gpdf.WithDefaultFont(\"NotoSansJP\", 11) a gpdf.NewDocument. Sin AddUTF8Font, sin rutas de archivo.",{"name":1597,"text":1598},"Escribir texto japonés y generar el PDF","Llama a c.Text(\"請求書\") dentro de una columna. doc.Generate() devuelve []byte y gpdf subsetea solo los glifos que realmente usaste en el PDF final.",null,{},"/es/blog/noto-sans-jp-with-gpdf",{"title":5,"description":1577},"es/blog/004.noto-sans-jp-with-gpdf",[1605,1606,1607],"recipe","cjk","tutorial","1TavhiciCmahaGud32HNaS--2kxYa5u5soHz6naWCuQ",1776529274337]