[{"data":1,"prerenderedAt":1541},["ShallowReactive",2],{"blog-ja-mix-two-fonts-in-paragraph":3},{"id":4,"title":5,"author":6,"body":10,"date":1506,"description":1507,"draft":1508,"extension":1509,"howTo":1510,"image":1531,"meta":1532,"navigation":224,"path":1533,"seo":1534,"stem":1535,"tags":1536,"updated":1531,"__hash__":1540},"blogJa/ja/blog/023.mix-two-fonts-in-paragraph.md","gpdf で 1 つの段落に 2 つのフォントを混ぜる方法",{"name":7,"url":8,"avatar":9},"野田大貴","https://nadai.dev/ja/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1496},"minimark",[13,17,21,24,39,183,186,203,207,1006,1021,1025,1043,1051,1066,1140,1150,1154,1157,1171,1371,1392,1396,1419,1422,1454,1458,1461,1478,1492],[14,15,16],"h2",{"id":16},"質問を言い換えると",[18,19,20],"p",{},"1 つの段落 — 1 文、ラベル、表のセル — があって、その一部を別のフォントにしたい。Helvetica の行の中にコードスニペットを等幅で。ASCII の注文 ID の隣に日本語の名前を Noto Sans JP で。テキストを別々のブロックに分けずに、段落の途中でフォントを切り替えるにはどうするのか。",[14,22,23],{"id":23},"即答",[18,25,26,30,31,34,35,38],{},[27,28,29],"code",{},"c.Text"," はここでは間違った道具だ。文字列全体に 1 つの ",[27,32,33],{},"document.Style"," — フォントファミリーも 1 つ込み — を当てる。欲しいのは ",[27,36,37],{},"c.RichText"," で、各 span が独自のスタイルを持つ:",[40,41,46],"pre",{"className":42,"code":43,"language":44,"meta":45,"style":45},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","c.RichText(func(rt *template.RichTextBuilder) {\n    rt.Span(\"Run \")\n    rt.Span(\"gofmt ./...\", template.FontFamily(\"Courier\"))\n    rt.Span(\" before you commit.\")\n})\n","go","",[27,47,48,90,116,157,177],{"__ignoreMap":45},[49,50,53,57,61,65,68,72,75,79,81,84,87],"span",{"class":51,"line":52},"line",1,[49,54,56],{"class":55},"sTEyZ","c",[49,58,60],{"class":59},"sMK4o",".",[49,62,64],{"class":63},"s2Zo4","RichText",[49,66,67],{"class":59},"(func(",[49,69,71],{"class":70},"sHdIc","rt",[49,73,74],{"class":59}," *",[49,76,78],{"class":77},"sBMFI","template",[49,80,60],{"class":59},[49,82,83],{"class":77},"RichTextBuilder",[49,85,86],{"class":59},")",[49,88,89],{"class":59}," {\n",[49,91,93,96,98,101,104,107,111,113],{"class":51,"line":92},2,[49,94,95],{"class":55},"    rt",[49,97,60],{"class":59},[49,99,100],{"class":63},"Span",[49,102,103],{"class":59},"(",[49,105,106],{"class":59},"\"",[49,108,110],{"class":109},"sfazB","Run ",[49,112,106],{"class":59},[49,114,115],{"class":59},")\n",[49,117,119,121,123,125,127,129,132,134,137,140,142,145,147,149,152,154],{"class":51,"line":118},3,[49,120,95],{"class":55},[49,122,60],{"class":59},[49,124,100],{"class":63},[49,126,103],{"class":59},[49,128,106],{"class":59},[49,130,131],{"class":109},"gofmt ./...",[49,133,106],{"class":59},[49,135,136],{"class":59},",",[49,138,139],{"class":55}," template",[49,141,60],{"class":59},[49,143,144],{"class":63},"FontFamily",[49,146,103],{"class":59},[49,148,106],{"class":59},[49,150,151],{"class":109},"Courier",[49,153,106],{"class":59},[49,155,156],{"class":59},"))\n",[49,158,160,162,164,166,168,170,173,175],{"class":51,"line":159},4,[49,161,95],{"class":55},[49,163,60],{"class":59},[49,165,100],{"class":63},[49,167,103],{"class":59},[49,169,106],{"class":59},[49,171,172],{"class":109}," before you commit.",[49,174,106],{"class":59},[49,176,115],{"class":59},[49,178,180],{"class":51,"line":179},5,[49,181,182],{"class":59},"})\n",[18,184,185],{},"span 3 つ、フォント 2 つ、段落 1 つ。レイアウトエンジンはワードプロセッサと同じ要領で span 境界をまたいで改行するので、等幅のフラグメントは周囲の Helvetica とインラインで流れる。",[18,187,188,190,191,194,195,198,199,202],{},[27,189,151],{}," が ",[27,192,193],{},"WithFont"," 呼び出しなしで動くのは、PDF Standard 14 フォントの 1 つだから — ",[27,196,197],{},"Helvetica"," や ",[27,200,201],{},"Times-Roman"," と同じく、どのビューアも最初から持っている。2 つ目のフォントが自分で用意する TrueType ファイル (ブランドフォント、CJK フォント) なら、1 回登録して名前で参照する。詳しくは後述。",[14,204,206],{"id":205},"動くコード-helvetica-courierフォントファイルなし","動くコード (Helvetica + Courier、フォントファイルなし)",[40,208,210],{"className":42,"code":209,"language":44,"meta":45,"style":45},"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/pdf\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(gpdf.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.RichText(func(rt *template.RichTextBuilder) {\n                rt.Span(\"Run \")\n                rt.Span(\"gofmt ./...\", template.FontFamily(\"Courier\"))\n                rt.Span(\" before every commit. \")\n                rt.Span(\"It is not optional\", template.Bold(), template.Italic())\n                rt.Span(\".\")\n            })\n            c.RichText(func(rt *template.RichTextBuilder) {\n                rt.Span(\"The field is \")\n                rt.Span(\"created_at\", template.FontFamily(\"Courier\"), template.TextColor(pdf.RGBHex(0xB00020)))\n                rt.Span(\" — not \")\n                rt.Span(\"createdAt\", template.FontFamily(\"Courier\"))\n                rt.Span(\".\")\n            })\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"mixed-fonts.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[27,211,212,220,226,235,246,255,260,270,280,290,300,305,310,324,344,368,406,412,417,436,465,501,527,547,582,602,642,661,667,692,712,774,794,830,849,854,860,866,871,893,909,927,933,980,995,1000],{"__ignoreMap":45},[49,213,214,217],{"class":51,"line":52},[49,215,216],{"class":59},"package",[49,218,219],{"class":77}," main\n",[49,221,222],{"class":51,"line":92},[49,223,225],{"emptyLinePlaceholder":224},true,"\n",[49,227,228,232],{"class":51,"line":118},[49,229,231],{"class":230},"s7zQu","import",[49,233,234],{"class":59}," (\n",[49,236,237,240,243],{"class":51,"line":159},[49,238,239],{"class":59},"    \"",[49,241,242],{"class":77},"log",[49,244,245],{"class":59},"\"\n",[49,247,248,250,253],{"class":51,"line":179},[49,249,239],{"class":59},[49,251,252],{"class":77},"os",[49,254,245],{"class":59},[49,256,258],{"class":51,"line":257},6,[49,259,225],{"emptyLinePlaceholder":224},[49,261,263,265,268],{"class":51,"line":262},7,[49,264,239],{"class":59},[49,266,267],{"class":77},"github.com/gpdf-dev/gpdf",[49,269,245],{"class":59},[49,271,273,275,278],{"class":51,"line":272},8,[49,274,239],{"class":59},[49,276,277],{"class":77},"github.com/gpdf-dev/gpdf/document",[49,279,245],{"class":59},[49,281,283,285,288],{"class":51,"line":282},9,[49,284,239],{"class":59},[49,286,287],{"class":77},"github.com/gpdf-dev/gpdf/pdf",[49,289,245],{"class":59},[49,291,293,295,298],{"class":51,"line":292},10,[49,294,239],{"class":59},[49,296,297],{"class":77},"github.com/gpdf-dev/gpdf/template",[49,299,245],{"class":59},[49,301,303],{"class":51,"line":302},11,[49,304,115],{"class":59},[49,306,308],{"class":51,"line":307},12,[49,309,225],{"emptyLinePlaceholder":224},[49,311,313,316,319,322],{"class":51,"line":312},13,[49,314,315],{"class":59},"func",[49,317,318],{"class":63}," main",[49,320,321],{"class":59},"()",[49,323,89],{"class":59},[49,325,327,330,333,336,338,341],{"class":51,"line":326},14,[49,328,329],{"class":55},"    doc ",[49,331,332],{"class":59},":=",[49,334,335],{"class":55}," gpdf",[49,337,60],{"class":59},[49,339,340],{"class":63},"NewDocument",[49,342,343],{"class":59},"(\n",[49,345,347,350,352,355,357,360,362,365],{"class":51,"line":346},15,[49,348,349],{"class":55},"        gpdf",[49,351,60],{"class":59},[49,353,354],{"class":63},"WithPageSize",[49,356,103],{"class":59},[49,358,359],{"class":55},"gpdf",[49,361,60],{"class":59},[49,363,364],{"class":55},"A4",[49,366,367],{"class":59},"),\n",[49,369,371,373,375,378,380,383,385,388,390,392,394,397,399,403],{"class":51,"line":370},16,[49,372,349],{"class":55},[49,374,60],{"class":59},[49,376,377],{"class":63},"WithMargins",[49,379,103],{"class":59},[49,381,382],{"class":55},"document",[49,384,60],{"class":59},[49,386,387],{"class":63},"UniformEdges",[49,389,103],{"class":59},[49,391,382],{"class":55},[49,393,60],{"class":59},[49,395,396],{"class":63},"Mm",[49,398,103],{"class":59},[49,400,402],{"class":401},"sbssI","20",[49,404,405],{"class":59},"))),\n",[49,407,409],{"class":51,"line":408},17,[49,410,411],{"class":59},"    )\n",[49,413,415],{"class":51,"line":414},18,[49,416,225],{"emptyLinePlaceholder":224},[49,418,420,423,425,428,430,433],{"class":51,"line":419},19,[49,421,422],{"class":55},"    page ",[49,424,332],{"class":59},[49,426,427],{"class":55}," doc",[49,429,60],{"class":59},[49,431,432],{"class":63},"AddPage",[49,434,435],{"class":59},"()\n",[49,437,439,442,444,447,449,452,454,456,458,461,463],{"class":51,"line":438},20,[49,440,441],{"class":55},"    page",[49,443,60],{"class":59},[49,445,446],{"class":63},"AutoRow",[49,448,67],{"class":59},[49,450,451],{"class":70},"r",[49,453,74],{"class":59},[49,455,78],{"class":77},[49,457,60],{"class":59},[49,459,460],{"class":77},"RowBuilder",[49,462,86],{"class":59},[49,464,89],{"class":59},[49,466,468,471,473,476,478,481,483,486,488,490,492,494,497,499],{"class":51,"line":467},21,[49,469,470],{"class":55},"        r",[49,472,60],{"class":59},[49,474,475],{"class":63},"Col",[49,477,103],{"class":59},[49,479,480],{"class":401},"12",[49,482,136],{"class":59},[49,484,485],{"class":59}," func(",[49,487,56],{"class":70},[49,489,74],{"class":59},[49,491,78],{"class":77},[49,493,60],{"class":59},[49,495,496],{"class":77},"ColBuilder",[49,498,86],{"class":59},[49,500,89],{"class":59},[49,502,504,507,509,511,513,515,517,519,521,523,525],{"class":51,"line":503},22,[49,505,506],{"class":55},"            c",[49,508,60],{"class":59},[49,510,64],{"class":63},[49,512,67],{"class":59},[49,514,71],{"class":70},[49,516,74],{"class":59},[49,518,78],{"class":77},[49,520,60],{"class":59},[49,522,83],{"class":77},[49,524,86],{"class":59},[49,526,89],{"class":59},[49,528,530,533,535,537,539,541,543,545],{"class":51,"line":529},23,[49,531,532],{"class":55},"                rt",[49,534,60],{"class":59},[49,536,100],{"class":63},[49,538,103],{"class":59},[49,540,106],{"class":59},[49,542,110],{"class":109},[49,544,106],{"class":59},[49,546,115],{"class":59},[49,548,550,552,554,556,558,560,562,564,566,568,570,572,574,576,578,580],{"class":51,"line":549},24,[49,551,532],{"class":55},[49,553,60],{"class":59},[49,555,100],{"class":63},[49,557,103],{"class":59},[49,559,106],{"class":59},[49,561,131],{"class":109},[49,563,106],{"class":59},[49,565,136],{"class":59},[49,567,139],{"class":55},[49,569,60],{"class":59},[49,571,144],{"class":63},[49,573,103],{"class":59},[49,575,106],{"class":59},[49,577,151],{"class":109},[49,579,106],{"class":59},[49,581,156],{"class":59},[49,583,585,587,589,591,593,595,598,600],{"class":51,"line":584},25,[49,586,532],{"class":55},[49,588,60],{"class":59},[49,590,100],{"class":63},[49,592,103],{"class":59},[49,594,106],{"class":59},[49,596,597],{"class":109}," before every commit. ",[49,599,106],{"class":59},[49,601,115],{"class":59},[49,603,605,607,609,611,613,615,618,620,622,624,626,629,632,634,636,639],{"class":51,"line":604},26,[49,606,532],{"class":55},[49,608,60],{"class":59},[49,610,100],{"class":63},[49,612,103],{"class":59},[49,614,106],{"class":59},[49,616,617],{"class":109},"It is not optional",[49,619,106],{"class":59},[49,621,136],{"class":59},[49,623,139],{"class":55},[49,625,60],{"class":59},[49,627,628],{"class":63},"Bold",[49,630,631],{"class":59},"(),",[49,633,139],{"class":55},[49,635,60],{"class":59},[49,637,638],{"class":63},"Italic",[49,640,641],{"class":59},"())\n",[49,643,645,647,649,651,653,655,657,659],{"class":51,"line":644},27,[49,646,532],{"class":55},[49,648,60],{"class":59},[49,650,100],{"class":63},[49,652,103],{"class":59},[49,654,106],{"class":59},[49,656,60],{"class":109},[49,658,106],{"class":59},[49,660,115],{"class":59},[49,662,664],{"class":51,"line":663},28,[49,665,666],{"class":59},"            })\n",[49,668,670,672,674,676,678,680,682,684,686,688,690],{"class":51,"line":669},29,[49,671,506],{"class":55},[49,673,60],{"class":59},[49,675,64],{"class":63},[49,677,67],{"class":59},[49,679,71],{"class":70},[49,681,74],{"class":59},[49,683,78],{"class":77},[49,685,60],{"class":59},[49,687,83],{"class":77},[49,689,86],{"class":59},[49,691,89],{"class":59},[49,693,695,697,699,701,703,705,708,710],{"class":51,"line":694},30,[49,696,532],{"class":55},[49,698,60],{"class":59},[49,700,100],{"class":63},[49,702,103],{"class":59},[49,704,106],{"class":59},[49,706,707],{"class":109},"The field is ",[49,709,106],{"class":59},[49,711,115],{"class":59},[49,713,715,717,719,721,723,725,728,730,732,734,736,738,740,742,744,746,749,751,753,756,758,761,763,766,768,771],{"class":51,"line":714},31,[49,716,532],{"class":55},[49,718,60],{"class":59},[49,720,100],{"class":63},[49,722,103],{"class":59},[49,724,106],{"class":59},[49,726,727],{"class":109},"created_at",[49,729,106],{"class":59},[49,731,136],{"class":59},[49,733,139],{"class":55},[49,735,60],{"class":59},[49,737,144],{"class":63},[49,739,103],{"class":59},[49,741,106],{"class":59},[49,743,151],{"class":109},[49,745,106],{"class":59},[49,747,748],{"class":59},"),",[49,750,139],{"class":55},[49,752,60],{"class":59},[49,754,755],{"class":63},"TextColor",[49,757,103],{"class":59},[49,759,760],{"class":55},"pdf",[49,762,60],{"class":59},[49,764,765],{"class":63},"RGBHex",[49,767,103],{"class":59},[49,769,770],{"class":401},"0xB00020",[49,772,773],{"class":59},")))\n",[49,775,777,779,781,783,785,787,790,792],{"class":51,"line":776},32,[49,778,532],{"class":55},[49,780,60],{"class":59},[49,782,100],{"class":63},[49,784,103],{"class":59},[49,786,106],{"class":59},[49,788,789],{"class":109}," — not ",[49,791,106],{"class":59},[49,793,115],{"class":59},[49,795,797,799,801,803,805,807,810,812,814,816,818,820,822,824,826,828],{"class":51,"line":796},33,[49,798,532],{"class":55},[49,800,60],{"class":59},[49,802,100],{"class":63},[49,804,103],{"class":59},[49,806,106],{"class":59},[49,808,809],{"class":109},"createdAt",[49,811,106],{"class":59},[49,813,136],{"class":59},[49,815,139],{"class":55},[49,817,60],{"class":59},[49,819,144],{"class":63},[49,821,103],{"class":59},[49,823,106],{"class":59},[49,825,151],{"class":109},[49,827,106],{"class":59},[49,829,156],{"class":59},[49,831,833,835,837,839,841,843,845,847],{"class":51,"line":832},34,[49,834,532],{"class":55},[49,836,60],{"class":59},[49,838,100],{"class":63},[49,840,103],{"class":59},[49,842,106],{"class":59},[49,844,60],{"class":109},[49,846,106],{"class":59},[49,848,115],{"class":59},[49,850,852],{"class":51,"line":851},35,[49,853,666],{"class":59},[49,855,857],{"class":51,"line":856},36,[49,858,859],{"class":59},"        })\n",[49,861,863],{"class":51,"line":862},37,[49,864,865],{"class":59},"    })\n",[49,867,869],{"class":51,"line":868},38,[49,870,225],{"emptyLinePlaceholder":224},[49,872,874,877,879,882,884,886,888,891],{"class":51,"line":873},39,[49,875,876],{"class":55},"    data",[49,878,136],{"class":59},[49,880,881],{"class":55}," err ",[49,883,332],{"class":59},[49,885,427],{"class":55},[49,887,60],{"class":59},[49,889,890],{"class":63},"Generate",[49,892,435],{"class":59},[49,894,896,899,901,904,907],{"class":51,"line":895},40,[49,897,898],{"class":230},"    if",[49,900,881],{"class":55},[49,902,903],{"class":59},"!=",[49,905,906],{"class":59}," nil",[49,908,89],{"class":59},[49,910,912,915,917,920,922,925],{"class":51,"line":911},41,[49,913,914],{"class":55},"        log",[49,916,60],{"class":59},[49,918,919],{"class":63},"Fatal",[49,921,103],{"class":59},[49,923,924],{"class":55},"err",[49,926,115],{"class":59},[49,928,930],{"class":51,"line":929},42,[49,931,932],{"class":59},"    }\n",[49,934,936,938,940,942,945,947,950,952,954,957,959,961,964,966,969,972,974,976,978],{"class":51,"line":935},43,[49,937,898],{"class":230},[49,939,881],{"class":55},[49,941,332],{"class":59},[49,943,944],{"class":55}," os",[49,946,60],{"class":59},[49,948,949],{"class":63},"WriteFile",[49,951,103],{"class":59},[49,953,106],{"class":59},[49,955,956],{"class":109},"mixed-fonts.pdf",[49,958,106],{"class":59},[49,960,136],{"class":59},[49,962,963],{"class":55}," data",[49,965,136],{"class":59},[49,967,968],{"class":401}," 0o644",[49,970,971],{"class":59},");",[49,973,881],{"class":55},[49,975,903],{"class":59},[49,977,906],{"class":59},[49,979,89],{"class":59},[49,981,983,985,987,989,991,993],{"class":51,"line":982},44,[49,984,914],{"class":55},[49,986,60],{"class":59},[49,988,919],{"class":63},[49,990,103],{"class":59},[49,992,924],{"class":55},[49,994,115],{"class":59},[49,996,998],{"class":51,"line":997},45,[49,999,932],{"class":59},[49,1001,1003],{"class":51,"line":1002},46,[49,1004,1005],{"class":59},"}\n",[18,1007,1008,1009,1011,1012,1014,1015,1014,1018,1020],{},"本文は Helvetica (デフォルト) のまま、インラインの識別子は Courier に切り替わり、1 つの span はデフォルトフォントの上に bold + italic を重ねる。",[27,1010,193],{}," なし、埋め込みフォントデータなし — PDF は ",[27,1013,197],{},"、",[27,1016,1017],{},"Helvetica-BoldOblique",[27,1019,151],{}," を未埋め込みの Type 1 エントリとして参照する。どのリーダーも最初から持っているフォントだ。",[14,1022,1024],{"id":1023},"richtext-が-span-に対してやっていること","RichText が span に対してやっていること",[18,1026,1027,1028,1031,1032,1035,1036,1038,1039,1042],{},"各 ",[27,1029,1030],{},"rt.Span"," は独自のスタイルのコピーを持つ ",[27,1033,1034],{},"document.RichTextFragment"," になる。オプションなしで呼んだ span はブロックスタイル — ",[27,1037,64],{}," ではカラムのデフォルト、つまりドキュメントのデフォルトフォントとサイズ — を継承する。",[27,1040,1041],{},"template.FontFamily(\"Courier\")"," 付きで呼んだ span はそのフィールドだけ上書きされ、他はそのまま。",[18,1044,1045,1046,1050],{},"レイアウト時、gpdf は各フラグメントを単語レベルの run に分割し、各 run を ",[1047,1048,1049],"strong",{},"その run 自身のフォントメトリクス","で計測して — だから同じ行の Courier の単語と Helvetica の単語が正しい幅になる — 貪欲法で run を行に詰める。1 行上の run は同じベースラインを共有するので、24 pt の span と 12 pt の span が並ぶと下端で揃い、行の高さは背の高い方に合わせて伸びる。",[18,1052,1053,1054,1056,1057,1061,1062,1065],{},"ここで 1 つ引っかかるのが、",[27,1055,37],{}," の第 2 引数は",[1058,1059,1060],"em",{},"段落レベル","のスタイル、span ごとのオプションは",[1058,1063,1064],{},"フラグメントレベル","だという区別:",[1067,1068,1069,1082],"table",{},[1070,1071,1072],"thead",{},[1073,1074,1075,1079],"tr",{},[1076,1077,1078],"th",{},"オプション",[1076,1080,1081],{},"置き場所",[1083,1084,1085,1114],"tbody",{},[1073,1086,1087,1108],{},[1088,1089,1090,1092,1093,1092,1096,1092,1098,1092,1100,1092,1102,1092,1105],"td",{},[27,1091,144],{}," / ",[27,1094,1095],{},"FontSize",[27,1097,628],{},[27,1099,638],{},[27,1101,755],{},[27,1103,1104],{},"Underline",[27,1106,1107],{},"Strikethrough",[1088,1109,1110,1111,1113],{},"span ごと — 各 ",[27,1112,1030],{}," に渡す",[1073,1115,1116,1134],{},[1088,1117,1118,1092,1121,1092,1124,1092,1127,1130,1131],{},[27,1119,1120],{},"AlignLeft",[27,1122,1123],{},"AlignCenter",[27,1125,1126],{},"AlignRight",[27,1128,1129],{},"AlignJustify","、行の高さ、",[27,1132,1133],{},"TextIndent",[1088,1135,1136,1137,1139],{},"段落レベル — ",[27,1138,37],{}," の第 2 引数に渡す",[18,1141,1142,1143,1145,1146,1149],{},"個々の ",[27,1144,1030],{}," に ",[27,1147,1148],{},"AlignRight()"," を付けても何も起きない。アラインメントは行のプロパティであって、フラグメントのプロパティではない。",[14,1151,1153],{"id":1152},"本命のケース-欧文フォントの隣に-cjk-フォント","本命のケース: 欧文フォントの隣に CJK フォント",[18,1155,1156],{},"文中の等幅は簡単な方。実際にみんなが苦労するのは、1 行の中で欧文フォントと CJK フォントを混ぜることだ — 英語ラベルと日本語の値、製品コードと商品名。知っておくべきことが 2 つある。",[18,1158,1159,1160,1163,1164,1166,1167,1170],{},"1 つ目、",[1047,1161,1162],{},"gpdf はスクリプトでフォントを選ばない","。span のファミリーが ",[27,1165,197],{}," でテキストが ",[27,1168,1169],{},"日本語"," なら、豆腐 (□) が出る — Helvetica に CJK グリフはなく、gpdf は他の登録済みフォントを黙って引っ張ってカバーしたりしない。CJK の span には自分で CJK ファミリーを付ける:",[40,1172,1174],{"className":42,"code":1173,"language":44,"meta":45,"style":45},"ttf, _ := os.ReadFile(\"NotoSansJP-Regular.ttf\")\n\ndoc := gpdf.NewDocument(\n    gpdf.WithFont(\"NotoSansJP\", ttf),\n)\n// ...\nc.RichText(func(rt *template.RichTextBuilder) {\n    rt.Span(\"Customer: \")                                 // デフォルト → Helvetica\n    rt.Span(\"山田 太郎\", template.FontFamily(\"NotoSansJP\")) // CJK → Noto Sans JP\n    rt.Span(\"  (ID 10293)\")                               // Helvetica に戻る\n})\n",[27,1175,1176,1206,1210,1225,1250,1254,1260,1284,1306,1345,1367],{"__ignoreMap":45},[49,1177,1178,1181,1183,1186,1188,1190,1192,1195,1197,1199,1202,1204],{"class":51,"line":52},[49,1179,1180],{"class":55},"ttf",[49,1182,136],{"class":59},[49,1184,1185],{"class":55}," _ ",[49,1187,332],{"class":59},[49,1189,944],{"class":55},[49,1191,60],{"class":59},[49,1193,1194],{"class":63},"ReadFile",[49,1196,103],{"class":59},[49,1198,106],{"class":59},[49,1200,1201],{"class":109},"NotoSansJP-Regular.ttf",[49,1203,106],{"class":59},[49,1205,115],{"class":59},[49,1207,1208],{"class":51,"line":92},[49,1209,225],{"emptyLinePlaceholder":224},[49,1211,1212,1215,1217,1219,1221,1223],{"class":51,"line":118},[49,1213,1214],{"class":55},"doc ",[49,1216,332],{"class":59},[49,1218,335],{"class":55},[49,1220,60],{"class":59},[49,1222,340],{"class":63},[49,1224,343],{"class":59},[49,1226,1227,1230,1232,1234,1236,1238,1241,1243,1245,1248],{"class":51,"line":159},[49,1228,1229],{"class":55},"    gpdf",[49,1231,60],{"class":59},[49,1233,193],{"class":63},[49,1235,103],{"class":59},[49,1237,106],{"class":59},[49,1239,1240],{"class":109},"NotoSansJP",[49,1242,106],{"class":59},[49,1244,136],{"class":59},[49,1246,1247],{"class":55}," ttf",[49,1249,367],{"class":59},[49,1251,1252],{"class":51,"line":179},[49,1253,115],{"class":59},[49,1255,1256],{"class":51,"line":257},[49,1257,1259],{"class":1258},"sHwdD","// ...\n",[49,1261,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282],{"class":51,"line":262},[49,1263,56],{"class":55},[49,1265,60],{"class":59},[49,1267,64],{"class":63},[49,1269,67],{"class":59},[49,1271,71],{"class":70},[49,1273,74],{"class":59},[49,1275,78],{"class":77},[49,1277,60],{"class":59},[49,1279,83],{"class":77},[49,1281,86],{"class":59},[49,1283,89],{"class":59},[49,1285,1286,1288,1290,1292,1294,1296,1299,1301,1303],{"class":51,"line":272},[49,1287,95],{"class":55},[49,1289,60],{"class":59},[49,1291,100],{"class":63},[49,1293,103],{"class":59},[49,1295,106],{"class":59},[49,1297,1298],{"class":109},"Customer: ",[49,1300,106],{"class":59},[49,1302,86],{"class":59},[49,1304,1305],{"class":1258},"                                 // デフォルト → Helvetica\n",[49,1307,1308,1310,1312,1314,1316,1318,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1342],{"class":51,"line":282},[49,1309,95],{"class":55},[49,1311,60],{"class":59},[49,1313,100],{"class":63},[49,1315,103],{"class":59},[49,1317,106],{"class":59},[49,1319,1320],{"class":109},"山田 太郎",[49,1322,106],{"class":59},[49,1324,136],{"class":59},[49,1326,139],{"class":55},[49,1328,60],{"class":59},[49,1330,144],{"class":63},[49,1332,103],{"class":59},[49,1334,106],{"class":59},[49,1336,1240],{"class":109},[49,1338,106],{"class":59},[49,1340,1341],{"class":59},"))",[49,1343,1344],{"class":1258}," // CJK → Noto Sans JP\n",[49,1346,1347,1349,1351,1353,1355,1357,1360,1362,1364],{"class":51,"line":292},[49,1348,95],{"class":55},[49,1350,60],{"class":59},[49,1352,100],{"class":63},[49,1354,103],{"class":59},[49,1356,106],{"class":59},[49,1358,1359],{"class":109},"  (ID 10293)",[49,1361,106],{"class":59},[49,1363,86],{"class":59},[49,1365,1366],{"class":1258},"                               // Helvetica に戻る\n",[49,1368,1369],{"class":51,"line":302},[49,1370,182],{"class":59},[18,1372,1373,1374,1377,1378,1381,1382,1384,1385,1387,1388,1391],{},"2 つ目 — そしてこれは口に出して言っておくべきところだが — 日本語の CJK フォントの多くは、まともな欧文グリフをすでに持っている。Noto Sans JP、IPAex、Source Han Sans、どれも ",[27,1375,1376],{},"ID 10293"," をちゃんと描く。だから span ごとの混在に手を出す前に、本当に 2 つのフォントが要るのか、それとも惰性でそこに来ただけなのか、を考えてほしい。ドキュメント全体が「日本語＋少しの ASCII」なら、いちばん簡単なのは ",[27,1379,1380],{},"gpdf.WithDefaultFont(\"NotoSansJP\", 11)"," で混在ゼロ。",[27,1383,64],{}," + ",[27,1386,144],{}," を使うのは、本当に",[1058,1389,1390],{},"見た目を変えたい","とき — 数字には端正なジオメトリック欧文、本文にはヒューマニストな CJK — であって、単にスクリプトを表示させるためではない。",[14,1393,1395],{"id":1394},"ctext-で十分なとき","c.Text で十分なとき",[18,1397,1398,1399,1401,1402,1405,1406,1408,1409,1411,1412,1415,1416,1418],{},"文字列全体が 1 つのフォントなら、",[27,1400,29],{}," のままがいい — 軽いし読みやすい。",[27,1403,1404],{},"c.Text(\"発行日: 2026-05-11\", template.FontFamily(\"NotoSansJP\"))"," は行全体が 1 フォントで、",[27,1407,29],{}," で処理できる。",[27,1410,64],{}," が値を出すのは、スタイルが文字列の",[1058,1413,1414],{},"中で","変わるときだけ。1 スタイルの行を、できるからといって ",[27,1417,64],{}," のコールバックで包まないこと。",[14,1420,1421],{"id":1421},"関連レシピ",[1423,1424,1425,1437,1444],"ul",{},[1426,1427,1428,1433,1434,1436],"li",{},[1429,1430,1432],"a",{"href":1431},"/ja/blog/bold-italic-together","gpdf で Bold と Italic を同時に指定する方法"," — 同じ ",[27,1435,64],{}," の span メカニズムを、ファミリーではなくウェイトと斜体に適用したもの",[1426,1438,1439,1443],{},[1429,1440,1442],{"href":1441},"/ja/blog/add-custom-truetype-font","gpdf にカスタム TrueType フォントを追加する方法"," — 混ぜたい 2 つ目のフォントを登録する",[1426,1445,1446,1450,1451,1453],{},[1429,1447,1449],{"href":1448},"/ja/blog/embed-japanese-font","gpdf で日本語フォントを埋め込む方法"," — 混在フォント行の CJK 側の ",[27,1452,193],{}," の使い方",[14,1455,1457],{"id":1456},"gpdf-を使ってみる","gpdf を使ってみる",[18,1459,1460],{},"gpdf は Go の PDF 生成ライブラリ。MIT、ゼロ依存、CJK 対応。",[40,1462,1466],{"className":1463,"code":1464,"language":1465,"meta":45,"style":45},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[27,1467,1468],{"__ignoreMap":45},[49,1469,1470,1472,1475],{"class":51,"line":52},[49,1471,44],{"class":77},[49,1473,1474],{"class":109}," get",[49,1476,1477],{"class":109}," github.com/gpdf-dev/gpdf\n",[18,1479,1480,1486,1487],{},[1429,1481,1485],{"href":1482,"rel":1483},"https://github.com/gpdf-dev/gpdf",[1484],"nofollow","⭐ Star on GitHub"," · ",[1429,1488,1491],{"href":1489,"rel":1490},"https://gpdf.dev/ja/docs/quickstart",[1484],"ドキュメントを読む",[1493,1494,1495],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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}",{"title":45,"searchDepth":92,"depth":92,"links":1497},[1498,1499,1500,1501,1502,1503,1504,1505],{"id":16,"depth":92,"text":16},{"id":23,"depth":92,"text":23},{"id":205,"depth":92,"text":206},{"id":1023,"depth":92,"text":1024},{"id":1152,"depth":92,"text":1153},{"id":1394,"depth":92,"text":1395},{"id":1421,"depth":92,"text":1421},{"id":1456,"depth":92,"text":1457},"2026-05-11","gpdf で 1 段落に複数フォントを混ぜるには c.RichText を使い、各 Span に template.FontFamily を指定する。c.Text は文字列全体に 1 書体しか当てられない。",false,"md",{"name":1511,"totalTime":1512,"tools":1513,"steps":1515},"gpdf の 1 つの段落の中で 2 つのフォントファミリーを混ぜる","PT10M",[1514],"Go 1.22+",[1516,1519,1522,1525,1528],{"name":1517,"text":1518},"c.Text ではなく c.RichText を使う","c.Text は文字列全体に 1 つの Style を当てる。段落の途中でフォントを変えるには c.RichText(func(rt) { ... }) を呼び、各パーツを個別の rt.Span として追加する。",{"name":1520,"text":1521},"変えたい Span に template.FontFamily を指定する","rt.Span(\"gofmt ./...\", template.FontFamily(\"Courier\")) のように書く。FontFamily を付けない Span はドキュメントのデフォルトファミリーを継承する。",{"name":1523,"text":1524},"Standard 14 の名前を使えばフォント登録は不要","Helvetica / Courier / Times (とその Bold / Oblique バリアント) はどの PDF ビューアにも入っているので、これらを混ぜるのに WithFont 呼び出しは要らない。",{"name":1526,"text":1527},"2 つ目のフォントがカスタムや CJK なら先に TTF を登録する","TrueType ファミリーは構築時に gpdf.WithFont(\"NotoSansJP\", ttfBytes) を 1 回呼び、Span の中で \"NotoSansJP\" を名前で参照する。gpdf はスクリプト単位の自動フォールバックをしない。",{"name":1529,"text":1530},"同じ Span に FontSize / Bold / TextColor を重ねる","各 Span は独自の Style を持つので、rt.Span(\"BIG\", template.FontSize(24)) はサイズだけを変え、隣の Span は自分のサイズを保つ。行の高さは一番背の高い Span に追従する。",null,{},"/ja/blog/mix-two-fonts-in-paragraph",{"title":5,"description":1507},"ja/blog/023.mix-two-fonts-in-paragraph",[1537,1538,1539],"recipe","tutorial","cjk","VO-atuFf3V6ga1Le9db3PIQyAve0oP2fAWhHV5xRW6k",1779199021495]