[{"data":1,"prerenderedAt":1552},["ShallowReactive",2],{"blog-en-embed-japanese-font":3},{"id":4,"title":5,"author":6,"body":9,"date":1519,"description":1520,"draft":1521,"extension":1522,"howTo":1523,"image":1542,"meta":1543,"navigation":85,"path":1544,"seo":1545,"stem":1546,"tags":1547,"updated":1542,"__hash__":1551},"blog/blog/003.embed-japanese-font.md","How do I embed a Japanese font in gpdf?",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1508},"minimark",[12,17,34,38,54,58,707,727,731,734,740,750,760,764,775,928,946,950,957,1390,1397,1401,1407,1415,1431,1435,1468,1472,1475,1492,1504],[13,14,16],"h2",{"id":15},"the-question-in-other-words","The question, in other words",[18,19,20,21,28,29,33],"p",{},"How do I render Japanese (or any CJK) text in a PDF generated with ",[22,23,27],"a",{"href":24,"rel":25},"https://github.com/gpdf-dev/gpdf",[26],"nofollow","gpdf"," — without the ",[30,31,32],"code",{},"AddUTF8Font"," dance, without CGO, without a five-megabyte font embedded on every document?",[13,35,37],{"id":36},"tldr","TL;DR",[18,39,40,41,44,45,48,49,53],{},"Load the TTF bytes. Pass ",[30,42,43],{},"gpdf.WithFont(\"NotoSansJP\", fontBytes)"," to ",[30,46,47],{},"NewDocument",". Optionally set it as the default. Write Japanese. ",[50,51,52],"strong",{},"Three lines of setup, and gpdf subsets the glyphs automatically"," so the final PDF carries only the characters you actually used.",[13,55,57],{"id":56},"the-complete-example","The complete example",[59,60,65],"pre",{"className":61,"code":62,"language":63,"meta":64,"style":64},"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(\"こんにちは、世界。\", template.FontSize(24), template.Bold())\n            c.Text(\"日本語 PDF、これだけ。\")\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","",[30,66,67,80,87,97,109,119,124,134,144,154,160,165,181,220,236,254,260,265,283,306,344,370,395,401,406,425,459,496,544,564,570,576,581,602,615,630,635,681,696,701],{"__ignoreMap":64},[68,69,72,76],"span",{"class":70,"line":71},"line",1,[68,73,75],{"class":74},"sMK4o","package",[68,77,79],{"class":78},"sBMFI"," main\n",[68,81,83],{"class":70,"line":82},2,[68,84,86],{"emptyLinePlaceholder":85},true,"\n",[68,88,90,94],{"class":70,"line":89},3,[68,91,93],{"class":92},"s7zQu","import",[68,95,96],{"class":74}," (\n",[68,98,100,103,106],{"class":70,"line":99},4,[68,101,102],{"class":74},"    \"",[68,104,105],{"class":78},"log",[68,107,108],{"class":74},"\"\n",[68,110,112,114,117],{"class":70,"line":111},5,[68,113,102],{"class":74},[68,115,116],{"class":78},"os",[68,118,108],{"class":74},[68,120,122],{"class":70,"line":121},6,[68,123,86],{"emptyLinePlaceholder":85},[68,125,127,129,132],{"class":70,"line":126},7,[68,128,102],{"class":74},[68,130,131],{"class":78},"github.com/gpdf-dev/gpdf",[68,133,108],{"class":74},[68,135,137,139,142],{"class":70,"line":136},8,[68,138,102],{"class":74},[68,140,141],{"class":78},"github.com/gpdf-dev/gpdf/document",[68,143,108],{"class":74},[68,145,147,149,152],{"class":70,"line":146},9,[68,148,102],{"class":74},[68,150,151],{"class":78},"github.com/gpdf-dev/gpdf/template",[68,153,108],{"class":74},[68,155,157],{"class":70,"line":156},10,[68,158,159],{"class":74},")\n",[68,161,163],{"class":70,"line":162},11,[68,164,86],{"emptyLinePlaceholder":85},[68,166,168,171,175,178],{"class":70,"line":167},12,[68,169,170],{"class":74},"func",[68,172,174],{"class":173},"s2Zo4"," main",[68,176,177],{"class":74},"()",[68,179,180],{"class":74}," {\n",[68,182,184,188,191,194,197,200,203,206,209,212,216,218],{"class":70,"line":183},13,[68,185,187],{"class":186},"sTEyZ","    font",[68,189,190],{"class":74},",",[68,192,193],{"class":186}," err ",[68,195,196],{"class":74},":=",[68,198,199],{"class":186}," os",[68,201,202],{"class":74},".",[68,204,205],{"class":173},"ReadFile",[68,207,208],{"class":74},"(",[68,210,211],{"class":74},"\"",[68,213,215],{"class":214},"sfazB","NotoSansJP-Regular.ttf",[68,217,211],{"class":74},[68,219,159],{"class":74},[68,221,223,226,228,231,234],{"class":70,"line":222},14,[68,224,225],{"class":92},"    if",[68,227,193],{"class":186},[68,229,230],{"class":74},"!=",[68,232,233],{"class":74}," nil",[68,235,180],{"class":74},[68,237,239,242,244,247,249,252],{"class":70,"line":238},15,[68,240,241],{"class":186},"        log",[68,243,202],{"class":74},[68,245,246],{"class":173},"Fatal",[68,248,208],{"class":74},[68,250,251],{"class":186},"err",[68,253,159],{"class":74},[68,255,257],{"class":70,"line":256},16,[68,258,259],{"class":74},"    }\n",[68,261,263],{"class":70,"line":262},17,[68,264,86],{"emptyLinePlaceholder":85},[68,266,268,271,273,276,278,280],{"class":70,"line":267},18,[68,269,270],{"class":186},"    doc ",[68,272,196],{"class":74},[68,274,275],{"class":186}," gpdf",[68,277,202],{"class":74},[68,279,47],{"class":173},[68,281,282],{"class":74},"(\n",[68,284,286,289,291,294,296,298,300,303],{"class":70,"line":285},19,[68,287,288],{"class":186},"        gpdf",[68,290,202],{"class":74},[68,292,293],{"class":173},"WithPageSize",[68,295,208],{"class":74},[68,297,27],{"class":186},[68,299,202],{"class":74},[68,301,302],{"class":186},"A4",[68,304,305],{"class":74},"),\n",[68,307,309,311,313,316,318,321,323,326,328,330,332,335,337,341],{"class":70,"line":308},20,[68,310,288],{"class":186},[68,312,202],{"class":74},[68,314,315],{"class":173},"WithMargins",[68,317,208],{"class":74},[68,319,320],{"class":186},"document",[68,322,202],{"class":74},[68,324,325],{"class":173},"UniformEdges",[68,327,208],{"class":74},[68,329,320],{"class":186},[68,331,202],{"class":74},[68,333,334],{"class":173},"Mm",[68,336,208],{"class":74},[68,338,340],{"class":339},"sbssI","20",[68,342,343],{"class":74},"))),\n",[68,345,347,349,351,354,356,358,361,363,365,368],{"class":70,"line":346},21,[68,348,288],{"class":186},[68,350,202],{"class":74},[68,352,353],{"class":173},"WithFont",[68,355,208],{"class":74},[68,357,211],{"class":74},[68,359,360],{"class":214},"NotoSansJP",[68,362,211],{"class":74},[68,364,190],{"class":74},[68,366,367],{"class":186}," font",[68,369,305],{"class":74},[68,371,373,375,377,380,382,384,386,388,390,393],{"class":70,"line":372},22,[68,374,288],{"class":186},[68,376,202],{"class":74},[68,378,379],{"class":173},"WithDefaultFont",[68,381,208],{"class":74},[68,383,211],{"class":74},[68,385,360],{"class":214},[68,387,211],{"class":74},[68,389,190],{"class":74},[68,391,392],{"class":339}," 12",[68,394,305],{"class":74},[68,396,398],{"class":70,"line":397},23,[68,399,400],{"class":74},"    )\n",[68,402,404],{"class":70,"line":403},24,[68,405,86],{"emptyLinePlaceholder":85},[68,407,409,412,414,417,419,422],{"class":70,"line":408},25,[68,410,411],{"class":186},"    page ",[68,413,196],{"class":74},[68,415,416],{"class":186}," doc",[68,418,202],{"class":74},[68,420,421],{"class":173},"AddPage",[68,423,424],{"class":74},"()\n",[68,426,428,431,433,436,439,443,446,449,451,454,457],{"class":70,"line":427},26,[68,429,430],{"class":186},"    page",[68,432,202],{"class":74},[68,434,435],{"class":173},"AutoRow",[68,437,438],{"class":74},"(func(",[68,440,442],{"class":441},"sHdIc","r",[68,444,445],{"class":74}," *",[68,447,448],{"class":78},"template",[68,450,202],{"class":74},[68,452,453],{"class":78},"RowBuilder",[68,455,456],{"class":74},")",[68,458,180],{"class":74},[68,460,462,465,467,470,472,475,477,480,483,485,487,489,492,494],{"class":70,"line":461},27,[68,463,464],{"class":186},"        r",[68,466,202],{"class":74},[68,468,469],{"class":173},"Col",[68,471,208],{"class":74},[68,473,474],{"class":339},"12",[68,476,190],{"class":74},[68,478,479],{"class":74}," func(",[68,481,482],{"class":441},"c",[68,484,445],{"class":74},[68,486,448],{"class":78},[68,488,202],{"class":74},[68,490,491],{"class":78},"ColBuilder",[68,493,456],{"class":74},[68,495,180],{"class":74},[68,497,499,502,504,507,509,511,514,516,518,521,523,526,528,531,534,536,538,541],{"class":70,"line":498},28,[68,500,501],{"class":186},"            c",[68,503,202],{"class":74},[68,505,506],{"class":173},"Text",[68,508,208],{"class":74},[68,510,211],{"class":74},[68,512,513],{"class":214},"こんにちは、世界。",[68,515,211],{"class":74},[68,517,190],{"class":74},[68,519,520],{"class":186}," template",[68,522,202],{"class":74},[68,524,525],{"class":173},"FontSize",[68,527,208],{"class":74},[68,529,530],{"class":339},"24",[68,532,533],{"class":74},"),",[68,535,520],{"class":186},[68,537,202],{"class":74},[68,539,540],{"class":173},"Bold",[68,542,543],{"class":74},"())\n",[68,545,547,549,551,553,555,557,560,562],{"class":70,"line":546},29,[68,548,501],{"class":186},[68,550,202],{"class":74},[68,552,506],{"class":173},[68,554,208],{"class":74},[68,556,211],{"class":74},[68,558,559],{"class":214},"日本語 PDF、これだけ。",[68,561,211],{"class":74},[68,563,159],{"class":74},[68,565,567],{"class":70,"line":566},30,[68,568,569],{"class":74},"        })\n",[68,571,573],{"class":70,"line":572},31,[68,574,575],{"class":74},"    })\n",[68,577,579],{"class":70,"line":578},32,[68,580,86],{"emptyLinePlaceholder":85},[68,582,584,587,589,591,593,595,597,600],{"class":70,"line":583},33,[68,585,586],{"class":186},"    data",[68,588,190],{"class":74},[68,590,193],{"class":186},[68,592,196],{"class":74},[68,594,416],{"class":186},[68,596,202],{"class":74},[68,598,599],{"class":173},"Generate",[68,601,424],{"class":74},[68,603,605,607,609,611,613],{"class":70,"line":604},34,[68,606,225],{"class":92},[68,608,193],{"class":186},[68,610,230],{"class":74},[68,612,233],{"class":74},[68,614,180],{"class":74},[68,616,618,620,622,624,626,628],{"class":70,"line":617},35,[68,619,241],{"class":186},[68,621,202],{"class":74},[68,623,246],{"class":173},[68,625,208],{"class":74},[68,627,251],{"class":186},[68,629,159],{"class":74},[68,631,633],{"class":70,"line":632},36,[68,634,259],{"class":74},[68,636,638,640,642,644,646,648,651,653,655,658,660,662,665,667,670,673,675,677,679],{"class":70,"line":637},37,[68,639,225],{"class":92},[68,641,193],{"class":186},[68,643,196],{"class":74},[68,645,199],{"class":186},[68,647,202],{"class":74},[68,649,650],{"class":173},"WriteFile",[68,652,208],{"class":74},[68,654,211],{"class":74},[68,656,657],{"class":214},"hello.pdf",[68,659,211],{"class":74},[68,661,190],{"class":74},[68,663,664],{"class":186}," data",[68,666,190],{"class":74},[68,668,669],{"class":339}," 0o644",[68,671,672],{"class":74},");",[68,674,193],{"class":186},[68,676,230],{"class":74},[68,678,233],{"class":74},[68,680,180],{"class":74},[68,682,684,686,688,690,692,694],{"class":70,"line":683},38,[68,685,241],{"class":186},[68,687,202],{"class":74},[68,689,246],{"class":173},[68,691,208],{"class":74},[68,693,251],{"class":186},[68,695,159],{"class":74},[68,697,699],{"class":70,"line":698},39,[68,700,259],{"class":74},[68,702,704],{"class":70,"line":703},40,[68,705,706],{"class":74},"}\n",[18,708,709,710,712,713,718,719,722,723,726],{},"Download ",[30,711,215],{}," from ",[22,714,717],{"href":715,"rel":716},"https://fonts.google.com/noto/specimen/Noto+Sans+JP",[26],"Google Fonts"," and drop it next to ",[30,720,721],{},"main.go",". Run ",[30,724,725],{},"go run main.go",". You get a one-page PDF with Japanese text.",[13,728,730],{"id":729},"what-those-three-lines-actually-do","What those three lines actually do",[18,732,733],{},"Two things happen under the hood, and neither one needs any help from you.",[18,735,736,739],{},[50,737,738],{},"Subset embedding."," Noto Sans JP ships with around 17,000 glyphs — the regular weight is about 5 MB on disk. If every PDF embedded the whole font, a receipt with four lines of Japanese would still cost you five megabytes of font data. gpdf walks the text you rendered, figures out which glyph IDs you used, and writes only that subset into the PDF. A short invoice usually ends up carrying 20–40 KB of font data instead of 5 MB.",[18,741,742,743,745,746,749],{},"gofpdf could do subset embedding too, but it needed ",[30,744,32],{}," called with a filesystem path and a UTF-8 flag, and font switching mid-document was awkward. gpdf registers the font once at document construction and then every ",[30,747,748],{},"c.Text"," call just references it by family name. There's no per-call bookkeeping.",[18,751,752,755,756,759],{},[50,753,754],{},"No CGO."," This matters more than it sounds. A lot of font handling in other ecosystems routes through FreeType or HarfBuzz, which means a C dependency, which means your build caches invalidate differently, your Docker images gain layers, and cross-compilation from macOS to linux/arm64 becomes a thing you have to think about. gpdf parses TrueType tables in pure Go. ",[30,757,758],{},"go build"," stays static. Ship a distroless container with the Go binary and the TTF file; that's all.",[13,761,763],{"id":762},"bold-and-italic-variants","Bold and italic variants",[18,765,766,767,770,771,774],{},"Japanese Noto ships a separate file per weight. To use ",[50,768,769],{},"bold",", register the bold TTF under the ",[30,772,773],{},"-Bold"," suffix:",[59,776,778],{"className":61,"code":777,"language":63,"meta":64,"style":64},"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\", 12),\n)\n",[30,779,780,808,835,839,854,878,902,924],{"__ignoreMap":64},[68,781,782,785,787,790,792,794,796,798,800,802,804,806],{"class":70,"line":71},[68,783,784],{"class":186},"reg",[68,786,190],{"class":74},[68,788,789],{"class":186}," _ ",[68,791,196],{"class":74},[68,793,199],{"class":186},[68,795,202],{"class":74},[68,797,205],{"class":173},[68,799,208],{"class":74},[68,801,211],{"class":74},[68,803,215],{"class":214},[68,805,211],{"class":74},[68,807,159],{"class":74},[68,809,810,812,814,816,818,820,822,824,826,828,831,833],{"class":70,"line":82},[68,811,769],{"class":186},[68,813,190],{"class":74},[68,815,789],{"class":186},[68,817,196],{"class":74},[68,819,199],{"class":186},[68,821,202],{"class":74},[68,823,205],{"class":173},[68,825,208],{"class":74},[68,827,211],{"class":74},[68,829,830],{"class":214},"NotoSansJP-Bold.ttf",[68,832,211],{"class":74},[68,834,159],{"class":74},[68,836,837],{"class":70,"line":89},[68,838,86],{"emptyLinePlaceholder":85},[68,840,841,844,846,848,850,852],{"class":70,"line":99},[68,842,843],{"class":186},"doc ",[68,845,196],{"class":74},[68,847,275],{"class":186},[68,849,202],{"class":74},[68,851,47],{"class":173},[68,853,282],{"class":74},[68,855,856,859,861,863,865,867,869,871,873,876],{"class":70,"line":111},[68,857,858],{"class":186},"    gpdf",[68,860,202],{"class":74},[68,862,353],{"class":173},[68,864,208],{"class":74},[68,866,211],{"class":74},[68,868,360],{"class":214},[68,870,211],{"class":74},[68,872,190],{"class":74},[68,874,875],{"class":186}," reg",[68,877,305],{"class":74},[68,879,880,882,884,886,888,890,893,895,897,900],{"class":70,"line":121},[68,881,858],{"class":186},[68,883,202],{"class":74},[68,885,353],{"class":173},[68,887,208],{"class":74},[68,889,211],{"class":74},[68,891,892],{"class":214},"NotoSansJP-Bold",[68,894,211],{"class":74},[68,896,190],{"class":74},[68,898,899],{"class":186}," bold",[68,901,305],{"class":74},[68,903,904,906,908,910,912,914,916,918,920,922],{"class":70,"line":126},[68,905,858],{"class":186},[68,907,202],{"class":74},[68,909,379],{"class":173},[68,911,208],{"class":74},[68,913,211],{"class":74},[68,915,360],{"class":214},[68,917,211],{"class":74},[68,919,190],{"class":74},[68,921,392],{"class":339},[68,923,305],{"class":74},[68,925,926],{"class":70,"line":136},[68,927,159],{"class":74},[18,929,930,931,934,935,937,938,941,942,945],{},"Now ",[30,932,933],{},"template.Bold()"," picks up the ",[30,936,773],{}," variant. Same convention for ",[30,939,940],{},"-Italic"," and ",[30,943,944],{},"-BoldItalic",". If you don't register the variant, bold falls back to a synthesized weight — readable on screen but not typographically honest. For production invoices, register the real weight.",[13,947,949],{"id":948},"multiple-cjk-languages-in-the-same-document","Multiple CJK languages in the same document",[18,951,952,953,956],{},"Registering more than one family is fine — gpdf tracks them independently. Use ",[30,954,955],{},"template.FontFamily(...)"," to switch per text:",[59,958,960],{"className":61,"code":959,"language":63,"meta":64,"style":64},"jp, _ := os.ReadFile(\"NotoSansJP-Regular.ttf\")\nsc, _ := os.ReadFile(\"NotoSansSC-Regular.ttf\")\nkr, _ := os.ReadFile(\"NotoSansKR-Regular.ttf\")\n\ndoc := gpdf.NewDocument(\n    gpdf.WithFont(\"NotoSansJP\", jp),\n    gpdf.WithFont(\"NotoSansSC\", sc),\n    gpdf.WithFont(\"NotoSansKR\", kr),\n    gpdf.WithDefaultFont(\"NotoSansJP\", 12),\n)\n\npage.AutoRow(func(r *template.RowBuilder) {\n    r.Col(4, func(c *template.ColBuilder) {\n        c.Text(\"日本語\")\n    })\n    r.Col(4, func(c *template.ColBuilder) {\n        c.Text(\"中文\", template.FontFamily(\"NotoSansSC\"))\n    })\n    r.Col(4, func(c *template.ColBuilder) {\n        c.Text(\"한국어\", template.FontFamily(\"NotoSansKR\"))\n    })\n})\n",[30,961,962,989,1017,1045,1049,1063,1086,1110,1134,1156,1160,1164,1189,1221,1241,1245,1275,1312,1316,1346,1381,1385],{"__ignoreMap":64},[68,963,964,967,969,971,973,975,977,979,981,983,985,987],{"class":70,"line":71},[68,965,966],{"class":186},"jp",[68,968,190],{"class":74},[68,970,789],{"class":186},[68,972,196],{"class":74},[68,974,199],{"class":186},[68,976,202],{"class":74},[68,978,205],{"class":173},[68,980,208],{"class":74},[68,982,211],{"class":74},[68,984,215],{"class":214},[68,986,211],{"class":74},[68,988,159],{"class":74},[68,990,991,994,996,998,1000,1002,1004,1006,1008,1010,1013,1015],{"class":70,"line":82},[68,992,993],{"class":186},"sc",[68,995,190],{"class":74},[68,997,789],{"class":186},[68,999,196],{"class":74},[68,1001,199],{"class":186},[68,1003,202],{"class":74},[68,1005,205],{"class":173},[68,1007,208],{"class":74},[68,1009,211],{"class":74},[68,1011,1012],{"class":214},"NotoSansSC-Regular.ttf",[68,1014,211],{"class":74},[68,1016,159],{"class":74},[68,1018,1019,1022,1024,1026,1028,1030,1032,1034,1036,1038,1041,1043],{"class":70,"line":89},[68,1020,1021],{"class":186},"kr",[68,1023,190],{"class":74},[68,1025,789],{"class":186},[68,1027,196],{"class":74},[68,1029,199],{"class":186},[68,1031,202],{"class":74},[68,1033,205],{"class":173},[68,1035,208],{"class":74},[68,1037,211],{"class":74},[68,1039,1040],{"class":214},"NotoSansKR-Regular.ttf",[68,1042,211],{"class":74},[68,1044,159],{"class":74},[68,1046,1047],{"class":70,"line":99},[68,1048,86],{"emptyLinePlaceholder":85},[68,1050,1051,1053,1055,1057,1059,1061],{"class":70,"line":111},[68,1052,843],{"class":186},[68,1054,196],{"class":74},[68,1056,275],{"class":186},[68,1058,202],{"class":74},[68,1060,47],{"class":173},[68,1062,282],{"class":74},[68,1064,1065,1067,1069,1071,1073,1075,1077,1079,1081,1084],{"class":70,"line":121},[68,1066,858],{"class":186},[68,1068,202],{"class":74},[68,1070,353],{"class":173},[68,1072,208],{"class":74},[68,1074,211],{"class":74},[68,1076,360],{"class":214},[68,1078,211],{"class":74},[68,1080,190],{"class":74},[68,1082,1083],{"class":186}," jp",[68,1085,305],{"class":74},[68,1087,1088,1090,1092,1094,1096,1098,1101,1103,1105,1108],{"class":70,"line":126},[68,1089,858],{"class":186},[68,1091,202],{"class":74},[68,1093,353],{"class":173},[68,1095,208],{"class":74},[68,1097,211],{"class":74},[68,1099,1100],{"class":214},"NotoSansSC",[68,1102,211],{"class":74},[68,1104,190],{"class":74},[68,1106,1107],{"class":186}," sc",[68,1109,305],{"class":74},[68,1111,1112,1114,1116,1118,1120,1122,1125,1127,1129,1132],{"class":70,"line":136},[68,1113,858],{"class":186},[68,1115,202],{"class":74},[68,1117,353],{"class":173},[68,1119,208],{"class":74},[68,1121,211],{"class":74},[68,1123,1124],{"class":214},"NotoSansKR",[68,1126,211],{"class":74},[68,1128,190],{"class":74},[68,1130,1131],{"class":186}," kr",[68,1133,305],{"class":74},[68,1135,1136,1138,1140,1142,1144,1146,1148,1150,1152,1154],{"class":70,"line":146},[68,1137,858],{"class":186},[68,1139,202],{"class":74},[68,1141,379],{"class":173},[68,1143,208],{"class":74},[68,1145,211],{"class":74},[68,1147,360],{"class":214},[68,1149,211],{"class":74},[68,1151,190],{"class":74},[68,1153,392],{"class":339},[68,1155,305],{"class":74},[68,1157,1158],{"class":70,"line":156},[68,1159,159],{"class":74},[68,1161,1162],{"class":70,"line":162},[68,1163,86],{"emptyLinePlaceholder":85},[68,1165,1166,1169,1171,1173,1175,1177,1179,1181,1183,1185,1187],{"class":70,"line":167},[68,1167,1168],{"class":186},"page",[68,1170,202],{"class":74},[68,1172,435],{"class":173},[68,1174,438],{"class":74},[68,1176,442],{"class":441},[68,1178,445],{"class":74},[68,1180,448],{"class":78},[68,1182,202],{"class":74},[68,1184,453],{"class":78},[68,1186,456],{"class":74},[68,1188,180],{"class":74},[68,1190,1191,1194,1196,1198,1200,1203,1205,1207,1209,1211,1213,1215,1217,1219],{"class":70,"line":183},[68,1192,1193],{"class":186},"    r",[68,1195,202],{"class":74},[68,1197,469],{"class":173},[68,1199,208],{"class":74},[68,1201,1202],{"class":339},"4",[68,1204,190],{"class":74},[68,1206,479],{"class":74},[68,1208,482],{"class":441},[68,1210,445],{"class":74},[68,1212,448],{"class":78},[68,1214,202],{"class":74},[68,1216,491],{"class":78},[68,1218,456],{"class":74},[68,1220,180],{"class":74},[68,1222,1223,1226,1228,1230,1232,1234,1237,1239],{"class":70,"line":222},[68,1224,1225],{"class":186},"        c",[68,1227,202],{"class":74},[68,1229,506],{"class":173},[68,1231,208],{"class":74},[68,1233,211],{"class":74},[68,1235,1236],{"class":214},"日本語",[68,1238,211],{"class":74},[68,1240,159],{"class":74},[68,1242,1243],{"class":70,"line":238},[68,1244,575],{"class":74},[68,1246,1247,1249,1251,1253,1255,1257,1259,1261,1263,1265,1267,1269,1271,1273],{"class":70,"line":256},[68,1248,1193],{"class":186},[68,1250,202],{"class":74},[68,1252,469],{"class":173},[68,1254,208],{"class":74},[68,1256,1202],{"class":339},[68,1258,190],{"class":74},[68,1260,479],{"class":74},[68,1262,482],{"class":441},[68,1264,445],{"class":74},[68,1266,448],{"class":78},[68,1268,202],{"class":74},[68,1270,491],{"class":78},[68,1272,456],{"class":74},[68,1274,180],{"class":74},[68,1276,1277,1279,1281,1283,1285,1287,1290,1292,1294,1296,1298,1301,1303,1305,1307,1309],{"class":70,"line":262},[68,1278,1225],{"class":186},[68,1280,202],{"class":74},[68,1282,506],{"class":173},[68,1284,208],{"class":74},[68,1286,211],{"class":74},[68,1288,1289],{"class":214},"中文",[68,1291,211],{"class":74},[68,1293,190],{"class":74},[68,1295,520],{"class":186},[68,1297,202],{"class":74},[68,1299,1300],{"class":173},"FontFamily",[68,1302,208],{"class":74},[68,1304,211],{"class":74},[68,1306,1100],{"class":214},[68,1308,211],{"class":74},[68,1310,1311],{"class":74},"))\n",[68,1313,1314],{"class":70,"line":267},[68,1315,575],{"class":74},[68,1317,1318,1320,1322,1324,1326,1328,1330,1332,1334,1336,1338,1340,1342,1344],{"class":70,"line":285},[68,1319,1193],{"class":186},[68,1321,202],{"class":74},[68,1323,469],{"class":173},[68,1325,208],{"class":74},[68,1327,1202],{"class":339},[68,1329,190],{"class":74},[68,1331,479],{"class":74},[68,1333,482],{"class":441},[68,1335,445],{"class":74},[68,1337,448],{"class":78},[68,1339,202],{"class":74},[68,1341,491],{"class":78},[68,1343,456],{"class":74},[68,1345,180],{"class":74},[68,1347,1348,1350,1352,1354,1356,1358,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379],{"class":70,"line":308},[68,1349,1225],{"class":186},[68,1351,202],{"class":74},[68,1353,506],{"class":173},[68,1355,208],{"class":74},[68,1357,211],{"class":74},[68,1359,1360],{"class":214},"한국어",[68,1362,211],{"class":74},[68,1364,190],{"class":74},[68,1366,520],{"class":186},[68,1368,202],{"class":74},[68,1370,1300],{"class":173},[68,1372,208],{"class":74},[68,1374,211],{"class":74},[68,1376,1124],{"class":214},[68,1378,211],{"class":74},[68,1380,1311],{"class":74},[68,1382,1383],{"class":70,"line":346},[68,1384,575],{"class":74},[68,1386,1387],{"class":70,"line":372},[68,1388,1389],{"class":74},"})\n",[18,1391,1392,1393,1396],{},"Han unification means the Unicode codepoints between Japanese and Simplified Chinese overlap, but the glyphs are drawn differently. Picking the right font isn't just aesthetic — ",[50,1394,1395],{},"the same codepoint renders as a different character shape depending on the font",". If you're producing invoices for both markets, get both files registered.",[13,1398,1400],{"id":1399},"the-tofu-trap","The tofu trap",[18,1402,1403,1404,1406],{},"If you write Japanese but forget ",[30,1405,353],{},", gpdf falls back to the Base-14 PDF fonts — none of which cover the CJK range. The characters render as blank rectangles, what Unicode people call \"tofu boxes\":",[59,1408,1413],{"className":1409,"code":1411,"language":1412},[1410],"language-text","□□□□□、□□。\n","text",[30,1414,1411],{"__ignoreMap":64},[18,1416,1417,1418,1420,1421,1423,1424,1427,1428,1430],{},"If you see that output, you forgot to register a CJK font, or you wrote the text in a font family that doesn't include those glyphs. The fix is always the same: add ",[30,1419,353],{}," and either use ",[30,1422,379],{}," or pass ",[30,1425,1426],{},"template.FontFamily"," on the ",[30,1429,748],{}," call.",[13,1432,1434],{"id":1433},"related-reading","Related reading",[1436,1437,1438,1450,1457],"ul",{},[1439,1440,1441,1445,1446,1449],"li",{},[22,1442,1444],{"href":1443},"/blog/gofpdf-migration","gofpdf is archived. Here's how to migrate to gpdf."," — if you're coming from ",[30,1447,1448],{},"pdf.AddUTF8Font"," and want the full migration map",[1439,1451,1452,1456],{},[22,1453,1455],{"href":1454},"/blog/go-pdf-library-showdown-2026","Go PDF Library Showdown 2026"," — how gpdf compares to gofpdf, gopdf, Maroto, and unipdf on CJK",[1439,1458,1459,1464,1465,1467],{},[22,1460,1463],{"href":1461,"rel":1462},"https://gpdf.dev/docs/guide/fonts",[26],"Fonts guide"," — the full ",[30,1466,353],{}," reference including variant naming rules",[13,1469,1471],{"id":1470},"try-gpdf","Try gpdf",[18,1473,1474],{},"gpdf is a Go library for generating PDFs. MIT licensed, zero external dependencies, native CJK support.",[59,1476,1480],{"className":1477,"code":1478,"language":1479,"meta":64,"style":64},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[30,1481,1482],{"__ignoreMap":64},[68,1483,1484,1486,1489],{"class":70,"line":71},[68,1485,63],{"class":78},[68,1487,1488],{"class":214}," get",[68,1490,1491],{"class":214}," github.com/gpdf-dev/gpdf\n",[18,1493,1494,1498,1499],{},[22,1495,1497],{"href":24,"rel":1496},[26],"⭐ Star on GitHub"," · ",[22,1500,1503],{"href":1501,"rel":1502},"https://gpdf.dev/docs/quickstart",[26],"Read the docs",[1505,1506,1507],"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);}",{"title":64,"searchDepth":82,"depth":82,"links":1509},[1510,1511,1512,1513,1514,1515,1516,1517,1518],{"id":15,"depth":82,"text":16},{"id":36,"depth":82,"text":37},{"id":56,"depth":82,"text":57},{"id":729,"depth":82,"text":730},{"id":762,"depth":82,"text":763},{"id":948,"depth":82,"text":949},{"id":1399,"depth":82,"text":1400},{"id":1433,"depth":82,"text":1434},{"id":1470,"depth":82,"text":1471},"2026-04-15","Register a Japanese TrueType font with gpdf.WithFont at document construction. Three lines, subset embedding happens automatically, no CGO.",false,"md",{"name":1524,"totalTime":1525,"tools":1526,"steps":1529},"Embed a Japanese TrueType font in a gpdf document","PT10M",[1527,1528],"Go 1.22+","NotoSansJP-Regular.ttf (or any CJK-capable TTF)",[1530,1533,1536,1539],{"name":1531,"text":1532},"Load the TTF bytes","Read the NotoSansJP-Regular.ttf file with os.ReadFile into a []byte at program start. Embedding with //go:embed works too if you want the font compiled into the binary.",{"name":1534,"text":1535},"Register the font at document construction","Pass gpdf.WithFont(\"NotoSansJP\", fontBytes) to gpdf.NewDocument. The family name is arbitrary — use whatever you'll reference later. gpdf subsets the glyph table at render time.",{"name":1537,"text":1538},"Set it as the default font","Add gpdf.WithDefaultFont(\"NotoSansJP\", 12) so every c.Text call uses the Japanese font without an explicit FontFamily option.",{"name":1540,"text":1541},"Write Japanese text and generate the PDF","Call c.Text(\"こんにちは、世界。\") inside a column. Then doc.Generate() returns []byte, which you write to disk with os.WriteFile.",null,{},"/blog/embed-japanese-font",{"title":5,"description":1520},"blog/003.embed-japanese-font",[1548,1549,1550],"recipe","cjk","tutorial","fD5yk3yBNUIQuBc8PSm_Qu8w7ukyfcoTTpmaanNiEkA",1776526785037]