[{"data":1,"prerenderedAt":1539},["ShallowReactive",2],{"blog-zh-mix-two-fonts-in-paragraph":3},{"id":4,"title":5,"author":6,"body":10,"date":1504,"description":1505,"draft":1506,"extension":1507,"howTo":1508,"image":1529,"meta":1530,"navigation":224,"path":1531,"seo":1532,"stem":1533,"tags":1534,"updated":1529,"__hash__":1538},"blogZh/zh/blog/023.mix-two-fonts-in-paragraph.md","如何在 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":1494},"minimark",[13,17,21,24,39,183,186,203,207,1006,1020,1024,1042,1050,1065,1138,1148,1152,1155,1169,1369,1390,1394,1417,1420,1452,1456,1459,1476,1490],[14,15,16],"h2",{"id":16},"换个说法",[18,19,20],"p",{},"我有一个段落 —— 一句话、一个标签、一个表格单元 —— 想让其中一部分用一种字体，另一部分用另一种。Helvetica 的一行里嵌一段等宽的代码片段。ASCII 订单号旁边用 Noto Sans JP 写一个日文名字。怎样在段落中途换字体，又不把文本拆成不同的块？",[14,22,23],{"id":23},"简短答案",[18,25,26,30,31,34,35,38],{},[27,28,29],"code",{},"c.Text"," 在这里是错的工具。它给整个字符串套一个 ",[27,32,33],{},"document.Style"," —— 字体族也只有一个。你要的是 ",[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],{},"3 个 span，2 种字体，1 个段落。布局引擎会像文字处理器那样跨 span 边界换行，所以等宽片段会和周围的 Helvetica 行内一起流动。",[18,187,188,190,191,194,195,198,199,202],{},[27,189,151],{}," 不用 ",[27,192,193],{},"WithFont"," 也能用，因为它是 PDF Standard 14 字体之一 —— 和 ",[27,196,197],{},"Helvetica","、",[27,200,201],{},"Times-Roman"," 一样，每个阅读器都自带。如果第二个字体是你自己提供的 TrueType 文件（品牌字体、CJK 字体），就注册一次再按名字引用。下面细说。",[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,198,1014,198,1017,1019],{},"正文保持 Helvetica（默认），行内标识符切到 Courier，有一个 span 在默认字体上叠了 bold + italic。没有 ",[27,1010,193],{},"，没有内嵌字体数据 —— PDF 把 ",[27,1013,197],{},[27,1015,1016],{},"Helvetica-BoldOblique",[27,1018,151],{}," 作为未内嵌的 Type 1 条目引用，每个阅读器都已经有这些字体。",[14,1021,1023],{"id":1022},"richtext-对这些-span-做了什么","RichText 对这些 span 做了什么",[18,1025,1026,1027,1030,1031,1034,1035,1037,1038,1041],{},"每个 ",[27,1028,1029],{},"rt.Span"," 都会变成一个带自己样式副本的 ",[27,1032,1033],{},"document.RichTextFragment","。不带选项调用的 span 继承块样式 —— 在 ",[27,1036,64],{}," 里就是列的默认值，也就是文档的默认字体和大小。带 ",[27,1039,1040],{},"template.FontFamily(\"Courier\")"," 调用的 span 只覆盖那个字段，其它保持不变。",[18,1043,1044,1045,1049],{},"布局时 gpdf 把每个 fragment 拆成单词级的 run，用 ",[1046,1047,1048],"strong",{},"该 run 自己的字体度量","去测量 —— 所以同一行里 Courier 的单词和 Helvetica 的单词宽度才对 —— 然后用贪心法把 run 装进行。同一行上的 run 共享一条基线，所以 24 pt 的 span 挨着 12 pt 的 span 时在底部对齐，行高会增长以容纳高的那个。",[18,1051,1052,1053,1055,1056,1060,1061,1064],{},"有一点容易让人栽跟头：",[27,1054,37],{}," 的第二个参数是",[1057,1058,1059],"em",{},"段落级","样式，每个 span 的选项是",[1057,1062,1063],{},"片段级","的：",[1066,1067,1068,1081],"table",{},[1069,1070,1071],"thead",{},[1072,1073,1074,1078],"tr",{},[1075,1076,1077],"th",{},"选项",[1075,1079,1080],{},"该放在哪",[1082,1083,1084,1112],"tbody",{},[1072,1085,1086,1107],{},[1087,1088,1089,1091,1092,1091,1095,1091,1097,1091,1099,1091,1101,1091,1104],"td",{},[27,1090,144],{}," / ",[27,1093,1094],{},"FontSize",[27,1096,628],{},[27,1098,638],{},[27,1100,755],{},[27,1102,1103],{},"Underline",[27,1105,1106],{},"Strikethrough",[1087,1108,1109,1110],{},"每个 span —— 传给每个 ",[27,1111,1029],{},[1072,1113,1114,1132],{},[1087,1115,1116,1091,1119,1091,1122,1091,1125,1128,1129],{},[27,1117,1118],{},"AlignLeft",[27,1120,1121],{},"AlignCenter",[27,1123,1124],{},"AlignRight",[27,1126,1127],{},"AlignJustify","、行高、",[27,1130,1131],{},"TextIndent",[1087,1133,1134,1135,1137],{},"段落级 —— 作为 ",[27,1136,37],{}," 的第二个参数传",[18,1139,1140,1141,1143,1144,1147],{},"在单个 ",[27,1142,1029],{}," 上加 ",[27,1145,1146],{},"AlignRight()"," 什么也不会发生。对齐是行的属性，不是片段的属性。",[14,1149,1151],{"id":1150},"真正的场景拉丁字体挨着-cjk-字体","真正的场景：拉丁字体挨着 CJK 字体",[18,1153,1154],{},"句中等宽是简单版。大家真正头疼的是在一行里混用西文字体和 CJK 字体 —— 英文标签和日文值、产品代码和商品名。要知道两点。",[18,1156,1157,1158,1161,1162,1164,1165,1168],{},"第一，",[1046,1159,1160],{},"gpdf 不按文字系统挑字体","。如果某个 span 的字体族是 ",[27,1163,197],{}," 而文本是 ",[27,1166,1167],{},"日本語","，你会得到豆腐字（□）—— Helvetica 没有 CJK 字形，gpdf 也不会悄悄拉来别的已注册字体来补。你要自己给 CJK 的 span 设上 CJK 字体族：",[40,1170,1172],{"className":42,"code":1171,"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,1173,1174,1204,1208,1223,1248,1252,1258,1282,1304,1343,1365],{"__ignoreMap":45},[49,1175,1176,1179,1181,1184,1186,1188,1190,1193,1195,1197,1200,1202],{"class":51,"line":52},[49,1177,1178],{"class":55},"ttf",[49,1180,136],{"class":59},[49,1182,1183],{"class":55}," _ ",[49,1185,332],{"class":59},[49,1187,944],{"class":55},[49,1189,60],{"class":59},[49,1191,1192],{"class":63},"ReadFile",[49,1194,103],{"class":59},[49,1196,106],{"class":59},[49,1198,1199],{"class":109},"NotoSansJP-Regular.ttf",[49,1201,106],{"class":59},[49,1203,115],{"class":59},[49,1205,1206],{"class":51,"line":92},[49,1207,225],{"emptyLinePlaceholder":224},[49,1209,1210,1213,1215,1217,1219,1221],{"class":51,"line":118},[49,1211,1212],{"class":55},"doc ",[49,1214,332],{"class":59},[49,1216,335],{"class":55},[49,1218,60],{"class":59},[49,1220,340],{"class":63},[49,1222,343],{"class":59},[49,1224,1225,1228,1230,1232,1234,1236,1239,1241,1243,1246],{"class":51,"line":159},[49,1226,1227],{"class":55},"    gpdf",[49,1229,60],{"class":59},[49,1231,193],{"class":63},[49,1233,103],{"class":59},[49,1235,106],{"class":59},[49,1237,1238],{"class":109},"NotoSansJP",[49,1240,106],{"class":59},[49,1242,136],{"class":59},[49,1244,1245],{"class":55}," ttf",[49,1247,367],{"class":59},[49,1249,1250],{"class":51,"line":179},[49,1251,115],{"class":59},[49,1253,1254],{"class":51,"line":257},[49,1255,1257],{"class":1256},"sHwdD","// ...\n",[49,1259,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280],{"class":51,"line":262},[49,1261,56],{"class":55},[49,1263,60],{"class":59},[49,1265,64],{"class":63},[49,1267,67],{"class":59},[49,1269,71],{"class":70},[49,1271,74],{"class":59},[49,1273,78],{"class":77},[49,1275,60],{"class":59},[49,1277,83],{"class":77},[49,1279,86],{"class":59},[49,1281,89],{"class":59},[49,1283,1284,1286,1288,1290,1292,1294,1297,1299,1301],{"class":51,"line":272},[49,1285,95],{"class":55},[49,1287,60],{"class":59},[49,1289,100],{"class":63},[49,1291,103],{"class":59},[49,1293,106],{"class":59},[49,1295,1296],{"class":109},"Customer: ",[49,1298,106],{"class":59},[49,1300,86],{"class":59},[49,1302,1303],{"class":1256},"                                 // 默认 → Helvetica\n",[49,1305,1306,1308,1310,1312,1314,1316,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1340],{"class":51,"line":282},[49,1307,95],{"class":55},[49,1309,60],{"class":59},[49,1311,100],{"class":63},[49,1313,103],{"class":59},[49,1315,106],{"class":59},[49,1317,1318],{"class":109},"山田 太郎",[49,1320,106],{"class":59},[49,1322,136],{"class":59},[49,1324,139],{"class":55},[49,1326,60],{"class":59},[49,1328,144],{"class":63},[49,1330,103],{"class":59},[49,1332,106],{"class":59},[49,1334,1238],{"class":109},[49,1336,106],{"class":59},[49,1338,1339],{"class":59},"))",[49,1341,1342],{"class":1256}," // CJK → Noto Sans JP\n",[49,1344,1345,1347,1349,1351,1353,1355,1358,1360,1362],{"class":51,"line":292},[49,1346,95],{"class":55},[49,1348,60],{"class":59},[49,1350,100],{"class":63},[49,1352,103],{"class":59},[49,1354,106],{"class":59},[49,1356,1357],{"class":109},"  (ID 10293)",[49,1359,106],{"class":59},[49,1361,86],{"class":59},[49,1363,1364],{"class":1256},"                               // 回到 Helvetica\n",[49,1366,1367],{"class":51,"line":302},[49,1368,182],{"class":59},[18,1370,1371,1372,1375,1376,1379,1380,1382,1383,1385,1386,1389],{},"第二 —— 这一点值得说出来 —— 多数日文 CJK 字体本身就带不错的拉丁字形。Noto Sans JP、IPAex、Source Han Sans，它们都能把 ",[27,1373,1374],{},"ID 10293"," 画得很好。所以在动手做逐 span 混排之前，先问问你是真的要两种字体，还是只是习惯使然走到了这一步。如果整份文档是「日文 + 一点 ASCII」，最简单的就是 ",[27,1377,1378],{},"gpdf.WithDefaultFont(\"NotoSansJP\", 11)","，根本不混。要用 ",[27,1381,64],{}," + ",[27,1384,144],{},"，是在你真的想要",[1057,1387,1388],{},"不同的观感","时 —— 数字用干净的几何拉丁体，正文用人文主义 CJK 体 —— 而不是为了让文字能显示出来。",[14,1391,1393],{"id":1392},"什么时候-ctext-就够了","什么时候 c.Text 就够了",[18,1395,1396,1397,1399,1400,1403,1404,1406,1407,1409,1410,1413,1414,1416],{},"如果整个字符串是一种字体，继续用 ",[27,1398,29],{}," —— 更轻，也更好读。",[27,1401,1402],{},"c.Text(\"発行日: 2026-05-11\", template.FontFamily(\"NotoSansJP\"))"," 是整行一种字体，",[27,1405,29],{}," 能处理。",[27,1408,64],{}," 体现价值，只在样式",[1057,1411,1412],{},"在字符串内部","变化时。别因为能这么做，就把单一样式的一行包进 ",[27,1415,64],{}," 回调里。",[14,1418,1419],{"id":1419},"相关菜谱",[1421,1422,1423,1435,1442],"ul",{},[1424,1425,1426,1431,1432,1434],"li",{},[1427,1428,1430],"a",{"href":1429},"/zh/blog/bold-italic-together","如何在 gpdf 中同时使用粗体和斜体"," —— 同样的 ",[27,1433,64],{}," span 机制，用在字重和倾斜上而不是字体族",[1424,1436,1437,1441],{},[1427,1438,1440],{"href":1439},"/zh/blog/add-custom-truetype-font","如何在 gpdf 中添加自定义 TrueType 字体"," —— 注册你想混进来的第二个字体",[1424,1443,1444,1448,1449,1451],{},[1427,1445,1447],{"href":1446},"/zh/blog/embed-japanese-font","如何在 gpdf 中嵌入日文字体"," —— 混排行 CJK 一侧的 ",[27,1450,193],{}," 用法",[14,1453,1455],{"id":1454},"试试-gpdf","试试 gpdf",[18,1457,1458],{},"gpdf 是一个用于生成 PDF 的 Go 库。MIT 许可，零外部依赖，原生支持 CJK。",[40,1460,1464],{"className":1461,"code":1462,"language":1463,"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,1465,1466],{"__ignoreMap":45},[49,1467,1468,1470,1473],{"class":51,"line":52},[49,1469,44],{"class":77},[49,1471,1472],{"class":109}," get",[49,1474,1475],{"class":109}," github.com/gpdf-dev/gpdf\n",[18,1477,1478,1484,1485],{},[1427,1479,1483],{"href":1480,"rel":1481},"https://github.com/gpdf-dev/gpdf",[1482],"nofollow","⭐ Star on GitHub"," · ",[1427,1486,1489],{"href":1487,"rel":1488},"https://gpdf.dev/zh/docs/quickstart",[1482],"阅读文档",[1491,1492,1493],"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":1495},[1496,1497,1498,1499,1500,1501,1502,1503],{"id":16,"depth":92,"text":16},{"id":23,"depth":92,"text":23},{"id":205,"depth":92,"text":206},{"id":1022,"depth":92,"text":1023},{"id":1150,"depth":92,"text":1151},{"id":1392,"depth":92,"text":1393},{"id":1419,"depth":92,"text":1419},{"id":1454,"depth":92,"text":1455},"2026-05-11","在 gpdf 中要在一个段落里混用多种字体，用 c.RichText 并给每个 span 设置 template.FontFamily。c.Text 只能给整个字符串套一种字体。",false,"md",{"name":1509,"totalTime":1510,"tools":1511,"steps":1513},"在一个 gpdf 段落里混用两个字体族","PT10M",[1512],"Go 1.22+",[1514,1517,1520,1523,1526],{"name":1515,"text":1516},"用 c.RichText，而不是 c.Text","c.Text 给整个字符串套一个 Style。要在段落中途换字体，调用 c.RichText(func(rt) { ... })，把每一部分作为单独的 rt.Span 添加。",{"name":1518,"text":1519},"在想换的 span 上设置 template.FontFamily","写成 rt.Span(\"gofmt ./...\", template.FontFamily(\"Courier\"))。没有 FontFamily 的 span 继承文档的默认字体族。",{"name":1521,"text":1522},"用 Standard 14 的名字就不必注册字体","Helvetica、Courier、Times（及其 Bold / Oblique 变体）每个 PDF 阅读器都自带，所以混用它们不需要 WithFont 调用。",{"name":1524,"text":1525},"如果第二个字体是自定义或 CJK，先注册 TTF","对 TrueType 字体族，在构造时调用一次 gpdf.WithFont(\"NotoSansJP\", ttfBytes)，然后在 span 里按名字引用 \"NotoSansJP\"。gpdf 不会按文字系统自动回退。",{"name":1527,"text":1528},"在同一个 span 上叠加 FontSize / Bold / TextColor","每个 span 有自己的 Style，所以 rt.Span(\"BIG\", template.FontSize(24)) 只改大小，相邻 span 保持各自的大小；行高跟随最高的 span。",null,{},"/zh/blog/mix-two-fonts-in-paragraph",{"title":5,"description":1505},"zh/blog/023.mix-two-fonts-in-paragraph",[1535,1536,1537],"recipe","tutorial","cjk","4XZA-P5uhBsT1N7PQAJ6qB8kJbAtU-1WZEyUUPWPb_w",1779199016624]