[{"data":1,"prerenderedAt":1542},["ShallowReactive",2],{"blog-en-mix-two-fonts-in-paragraph":3},{"id":4,"title":5,"author":6,"body":10,"date":1507,"description":1508,"draft":1509,"extension":1510,"howTo":1511,"image":1532,"meta":1533,"navigation":226,"path":1534,"seo":1535,"stem":1536,"tags":1537,"updated":1532,"__hash__":1541},"blog/blog/023.mix-two-fonts-in-paragraph.md","How do I mix two fonts in the same paragraph in gpdf?",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1497},"minimark",[13,18,22,26,41,185,188,205,209,1008,1024,1028,1046,1054,1068,1140,1150,1154,1157,1171,1371,1392,1396,1419,1423,1455,1459,1462,1479,1493],[14,15,17],"h2",{"id":16},"the-question-in-other-words","The question, in other words",[19,20,21],"p",{},"I have one paragraph — a sentence, a label, a table cell — and I want part of it in one font and part of it in another. A code snippet in monospace inside a line of Helvetica. A Japanese name in Noto Sans JP next to an ASCII order ID. How do I switch fonts mid-paragraph without breaking the text into separate blocks?",[14,23,25],{"id":24},"the-quick-answer","The quick answer",[19,27,28,32,33,36,37,40],{},[29,30,31],"code",{},"c.Text"," is the wrong tool here. It applies one ",[29,34,35],{},"document.Style"," — one font family included — to the whole string. The tool you want is ",[29,38,39],{},"c.RichText",", where every span carries its own style:",[42,43,48],"pre",{"className":44,"code":45,"language":46,"meta":47,"style":47},"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","",[29,49,50,92,118,159,179],{"__ignoreMap":47},[51,52,55,59,63,67,70,74,77,81,83,86,89],"span",{"class":53,"line":54},"line",1,[51,56,58],{"class":57},"sTEyZ","c",[51,60,62],{"class":61},"sMK4o",".",[51,64,66],{"class":65},"s2Zo4","RichText",[51,68,69],{"class":61},"(func(",[51,71,73],{"class":72},"sHdIc","rt",[51,75,76],{"class":61}," *",[51,78,80],{"class":79},"sBMFI","template",[51,82,62],{"class":61},[51,84,85],{"class":79},"RichTextBuilder",[51,87,88],{"class":61},")",[51,90,91],{"class":61}," {\n",[51,93,95,98,100,103,106,109,113,115],{"class":53,"line":94},2,[51,96,97],{"class":57},"    rt",[51,99,62],{"class":61},[51,101,102],{"class":65},"Span",[51,104,105],{"class":61},"(",[51,107,108],{"class":61},"\"",[51,110,112],{"class":111},"sfazB","Run ",[51,114,108],{"class":61},[51,116,117],{"class":61},")\n",[51,119,121,123,125,127,129,131,134,136,139,142,144,147,149,151,154,156],{"class":53,"line":120},3,[51,122,97],{"class":57},[51,124,62],{"class":61},[51,126,102],{"class":65},[51,128,105],{"class":61},[51,130,108],{"class":61},[51,132,133],{"class":111},"gofmt ./...",[51,135,108],{"class":61},[51,137,138],{"class":61},",",[51,140,141],{"class":57}," template",[51,143,62],{"class":61},[51,145,146],{"class":65},"FontFamily",[51,148,105],{"class":61},[51,150,108],{"class":61},[51,152,153],{"class":111},"Courier",[51,155,108],{"class":61},[51,157,158],{"class":61},"))\n",[51,160,162,164,166,168,170,172,175,177],{"class":53,"line":161},4,[51,163,97],{"class":57},[51,165,62],{"class":61},[51,167,102],{"class":65},[51,169,105],{"class":61},[51,171,108],{"class":61},[51,173,174],{"class":111}," before you commit.",[51,176,108],{"class":61},[51,178,117],{"class":61},[51,180,182],{"class":53,"line":181},5,[51,183,184],{"class":61},"})\n",[19,186,187],{},"Three spans, two fonts, one paragraph. The layout engine line-breaks across the span boundaries the way a word processor would, so the monospace fragment flows inline with the Helvetica around it.",[19,189,190,192,193,196,197,200,201,204],{},[29,191,153],{}," works with no ",[29,194,195],{},"WithFont"," call because it's one of the PDF Standard 14 fonts — every viewer already has it, same as ",[29,198,199],{},"Helvetica"," and ",[29,202,203],{},"Times-Roman",". If your second font is a TrueType file you supply (a brand font, a CJK font), you register it once and refer to it by name. More on that below.",[14,206,208],{"id":207},"working-code-helvetica-courier-no-font-files","Working code (Helvetica + Courier, no font files)",[42,210,212],{"className":44,"code":211,"language":46,"meta":47,"style":47},"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",[29,213,214,222,228,237,248,257,262,272,282,292,302,307,312,326,346,370,408,414,419,438,467,503,529,549,584,604,644,663,669,694,714,776,796,832,851,856,862,868,873,895,911,929,935,982,997,1002],{"__ignoreMap":47},[51,215,216,219],{"class":53,"line":54},[51,217,218],{"class":61},"package",[51,220,221],{"class":79}," main\n",[51,223,224],{"class":53,"line":94},[51,225,227],{"emptyLinePlaceholder":226},true,"\n",[51,229,230,234],{"class":53,"line":120},[51,231,233],{"class":232},"s7zQu","import",[51,235,236],{"class":61}," (\n",[51,238,239,242,245],{"class":53,"line":161},[51,240,241],{"class":61},"    \"",[51,243,244],{"class":79},"log",[51,246,247],{"class":61},"\"\n",[51,249,250,252,255],{"class":53,"line":181},[51,251,241],{"class":61},[51,253,254],{"class":79},"os",[51,256,247],{"class":61},[51,258,260],{"class":53,"line":259},6,[51,261,227],{"emptyLinePlaceholder":226},[51,263,265,267,270],{"class":53,"line":264},7,[51,266,241],{"class":61},[51,268,269],{"class":79},"github.com/gpdf-dev/gpdf",[51,271,247],{"class":61},[51,273,275,277,280],{"class":53,"line":274},8,[51,276,241],{"class":61},[51,278,279],{"class":79},"github.com/gpdf-dev/gpdf/document",[51,281,247],{"class":61},[51,283,285,287,290],{"class":53,"line":284},9,[51,286,241],{"class":61},[51,288,289],{"class":79},"github.com/gpdf-dev/gpdf/pdf",[51,291,247],{"class":61},[51,293,295,297,300],{"class":53,"line":294},10,[51,296,241],{"class":61},[51,298,299],{"class":79},"github.com/gpdf-dev/gpdf/template",[51,301,247],{"class":61},[51,303,305],{"class":53,"line":304},11,[51,306,117],{"class":61},[51,308,310],{"class":53,"line":309},12,[51,311,227],{"emptyLinePlaceholder":226},[51,313,315,318,321,324],{"class":53,"line":314},13,[51,316,317],{"class":61},"func",[51,319,320],{"class":65}," main",[51,322,323],{"class":61},"()",[51,325,91],{"class":61},[51,327,329,332,335,338,340,343],{"class":53,"line":328},14,[51,330,331],{"class":57},"    doc ",[51,333,334],{"class":61},":=",[51,336,337],{"class":57}," gpdf",[51,339,62],{"class":61},[51,341,342],{"class":65},"NewDocument",[51,344,345],{"class":61},"(\n",[51,347,349,352,354,357,359,362,364,367],{"class":53,"line":348},15,[51,350,351],{"class":57},"        gpdf",[51,353,62],{"class":61},[51,355,356],{"class":65},"WithPageSize",[51,358,105],{"class":61},[51,360,361],{"class":57},"gpdf",[51,363,62],{"class":61},[51,365,366],{"class":57},"A4",[51,368,369],{"class":61},"),\n",[51,371,373,375,377,380,382,385,387,390,392,394,396,399,401,405],{"class":53,"line":372},16,[51,374,351],{"class":57},[51,376,62],{"class":61},[51,378,379],{"class":65},"WithMargins",[51,381,105],{"class":61},[51,383,384],{"class":57},"document",[51,386,62],{"class":61},[51,388,389],{"class":65},"UniformEdges",[51,391,105],{"class":61},[51,393,384],{"class":57},[51,395,62],{"class":61},[51,397,398],{"class":65},"Mm",[51,400,105],{"class":61},[51,402,404],{"class":403},"sbssI","20",[51,406,407],{"class":61},"))),\n",[51,409,411],{"class":53,"line":410},17,[51,412,413],{"class":61},"    )\n",[51,415,417],{"class":53,"line":416},18,[51,418,227],{"emptyLinePlaceholder":226},[51,420,422,425,427,430,432,435],{"class":53,"line":421},19,[51,423,424],{"class":57},"    page ",[51,426,334],{"class":61},[51,428,429],{"class":57}," doc",[51,431,62],{"class":61},[51,433,434],{"class":65},"AddPage",[51,436,437],{"class":61},"()\n",[51,439,441,444,446,449,451,454,456,458,460,463,465],{"class":53,"line":440},20,[51,442,443],{"class":57},"    page",[51,445,62],{"class":61},[51,447,448],{"class":65},"AutoRow",[51,450,69],{"class":61},[51,452,453],{"class":72},"r",[51,455,76],{"class":61},[51,457,80],{"class":79},[51,459,62],{"class":61},[51,461,462],{"class":79},"RowBuilder",[51,464,88],{"class":61},[51,466,91],{"class":61},[51,468,470,473,475,478,480,483,485,488,490,492,494,496,499,501],{"class":53,"line":469},21,[51,471,472],{"class":57},"        r",[51,474,62],{"class":61},[51,476,477],{"class":65},"Col",[51,479,105],{"class":61},[51,481,482],{"class":403},"12",[51,484,138],{"class":61},[51,486,487],{"class":61}," func(",[51,489,58],{"class":72},[51,491,76],{"class":61},[51,493,80],{"class":79},[51,495,62],{"class":61},[51,497,498],{"class":79},"ColBuilder",[51,500,88],{"class":61},[51,502,91],{"class":61},[51,504,506,509,511,513,515,517,519,521,523,525,527],{"class":53,"line":505},22,[51,507,508],{"class":57},"            c",[51,510,62],{"class":61},[51,512,66],{"class":65},[51,514,69],{"class":61},[51,516,73],{"class":72},[51,518,76],{"class":61},[51,520,80],{"class":79},[51,522,62],{"class":61},[51,524,85],{"class":79},[51,526,88],{"class":61},[51,528,91],{"class":61},[51,530,532,535,537,539,541,543,545,547],{"class":53,"line":531},23,[51,533,534],{"class":57},"                rt",[51,536,62],{"class":61},[51,538,102],{"class":65},[51,540,105],{"class":61},[51,542,108],{"class":61},[51,544,112],{"class":111},[51,546,108],{"class":61},[51,548,117],{"class":61},[51,550,552,554,556,558,560,562,564,566,568,570,572,574,576,578,580,582],{"class":53,"line":551},24,[51,553,534],{"class":57},[51,555,62],{"class":61},[51,557,102],{"class":65},[51,559,105],{"class":61},[51,561,108],{"class":61},[51,563,133],{"class":111},[51,565,108],{"class":61},[51,567,138],{"class":61},[51,569,141],{"class":57},[51,571,62],{"class":61},[51,573,146],{"class":65},[51,575,105],{"class":61},[51,577,108],{"class":61},[51,579,153],{"class":111},[51,581,108],{"class":61},[51,583,158],{"class":61},[51,585,587,589,591,593,595,597,600,602],{"class":53,"line":586},25,[51,588,534],{"class":57},[51,590,62],{"class":61},[51,592,102],{"class":65},[51,594,105],{"class":61},[51,596,108],{"class":61},[51,598,599],{"class":111}," before every commit. ",[51,601,108],{"class":61},[51,603,117],{"class":61},[51,605,607,609,611,613,615,617,620,622,624,626,628,631,634,636,638,641],{"class":53,"line":606},26,[51,608,534],{"class":57},[51,610,62],{"class":61},[51,612,102],{"class":65},[51,614,105],{"class":61},[51,616,108],{"class":61},[51,618,619],{"class":111},"It is not optional",[51,621,108],{"class":61},[51,623,138],{"class":61},[51,625,141],{"class":57},[51,627,62],{"class":61},[51,629,630],{"class":65},"Bold",[51,632,633],{"class":61},"(),",[51,635,141],{"class":57},[51,637,62],{"class":61},[51,639,640],{"class":65},"Italic",[51,642,643],{"class":61},"())\n",[51,645,647,649,651,653,655,657,659,661],{"class":53,"line":646},27,[51,648,534],{"class":57},[51,650,62],{"class":61},[51,652,102],{"class":65},[51,654,105],{"class":61},[51,656,108],{"class":61},[51,658,62],{"class":111},[51,660,108],{"class":61},[51,662,117],{"class":61},[51,664,666],{"class":53,"line":665},28,[51,667,668],{"class":61},"            })\n",[51,670,672,674,676,678,680,682,684,686,688,690,692],{"class":53,"line":671},29,[51,673,508],{"class":57},[51,675,62],{"class":61},[51,677,66],{"class":65},[51,679,69],{"class":61},[51,681,73],{"class":72},[51,683,76],{"class":61},[51,685,80],{"class":79},[51,687,62],{"class":61},[51,689,85],{"class":79},[51,691,88],{"class":61},[51,693,91],{"class":61},[51,695,697,699,701,703,705,707,710,712],{"class":53,"line":696},30,[51,698,534],{"class":57},[51,700,62],{"class":61},[51,702,102],{"class":65},[51,704,105],{"class":61},[51,706,108],{"class":61},[51,708,709],{"class":111},"The field is ",[51,711,108],{"class":61},[51,713,117],{"class":61},[51,715,717,719,721,723,725,727,730,732,734,736,738,740,742,744,746,748,751,753,755,758,760,763,765,768,770,773],{"class":53,"line":716},31,[51,718,534],{"class":57},[51,720,62],{"class":61},[51,722,102],{"class":65},[51,724,105],{"class":61},[51,726,108],{"class":61},[51,728,729],{"class":111},"created_at",[51,731,108],{"class":61},[51,733,138],{"class":61},[51,735,141],{"class":57},[51,737,62],{"class":61},[51,739,146],{"class":65},[51,741,105],{"class":61},[51,743,108],{"class":61},[51,745,153],{"class":111},[51,747,108],{"class":61},[51,749,750],{"class":61},"),",[51,752,141],{"class":57},[51,754,62],{"class":61},[51,756,757],{"class":65},"TextColor",[51,759,105],{"class":61},[51,761,762],{"class":57},"pdf",[51,764,62],{"class":61},[51,766,767],{"class":65},"RGBHex",[51,769,105],{"class":61},[51,771,772],{"class":403},"0xB00020",[51,774,775],{"class":61},")))\n",[51,777,779,781,783,785,787,789,792,794],{"class":53,"line":778},32,[51,780,534],{"class":57},[51,782,62],{"class":61},[51,784,102],{"class":65},[51,786,105],{"class":61},[51,788,108],{"class":61},[51,790,791],{"class":111}," — not ",[51,793,108],{"class":61},[51,795,117],{"class":61},[51,797,799,801,803,805,807,809,812,814,816,818,820,822,824,826,828,830],{"class":53,"line":798},33,[51,800,534],{"class":57},[51,802,62],{"class":61},[51,804,102],{"class":65},[51,806,105],{"class":61},[51,808,108],{"class":61},[51,810,811],{"class":111},"createdAt",[51,813,108],{"class":61},[51,815,138],{"class":61},[51,817,141],{"class":57},[51,819,62],{"class":61},[51,821,146],{"class":65},[51,823,105],{"class":61},[51,825,108],{"class":61},[51,827,153],{"class":111},[51,829,108],{"class":61},[51,831,158],{"class":61},[51,833,835,837,839,841,843,845,847,849],{"class":53,"line":834},34,[51,836,534],{"class":57},[51,838,62],{"class":61},[51,840,102],{"class":65},[51,842,105],{"class":61},[51,844,108],{"class":61},[51,846,62],{"class":111},[51,848,108],{"class":61},[51,850,117],{"class":61},[51,852,854],{"class":53,"line":853},35,[51,855,668],{"class":61},[51,857,859],{"class":53,"line":858},36,[51,860,861],{"class":61},"        })\n",[51,863,865],{"class":53,"line":864},37,[51,866,867],{"class":61},"    })\n",[51,869,871],{"class":53,"line":870},38,[51,872,227],{"emptyLinePlaceholder":226},[51,874,876,879,881,884,886,888,890,893],{"class":53,"line":875},39,[51,877,878],{"class":57},"    data",[51,880,138],{"class":61},[51,882,883],{"class":57}," err ",[51,885,334],{"class":61},[51,887,429],{"class":57},[51,889,62],{"class":61},[51,891,892],{"class":65},"Generate",[51,894,437],{"class":61},[51,896,898,901,903,906,909],{"class":53,"line":897},40,[51,899,900],{"class":232},"    if",[51,902,883],{"class":57},[51,904,905],{"class":61},"!=",[51,907,908],{"class":61}," nil",[51,910,91],{"class":61},[51,912,914,917,919,922,924,927],{"class":53,"line":913},41,[51,915,916],{"class":57},"        log",[51,918,62],{"class":61},[51,920,921],{"class":65},"Fatal",[51,923,105],{"class":61},[51,925,926],{"class":57},"err",[51,928,117],{"class":61},[51,930,932],{"class":53,"line":931},42,[51,933,934],{"class":61},"    }\n",[51,936,938,940,942,944,947,949,952,954,956,959,961,963,966,968,971,974,976,978,980],{"class":53,"line":937},43,[51,939,900],{"class":232},[51,941,883],{"class":57},[51,943,334],{"class":61},[51,945,946],{"class":57}," os",[51,948,62],{"class":61},[51,950,951],{"class":65},"WriteFile",[51,953,105],{"class":61},[51,955,108],{"class":61},[51,957,958],{"class":111},"mixed-fonts.pdf",[51,960,108],{"class":61},[51,962,138],{"class":61},[51,964,965],{"class":57}," data",[51,967,138],{"class":61},[51,969,970],{"class":403}," 0o644",[51,972,973],{"class":61},");",[51,975,883],{"class":57},[51,977,905],{"class":61},[51,979,908],{"class":61},[51,981,91],{"class":61},[51,983,985,987,989,991,993,995],{"class":53,"line":984},44,[51,986,916],{"class":57},[51,988,62],{"class":61},[51,990,921],{"class":65},[51,992,105],{"class":61},[51,994,926],{"class":57},[51,996,117],{"class":61},[51,998,1000],{"class":53,"line":999},45,[51,1001,934],{"class":61},[51,1003,1005],{"class":53,"line":1004},46,[51,1006,1007],{"class":61},"}\n",[19,1009,1010,1011,1013,1014,1016,1017,1020,1021,1023],{},"The body text stays in Helvetica (the default), the inline identifiers switch to Courier, and one span layers bold + italic on top of the default font. No ",[29,1012,195],{},", no embedded font data — the PDF references ",[29,1015,199],{},", ",[29,1018,1019],{},"Helvetica-BoldOblique",", and ",[29,1022,153],{}," as non-embedded Type 1 entries that every reader already has.",[14,1025,1027],{"id":1026},"what-richtext-does-with-the-spans","What RichText does with the spans",[19,1029,1030,1031,1034,1035,1038,1039,1041,1042,1045],{},"Each ",[29,1032,1033],{},"rt.Span"," becomes a ",[29,1036,1037],{},"document.RichTextFragment"," with its own copy of the style. A span you call with no options inherits the block style — which for ",[29,1040,66],{}," is the column's default, i.e. the document's default font and size. A span you call with ",[29,1043,1044],{},"template.FontFamily(\"Courier\")"," gets exactly that field overridden and keeps everything else.",[19,1047,1048,1049,1053],{},"At layout time gpdf splits every fragment into word-level runs, measures each run with ",[1050,1051,1052],"strong",{},"that run's own font metrics"," — this is why a Courier word and a Helvetica word on the same line get the right widths — and then greedily packs runs into lines. All runs on a line share one baseline, so a 24 pt span sitting next to a 12 pt span lines up at the bottom and the line's height grows to fit the tall one.",[19,1055,1056,1057,1059,1060,1064,1065,62],{},"One distinction trips people up: the second argument to ",[29,1058,39],{}," is ",[1061,1062,1063],"em",{},"paragraph-level"," style, the per-span options are ",[1061,1066,1067],{},"fragment-level",[1069,1070,1071,1084],"table",{},[1072,1073,1074],"thead",{},[1075,1076,1077,1081],"tr",{},[1078,1079,1080],"th",{},"Option",[1078,1082,1083],{},"Where it belongs",[1085,1086,1087,1114],"tbody",{},[1075,1088,1089,1109],{},[1090,1091,1092,1016,1094,1016,1097,1016,1099,1016,1101,1016,1103,1016,1106],"td",{},[29,1093,146],{},[29,1095,1096],{},"FontSize",[29,1098,630],{},[29,1100,640],{},[29,1102,757],{},[29,1104,1105],{},"Underline",[29,1107,1108],{},"Strikethrough",[1090,1110,1111,1112],{},"per-span — pass to each ",[29,1113,1033],{},[1075,1115,1116,1135],{},[1090,1117,1118,1121,1122,1121,1125,1121,1128,1131,1132],{},[29,1119,1120],{},"AlignLeft"," / ",[29,1123,1124],{},"AlignCenter",[29,1126,1127],{},"AlignRight",[29,1129,1130],{},"AlignJustify",", line height, ",[29,1133,1134],{},"TextIndent",[1090,1136,1137,1138],{},"paragraph-level — pass as the second arg to ",[29,1139,39],{},[19,1141,1142,1143,1146,1147,1149],{},"Putting ",[29,1144,1145],{},"AlignRight()"," on an individual ",[29,1148,1033],{}," does nothing; alignment is a property of the line, not the fragment.",[14,1151,1153],{"id":1152},"the-real-case-a-latin-font-next-to-a-cjk-font","The real case: a Latin font next to a CJK font",[19,1155,1156],{},"Monospace-inside-a-sentence is the easy version. The one people actually fight with is mixing a Western font with a CJK font on one line — an English label and a Japanese value, a product code and a 商品名. Two things to know.",[19,1158,1159,1160,1163,1164,1166,1167,1170],{},"First, ",[1050,1161,1162],{},"gpdf does not pick a font by script",". If a span's family is ",[29,1165,199],{}," and the text is ",[29,1168,1169],{},"日本語",", you get tofu boxes — Helvetica has no CJK glyphs, and gpdf will not silently reach for some other registered font to cover them. Put the CJK family on the CJK span yourself:",[42,1172,1174],{"className":44,"code":1173,"language":46,"meta":47,"style":47},"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: \")                                 // default → Helvetica\n    rt.Span(\"山田 太郎\", template.FontFamily(\"NotoSansJP\")) // CJK → Noto Sans JP\n    rt.Span(\"  (ID 10293)\")                               // back to Helvetica\n})\n",[29,1175,1176,1206,1210,1225,1250,1254,1260,1284,1306,1345,1367],{"__ignoreMap":47},[51,1177,1178,1181,1183,1186,1188,1190,1192,1195,1197,1199,1202,1204],{"class":53,"line":54},[51,1179,1180],{"class":57},"ttf",[51,1182,138],{"class":61},[51,1184,1185],{"class":57}," _ ",[51,1187,334],{"class":61},[51,1189,946],{"class":57},[51,1191,62],{"class":61},[51,1193,1194],{"class":65},"ReadFile",[51,1196,105],{"class":61},[51,1198,108],{"class":61},[51,1200,1201],{"class":111},"NotoSansJP-Regular.ttf",[51,1203,108],{"class":61},[51,1205,117],{"class":61},[51,1207,1208],{"class":53,"line":94},[51,1209,227],{"emptyLinePlaceholder":226},[51,1211,1212,1215,1217,1219,1221,1223],{"class":53,"line":120},[51,1213,1214],{"class":57},"doc ",[51,1216,334],{"class":61},[51,1218,337],{"class":57},[51,1220,62],{"class":61},[51,1222,342],{"class":65},[51,1224,345],{"class":61},[51,1226,1227,1230,1232,1234,1236,1238,1241,1243,1245,1248],{"class":53,"line":161},[51,1228,1229],{"class":57},"    gpdf",[51,1231,62],{"class":61},[51,1233,195],{"class":65},[51,1235,105],{"class":61},[51,1237,108],{"class":61},[51,1239,1240],{"class":111},"NotoSansJP",[51,1242,108],{"class":61},[51,1244,138],{"class":61},[51,1246,1247],{"class":57}," ttf",[51,1249,369],{"class":61},[51,1251,1252],{"class":53,"line":181},[51,1253,117],{"class":61},[51,1255,1256],{"class":53,"line":259},[51,1257,1259],{"class":1258},"sHwdD","// ...\n",[51,1261,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282],{"class":53,"line":264},[51,1263,58],{"class":57},[51,1265,62],{"class":61},[51,1267,66],{"class":65},[51,1269,69],{"class":61},[51,1271,73],{"class":72},[51,1273,76],{"class":61},[51,1275,80],{"class":79},[51,1277,62],{"class":61},[51,1279,85],{"class":79},[51,1281,88],{"class":61},[51,1283,91],{"class":61},[51,1285,1286,1288,1290,1292,1294,1296,1299,1301,1303],{"class":53,"line":274},[51,1287,97],{"class":57},[51,1289,62],{"class":61},[51,1291,102],{"class":65},[51,1293,105],{"class":61},[51,1295,108],{"class":61},[51,1297,1298],{"class":111},"Customer: ",[51,1300,108],{"class":61},[51,1302,88],{"class":61},[51,1304,1305],{"class":1258},"                                 // default → Helvetica\n",[51,1307,1308,1310,1312,1314,1316,1318,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1342],{"class":53,"line":284},[51,1309,97],{"class":57},[51,1311,62],{"class":61},[51,1313,102],{"class":65},[51,1315,105],{"class":61},[51,1317,108],{"class":61},[51,1319,1320],{"class":111},"山田 太郎",[51,1322,108],{"class":61},[51,1324,138],{"class":61},[51,1326,141],{"class":57},[51,1328,62],{"class":61},[51,1330,146],{"class":65},[51,1332,105],{"class":61},[51,1334,108],{"class":61},[51,1336,1240],{"class":111},[51,1338,108],{"class":61},[51,1340,1341],{"class":61},"))",[51,1343,1344],{"class":1258}," // CJK → Noto Sans JP\n",[51,1346,1347,1349,1351,1353,1355,1357,1360,1362,1364],{"class":53,"line":294},[51,1348,97],{"class":57},[51,1350,62],{"class":61},[51,1352,102],{"class":65},[51,1354,105],{"class":61},[51,1356,108],{"class":61},[51,1358,1359],{"class":111},"  (ID 10293)",[51,1361,108],{"class":61},[51,1363,88],{"class":61},[51,1365,1366],{"class":1258},"                               // back to Helvetica\n",[51,1368,1369],{"class":53,"line":304},[51,1370,184],{"class":61},[19,1372,1373,1374,1377,1378,1381,1382,1384,1385,1387,1388,1391],{},"Second — and this is the part worth saying out loud — most Japanese CJK fonts already carry decent Latin glyphs. Noto Sans JP, IPAex, Source Han Sans: all of them draw ",[29,1375,1376],{},"ID 10293"," perfectly well. So before you reach for a per-span mix, ask whether you actually want two fonts or just got there by habit. If the whole document is Japanese-with-some-ASCII, the simplest thing is ",[29,1379,1380],{},"gpdf.WithDefaultFont(\"NotoSansJP\", 11)"," and never mix at all. Reach for ",[29,1383,66],{}," + ",[29,1386,146],{}," when you genuinely want a ",[1061,1389,1390],{},"different look"," — a clean geometric Latin face for the numbers, a humanist CJK face for the prose — not just to make the script render.",[14,1393,1395],{"id":1394},"when-ctext-is-still-fine","When c.Text is still fine",[19,1397,1398,1399,1401,1402,1405,1406,1408,1409,1411,1412,1415,1416,1418],{},"If the whole string is one font, keep using ",[29,1400,31],{}," — it's lighter and reads better. ",[29,1403,1404],{},"c.Text(\"発行日: 2026-05-11\", template.FontFamily(\"NotoSansJP\"))"," is one font for the whole line, and ",[29,1407,31],{}," handles it. ",[29,1410,66],{}," earns its keep only when the style changes ",[1061,1413,1414],{},"inside"," the string. Don't wrap a single-style line in a ",[29,1417,66],{}," callback just because you can.",[14,1420,1422],{"id":1421},"related-recipes","Related recipes",[1424,1425,1426,1438,1445],"ul",{},[1427,1428,1429,1434,1435,1437],"li",{},[1430,1431,1433],"a",{"href":1432},"/blog/bold-italic-together","How do I use bold and italic together in gpdf?"," — the same ",[29,1436,66],{}," span mechanism, applied to weight and slant instead of family",[1427,1439,1440,1444],{},[1430,1441,1443],{"href":1442},"/blog/add-custom-truetype-font","How do I add a custom TrueType font to gpdf?"," — registering the second font you want to mix in",[1427,1446,1447,1451,1452,1454],{},[1430,1448,1450],{"href":1449},"/blog/embed-japanese-font","How do I embed a Japanese font in gpdf?"," — the ",[29,1453,195],{}," walkthrough for the CJK side of a mixed-font line",[14,1456,1458],{"id":1457},"try-gpdf","Try gpdf",[19,1460,1461],{},"gpdf is a Go library for generating PDFs. MIT licensed, zero external dependencies, native CJK support.",[42,1463,1467],{"className":1464,"code":1465,"language":1466,"meta":47,"style":47},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[29,1468,1469],{"__ignoreMap":47},[51,1470,1471,1473,1476],{"class":53,"line":54},[51,1472,46],{"class":79},[51,1474,1475],{"class":111}," get",[51,1477,1478],{"class":111}," github.com/gpdf-dev/gpdf\n",[19,1480,1481,1487,1488],{},[1430,1482,1486],{"href":1483,"rel":1484},"https://github.com/gpdf-dev/gpdf",[1485],"nofollow","⭐ Star on GitHub"," · ",[1430,1489,1492],{"href":1490,"rel":1491},"https://gpdf.dev/docs/quickstart",[1485],"Read the docs",[1494,1495,1496],"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":47,"searchDepth":94,"depth":94,"links":1498},[1499,1500,1501,1502,1503,1504,1505,1506],{"id":16,"depth":94,"text":17},{"id":24,"depth":94,"text":25},{"id":207,"depth":94,"text":208},{"id":1026,"depth":94,"text":1027},{"id":1152,"depth":94,"text":1153},{"id":1394,"depth":94,"text":1395},{"id":1421,"depth":94,"text":1422},{"id":1457,"depth":94,"text":1458},"2026-05-11","To mix fonts in one paragraph in gpdf, call c.RichText and set template.FontFamily on each span — c.Text only styles the whole string at once.",false,"md",{"name":1512,"totalTime":1513,"tools":1514,"steps":1516},"Mix two font families inside one gpdf paragraph","PT10M",[1515],"Go 1.22+",[1517,1520,1523,1526,1529],{"name":1518,"text":1519},"Reach for c.RichText, not c.Text","c.Text applies one Style to the whole string. To change fonts mid-paragraph, call c.RichText(func(rt) { ... }) and add each piece as its own rt.Span.",{"name":1521,"text":1522},"Set template.FontFamily on the span you want different","Call rt.Span(\"gofmt ./...\", template.FontFamily(\"Courier\")). A span with no FontFamily inherits the document's default family.",{"name":1524,"text":1525},"Use Standard 14 names to skip font registration","Helvetica, Courier, and Times (with their Bold/Oblique variants) ship inside every PDF viewer, so mixing them needs no WithFont call.",{"name":1527,"text":1528},"Register a TTF first if the second font is custom or CJK","For a TrueType family, call gpdf.WithFont(\"NotoSansJP\", ttfBytes) once at construction, then reference \"NotoSansJP\" by name in a span. gpdf does not fall back by script.",{"name":1530,"text":1531},"Stack FontSize, Bold, and TextColor on the same span","Each span carries its own Style, so rt.Span(\"BIG\", template.FontSize(24)) sets size while its siblings keep theirs; the line height tracks the tallest span.",null,{},"/blog/mix-two-fonts-in-paragraph",{"title":5,"description":1508},"blog/023.mix-two-fonts-in-paragraph",[1538,1539,1540],"recipe","tutorial","cjk","qXmW_roA7-57forWRTCX1nEIlXi9NtmfjmvABl14brQ",1779199010122]