[{"data":1,"prerenderedAt":1328},["ShallowReactive",2],{"blog-ko-source-han-sans-jp-with-gpdf":3},{"id":4,"title":5,"author":6,"body":9,"date":1292,"description":1293,"draft":1294,"extension":1295,"howTo":1296,"image":1318,"meta":1319,"navigation":85,"path":1320,"seo":1321,"stem":1322,"tags":1323,"updated":1318,"__hash__":1327},"blogKo/ko/blog/010.source-han-sans-jp-with-gpdf.md","gpdf에서 Source Han Sans JP(본고딕 JP)를 사용하려면?",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1280},"minimark",[12,17,33,37,54,58,707,721,725,736,739,824,835,839,874,881,905,915,919,922,930,933,1088,1101,1104,1108,1111,1151,1165,1169,1172,1186,1189,1204,1207,1211,1240,1244,1247,1264,1276],[13,14,16],"h2",{"id":15},"질문을-다시-말하면","질문을 다시 말하면",[18,19,20,27,28,32],"p",{},[21,22,26],"a",{"href":23,"rel":24},"https://github.com/gpdf-dev/gpdf",[25],"nofollow","gpdf"," 문서에서 ",[29,30,31],"strong",{},"Source Han Sans JP(본고딕 JP)"," — 2014년 Adobe와 Google 협력으로 공개된 pan-CJK 산세리프의 Adobe 측 브랜드 — 를 쓰고 싶다. 이유는 다양하다. 팀이 재현성을 위해 폰트를 GitHub 릴리스 태그에 핀 해두고 싶거나, 오래 전 Source Han으로 표준화된 디자인 시스템을 인수받았거나, 그냥 Adobe 릴리스 주기가 더 편하거나. 뭐든 상관없다. 다운로드하기 전에 세 가지만 정리해 두면 된다 — 어떤 파일을 받을지, Noto Sans JP와의 실제 관계, 그리고 gpdf가 읽을 수 있는 포맷이 무엇인지.",[13,34,36],{"id":35},"빠른-답","빠른 답",[18,38,39,44,45,49,50,53],{},[21,40,43],{"href":41,"rel":42},"https://github.com/adobe-fonts/source-han-sans/releases",[25],"adobe-fonts/source-han-sans"," 릴리스 페이지에서 ",[46,47,48],"code",{},"SourceHanSansJP-Regular.ttf","를 받아(TTF 번들, OTF 아님), ",[46,51,52],{},"gpdf.WithFont(\"SourceHanSansJP\", bytes)","로 등록하고 기본 폰트로 설정한다. Source Han Sans JP와 Noto Sans JP는 글리프 윤곽이 같으므로, Adobe 배포 생태계에 특별히 얽매일 이유가 없다면 Noto Sans JP가 더 간단한 다운로드다.",[13,55,57],{"id":56},"완성된-예제","완성된 예제",[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(\"SourceHanSansJP-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(\"SourceHanSansJP\", font),\n        gpdf.WithDefaultFont(\"SourceHanSansJP\", 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(24), template.Bold())\n            c.Text(\"Source Han Sans JP — Adobe 배포 무료 CJK 폰트.\")\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"report.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[46,66,67,80,87,97,109,119,124,134,144,154,160,165,181,219,235,253,259,264,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,215,217],{"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,48],{"class":214},"sfazB",[68,216,211],{"class":74},[68,218,159],{"class":74},[68,220,222,225,227,230,233],{"class":70,"line":221},14,[68,223,224],{"class":92},"    if",[68,226,193],{"class":186},[68,228,229],{"class":74},"!=",[68,231,232],{"class":74}," nil",[68,234,180],{"class":74},[68,236,238,241,243,246,248,251],{"class":70,"line":237},15,[68,239,240],{"class":186},"        log",[68,242,202],{"class":74},[68,244,245],{"class":173},"Fatal",[68,247,208],{"class":74},[68,249,250],{"class":186},"err",[68,252,159],{"class":74},[68,254,256],{"class":70,"line":255},16,[68,257,258],{"class":74},"    }\n",[68,260,262],{"class":70,"line":261},17,[68,263,86],{"emptyLinePlaceholder":85},[68,265,267,270,272,275,277,280],{"class":70,"line":266},18,[68,268,269],{"class":186},"    doc ",[68,271,196],{"class":74},[68,273,274],{"class":186}," gpdf",[68,276,202],{"class":74},[68,278,279],{"class":173},"NewDocument",[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,26],{"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},"SourceHanSansJP",[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}," 11",[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},"Source Han Sans JP — Adobe 배포 무료 CJK 폰트.",[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,224],{"class":92},[68,608,193],{"class":186},[68,610,229],{"class":74},[68,612,232],{"class":74},[68,614,180],{"class":74},[68,616,618,620,622,624,626,628],{"class":70,"line":617},35,[68,619,240],{"class":186},[68,621,202],{"class":74},[68,623,245],{"class":173},[68,625,208],{"class":74},[68,627,250],{"class":186},[68,629,159],{"class":74},[68,631,633],{"class":70,"line":632},36,[68,634,258],{"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,224],{"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},"report.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,229],{"class":74},[68,678,232],{"class":74},[68,680,180],{"class":74},[68,682,684,686,688,690,692,694],{"class":70,"line":683},38,[68,685,240],{"class":186},[68,687,202],{"class":74},[68,689,245],{"class":173},[68,691,208],{"class":74},[68,693,250],{"class":186},[68,695,159],{"class":74},[68,697,699],{"class":70,"line":698},39,[68,700,258],{"class":74},[68,702,704],{"class":70,"line":703},40,[68,705,706],{"class":74},"}\n",[18,708,709,710,713,714,717,718,720],{},"TTF를 ",[46,711,712],{},"main.go"," 옆에 두고 ",[46,715,716],{},"go run main.go",". 일본어가 들어간 한 페이지짜리 PDF가 ",[46,719,657],{},"로 떨어진다.",[13,722,724],{"id":723},"source-han-sans-jp-noto-sans-cjk-jp","Source Han Sans JP = Noto Sans CJK JP",[18,726,727,728,731,732,735],{},"검색 시간 몇 시간을 아껴줄 사실 하나: ",[29,729,730],{},"Source Han Sans와 Noto Sans CJK는 같은 폰트다",". Adobe가 글리프 설계, 메트릭 테이블, 문자셋 커버리지를 담당했다. Google은 Noto 이름으로 병행 유통했다. 두 배포판 모두 2014-07-15에 출시되었다. 윤곽 데이터, ",[46,733,734],{},"hmtx",", JIS X 0213 / Adobe-Japan1-6 커버리지는 비트 단위로 동일하다. Adobe가 버전을 올리면 Noto에도 몇 주 안에 반영된다.",[18,737,738],{},"차이는 전부 브랜딩과 패키징 층에 있다:",[740,741,742,757],"table",{},[743,744,745],"thead",{},[746,747,748,751,754],"tr",{},[749,750],"th",{},[749,752,753],{},"Source Han Sans JP",[749,755,756],{},"Noto Sans JP",[758,759,760,772,791,802,813],"tbody",{},[746,761,762,766,769],{},[763,764,765],"td",{},"발행자",[763,767,768],{},"Adobe",[763,770,771],{},"Google",[746,773,774,777,783],{},[763,775,776],{},"정식 출처",[763,778,779],{},[21,780,43],{"href":781,"rel":782},"https://github.com/adobe-fonts/source-han-sans",[25],[763,784,785,790],{},[21,786,789],{"href":787,"rel":788},"https://notofonts.github.io",[25],"notofonts.github.io"," + Google Fonts",[746,792,793,796,799],{},[763,794,795],{},"기본 포맷",[763,797,798],{},"OTF (CFF 윤곽)",[763,800,801],{},"TTF (static) + variable",[746,803,804,807,810],{},[763,805,806],{},"릴리스 모델",[763,808,809],{},"GitHub 릴리스 태그로 수동 버전 관리",[763,811,812],{},"Google Fonts CDN + git 저장소",[746,814,815,818,821],{},[763,816,817],{},"언어 묶음",[763,819,820],{},"언어별 TTF + pan-CJK OTC",[763,822,823],{},"JP 전용",[18,825,826,827,830,831,834],{},"팀이 Adobe의 GitHub 태그에 폰트를 고정하려 하거나, 이미 ",[46,828,829],{},"github.com/adobe-fonts","를 사내 미러링하거나, 파이프라인 다른 공정에서 pan-CJK OTC가 필요하다면 Source Han Sans JP가 맞다. 그렇지 않다면 TTF를 바로 받을 수 있는 ",[21,832,756],{"href":833},"/ko/blog/noto-sans-jp-with-gpdf"," 쪽이 손이 덜 간다.",[13,836,838],{"id":837},"왜-otf가-아니라-ttf인가","왜 OTF가 아니라 TTF인가",[18,840,841,842,845,846,849,850,853,854,853,857,853,860,862,863,866,867,870,871,873],{},"Adobe의 기본 자산은 ",[46,843,844],{},".otf",", 정확히는 CFF 기반 OpenType이다. gpdf의 폰트 파서는 ",[46,847,848],{},"pdf/font/truetype.go"," 한 파일에 모여 있고 ",[46,851,852],{},"glyf",", ",[46,855,856],{},"loca",[46,858,859],{},"cmap",[46,861,734],{},"와 복합 글리프를 읽는다. ",[46,864,865],{},"CFF "," / ",[46,868,869],{},"CFF2"," 윤곽은 읽지 않는다. CFF 기반 ",[46,872,844],{},"를 넘기면 렌더 시점이 아니라 문서 생성 시점에 파싱 에러가 난다.",[18,875,876,877,880],{},"Adobe 릴리스 페이지는 OTF와 TTF를 모두 제공하므로 ",[29,878,879],{},"TTF 번들"," 쪽을 받는다. 특정 포인트 릴리스에 TTF가 없는 경우엔 깔끔한 대안이 둘 있다:",[882,883,884,891],"ol",{},[885,886,887,890],"li",{},[29,888,889],{},"Noto Sans JP로 바꾼다."," Google Fonts가 정적 TTF를 직접 제공한다. 글리프 데이터는 동일하다. 변환이 필요 없다.",[885,892,893,896,897,900,901,904],{},[29,894,895],{},"한 번만 변환하고 결과를 커밋한다."," ",[46,898,899],{},"fonttools","의 ",[46,902,903],{},"otf2ttf","가 1분이면 TTF를 만든다. 결과를 저장소나 사내 아티팩트 서버에 올리고, 변환 단계는 빌드 파이프라인에서 빼둔다.",[18,906,907,908,910,911,914],{},"빌드 시점에 변환하는 건 피한다. 폰트 변환 도구는 버전 간 동작이 미세하게 다르고, ",[46,909,734],{}," 테이블이 조금만 바뀌어도 ",[46,912,913],{},"pip install -U"," 하나로 행 넘김 위치가 바뀐다.",[13,916,918],{"id":917},"일곱-굵기","일곱 굵기",[18,920,921],{},"Source Han Sans JP는 ExtraLight부터 Heavy까지 한 굵기당 한 파일로 배포한다:",[59,923,928],{"className":924,"code":926,"language":927},[925],"language-text","SourceHanSansJP-ExtraLight.ttf\nSourceHanSansJP-Light.ttf\nSourceHanSansJP-Normal.ttf\nSourceHanSansJP-Regular.ttf\nSourceHanSansJP-Medium.ttf\nSourceHanSansJP-Bold.ttf\nSourceHanSansJP-Heavy.ttf\n","text",[46,929,926],{"__ignoreMap":64},[18,931,932],{},"대부분의 업무 문서는 Regular와 Bold 둘이면 충분하다:",[59,934,936],{"className":61,"code":935,"language":63,"meta":64,"style":64},"reg,  _ := os.ReadFile(\"SourceHanSansJP-Regular.ttf\")\nbold, _ := os.ReadFile(\"SourceHanSansJP-Bold.ttf\")\n\ndoc := gpdf.NewDocument(\n    gpdf.WithFont(\"SourceHanSansJP\", reg),\n    gpdf.WithFont(\"SourceHanSansJP-Bold\", bold),\n    gpdf.WithDefaultFont(\"SourceHanSansJP\", 11),\n)\n",[46,937,938,966,995,999,1014,1038,1062,1084],{"__ignoreMap":64},[68,939,940,943,945,948,950,952,954,956,958,960,962,964],{"class":70,"line":71},[68,941,942],{"class":186},"reg",[68,944,190],{"class":74},[68,946,947],{"class":186},"  _ ",[68,949,196],{"class":74},[68,951,199],{"class":186},[68,953,202],{"class":74},[68,955,205],{"class":173},[68,957,208],{"class":74},[68,959,211],{"class":74},[68,961,48],{"class":214},[68,963,211],{"class":74},[68,965,159],{"class":74},[68,967,968,971,973,976,978,980,982,984,986,988,991,993],{"class":70,"line":82},[68,969,970],{"class":186},"bold",[68,972,190],{"class":74},[68,974,975],{"class":186}," _ ",[68,977,196],{"class":74},[68,979,199],{"class":186},[68,981,202],{"class":74},[68,983,205],{"class":173},[68,985,208],{"class":74},[68,987,211],{"class":74},[68,989,990],{"class":214},"SourceHanSansJP-Bold.ttf",[68,992,211],{"class":74},[68,994,159],{"class":74},[68,996,997],{"class":70,"line":89},[68,998,86],{"emptyLinePlaceholder":85},[68,1000,1001,1004,1006,1008,1010,1012],{"class":70,"line":99},[68,1002,1003],{"class":186},"doc ",[68,1005,196],{"class":74},[68,1007,274],{"class":186},[68,1009,202],{"class":74},[68,1011,279],{"class":173},[68,1013,282],{"class":74},[68,1015,1016,1019,1021,1023,1025,1027,1029,1031,1033,1036],{"class":70,"line":111},[68,1017,1018],{"class":186},"    gpdf",[68,1020,202],{"class":74},[68,1022,353],{"class":173},[68,1024,208],{"class":74},[68,1026,211],{"class":74},[68,1028,360],{"class":214},[68,1030,211],{"class":74},[68,1032,190],{"class":74},[68,1034,1035],{"class":186}," reg",[68,1037,305],{"class":74},[68,1039,1040,1042,1044,1046,1048,1050,1053,1055,1057,1060],{"class":70,"line":121},[68,1041,1018],{"class":186},[68,1043,202],{"class":74},[68,1045,353],{"class":173},[68,1047,208],{"class":74},[68,1049,211],{"class":74},[68,1051,1052],{"class":214},"SourceHanSansJP-Bold",[68,1054,211],{"class":74},[68,1056,190],{"class":74},[68,1058,1059],{"class":186}," bold",[68,1061,305],{"class":74},[68,1063,1064,1066,1068,1070,1072,1074,1076,1078,1080,1082],{"class":70,"line":126},[68,1065,1018],{"class":186},[68,1067,202],{"class":74},[68,1069,379],{"class":173},[68,1071,208],{"class":74},[68,1073,211],{"class":74},[68,1075,360],{"class":214},[68,1077,211],{"class":74},[68,1079,190],{"class":74},[68,1081,392],{"class":339},[68,1083,305],{"class":74},[68,1085,1086],{"class":70,"line":136},[68,1087,159],{"class":74},[18,1089,1090,1093,1094,1097,1098,1100],{},[46,1091,1092],{},"-Bold"," 접미사가 ",[46,1095,1096],{},"template.Bold()","와 Bold TTF를 연결하는 규약이다. 등록하지 않은 채 ",[46,1099,1096],{},"를 쓰면 Regular 글리프 위에 0.4 pt 획을 덧댄 합성 볼드로 대체된다 — 제목 정도는 버티지만, 큰 글자 크기에서는 진짜 Bold 윤곽보다 가늘어 보인다.",[18,1102,1103],{},"CJK 폰트는 관례적으로 이탤릭을 만들지 않고, Source Han Sans JP도 마찬가지다. 일본어에 이탤릭 강조가 필요한 레이아웃이라면 굵기나 색으로 대신한다. 한자에 기울임 변환을 걸면 강조가 아니라 깨진 글자로 보인다.",[13,1105,1107],{"id":1106},"pan-cjk-jp-전용-super-otc","Pan-CJK, JP 전용, Super OTC",[18,1109,1110],{},"Adobe는 Source Han Sans를 여러 입도로 배포한다. Go PDF 생성에서는 혼용할 수 없다:",[1112,1113,1114,1127,1137],"ul",{},[885,1115,1116,1119,1120,1123,1124,1126],{},[29,1117,1118],{},"SourceHanSans.ttc","(Super OTC) — 모든 CJK 언어가 20 MB+ TrueType Collection 하나에 들어 있다. gpdf는 ",[46,1121,1122],{},".ttc"," 내부의 face 인덱스를 직접 풀지 않기 때문에, 먼저 ",[46,1125,899],{},"로 JP face를 추출해 TTF로 등록해야 한다. 보통은 쓰지 않는다.",[885,1128,1129,1132,1133,1136],{},[29,1130,1131],{},"지역 통합 OTF","(예: ",[46,1134,1135],{},"SourceHanSans-Regular.otf",") — 전체 CJK 통합, CFF 윤곽. gpdf가 못 읽는다.",[885,1138,1139,208,1142,1144,1145,1147,1148,202],{},[29,1140,1141],{},"언어별 TTF",[46,1143,48],{},") — JP 전용, ",[46,1146,852],{}," 윤곽. ",[29,1149,1150],{},"이걸 쓴다",[18,1152,1153,1154,1156,1157,1160,1161,1164],{},"한 페이지에서 일본어와 한국어/중국어가 섞이는 문서라면 pan-CJK OTF에 의존하지 말고 언어별 패밀리를 나란히 등록한다: ",[46,1155,360],{}," + ",[46,1158,1159],{},"SourceHanSansKR",". 스크립트가 바뀌는 지점에서 ",[46,1162,1163],{},"template.FontFamily","로 명시한다. pan-CJK OTF는 한자를 Han unification으로 하나의 형으로 묶어버리기 때문에, 일본어 본문에 있어야 할 일본어 자형의 한자가 중국어 자형으로 나오는 사고가 생긴다.",[13,1166,1168],{"id":1167},"noto-대신-source-han을-고를-때","Noto 대신 Source Han을 고를 때",[18,1170,1171],{},"윤곽은 같고 유통 채널이 다르다. Source Han Sans JP가 자연스러운 경우:",[1112,1173,1174,1177,1183],{},[885,1175,1176],{},"운영 팀이 폰트를 Adobe의 GitHub 릴리스 태그에 고정하는 운용을 선호함(재현성, 감사성)",[885,1178,1179,1180,1182],{},"사내에서 이미 ",[46,1181,829],{},"를 미러링하고 있음(엄격한 아티팩트 정책의 기업에서 흔함)",[885,1184,1185],{},"파이프라인 다른 단계에서도 pan-CJK OTC 번들이 필요함(DTP 핸드오프, Adobe 이름으로 통일된 브랜드 시스템 등)",[18,1187,1188],{},"Noto Sans JP가 더 잘 맞는 경우:",[1112,1190,1191,1198,1201],{},[885,1192,1193,1194,1197],{},"TTF를 최단 경로로 받고 싶다(",[46,1195,1196],{},"fonts.google.com/noto/specimen/Noto+Sans+JP"," → zip → 끝)",[885,1199,1200],{},"OTF → TTF 변환을 빌드에 끌어들이고 싶지 않다",[885,1202,1203],{},"프로젝트가 이미 기존 워크플로로 다른 Google Fonts를 받고 있다",[18,1205,1206],{},"렌더링 결과는 같다. 판단은 운영상의 것 — 파일이 어디에 있고 어떻게 버전을 관리하고 팀이 어느 쪽에 익숙한가 — 이지, 미감의 문제가 아니다.",[13,1208,1210],{"id":1209},"관련-레시피","관련 레시피",[1112,1212,1213,1219,1226,1233],{},[885,1214,1215,1218],{},[21,1216,1217],{"href":833},"gpdf에서 Noto Sans JP를 사용하려면?"," — 같은 글리프, 박스에서 꺼내면 TTF",[885,1220,1221,1225],{},[21,1222,1224],{"href":1223},"/ko/blog/embed-japanese-font","gpdf에서 일본어 폰트를 임베드하려면?"," — CJK 임베딩의 일반 레시피",[885,1227,1228,1232],{},[21,1229,1231],{"href":1230},"/ko/blog/ipaex-gothic-gpdf","gpdf에서 IPAex 고딕을 사용하려면?"," — 일본 공공 제출용 IPA 라이선스 대안",[885,1234,1235,1239],{},[21,1236,1238],{"href":1237},"/ko/blog/tofu-boxes-japanese","gpdf로 만든 PDF에서 일본어가 네모로 나올 때"," — 글리프 누락 트러블슈팅",[13,1241,1243],{"id":1242},"gpdf를-써보자","gpdf를 써보자",[18,1245,1246],{},"gpdf는 Go용 PDF 생성 라이브러리다. MIT 라이선스, 외부 의존성 0, 네이티브 CJK 지원.",[59,1248,1252],{"className":1249,"code":1250,"language":1251,"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",[46,1253,1254],{"__ignoreMap":64},[68,1255,1256,1258,1261],{"class":70,"line":71},[68,1257,63],{"class":78},[68,1259,1260],{"class":214}," get",[68,1262,1263],{"class":214}," github.com/gpdf-dev/gpdf\n",[18,1265,1266,1270,1271],{},[21,1267,1269],{"href":23,"rel":1268},[25],"⭐ GitHub에서 Star"," · ",[21,1272,1275],{"href":1273,"rel":1274},"https://gpdf.dev/ko/docs/quickstart",[25],"문서 읽기",[1277,1278,1279],"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":1281},[1282,1283,1284,1285,1286,1287,1288,1289,1290,1291],{"id":15,"depth":82,"text":16},{"id":35,"depth":82,"text":36},{"id":56,"depth":82,"text":57},{"id":723,"depth":82,"text":724},{"id":837,"depth":82,"text":838},{"id":917,"depth":82,"text":918},{"id":1106,"depth":82,"text":1107},{"id":1167,"depth":82,"text":1168},{"id":1209,"depth":82,"text":1210},{"id":1242,"depth":82,"text":1243},"2026-04-19","Adobe의 GitHub 릴리스에서 TTF 버전을 받아 gpdf.WithFont로 등록한다. Noto Sans JP와 같은 글리프, 7가지 굵기, SIL OFL.",false,"md",{"name":1297,"totalTime":1298,"tools":1299,"steps":1302},"gpdf 문서에서 Source Han Sans JP(본고딕 JP)를 기본 폰트로 설정하기","PT15M",[1300,1301],"Go 1.22+","SourceHanSansJP-Regular.ttf (adobe-fonts/source-han-sans)",[1303,1306,1309,1312,1315],{"name":1304,"text":1305},"Adobe의 GitHub 릴리스에서 TTF 버전을 받는다","github.com/adobe-fonts/source-han-sans/releases를 열고 최신 릴리스에서 TTF 번들(OTF나 SuperOTC 말고)을 다운로드한 뒤 SourceHanSansJP-Regular.ttf를 꺼낸다. gpdf는 TrueType만 파싱하고 CFF 기반 OpenType은 읽지 않는다.",{"name":1307,"text":1308},"시작 시 바이트를 로드한다","os.ReadFile(\"SourceHanSansJP-Regular.ttf\") 또는 //go:embed를 쓴다. CI 재현성을 위해 빌드 시점에 다운로드하지 말고 Adobe 릴리스 태그를 저장소에 고정한다.",{"name":1310,"text":1311},"문서 생성 시점에 등록한다","gpdf.WithFont(\"SourceHanSansJP\", fontBytes)와 gpdf.WithDefaultFont(\"SourceHanSansJP\", 11)을 gpdf.NewDocument에 전달한다. AddUTF8Font도 파일 경로도 필요 없다.",{"name":1313,"text":1314},"필요하면 다른 굵기도 등록한다","Source Han Sans JP는 ExtraLight부터 Heavy까지 7개 굵기를 각각 TTF로 배포한다. Bold TTF를 SourceHanSansJP-Bold라는 키로 등록하면 template.Bold()가 합성 볼드가 아니라 진짜 Bold 윤곽을 쓴다.",{"name":1316,"text":1317},"배포물에 OFL.txt를 함께 둔다","SIL OFL 1.1은 폰트 바이너리가 배포되는 곳에 라이선스 전문을 동반할 것을 요구한다. //go:embed로 TTF를 넣는다면 OFL.txt도 LICENSES/에 같이 넣고 NOTICE에서 참조한다.",null,{},"/ko/blog/source-han-sans-jp-with-gpdf",{"title":5,"description":1293},"ko/blog/010.source-han-sans-jp-with-gpdf",[1324,1325,1326],"recipe","cjk","tutorial","4SJzNvBt1VrHylWf5j9E1AfSvZHvgKIYIQFtVJXImC8",1776537637847]