如何使用CairoPDF导出含中线小数点Unicode字符的PDF?
解决CairoPDF无法导出含中线小数点的PDF问题
核心问题在于CairoPDF设备对字体字形查找、字符串编码解析的逻辑和普通pdf设备不同:一方面Helvetica字体可能未包含中线小数点(Unicode U+00B7)的对应字形,另一方面十六进制转义的字符在bquote中传递时,可能未被Cairo正确识别。
以下是几个可行的解决办法:
方法1:使用标准Unicode转义字符替换十六进制转义
把代码中替换小数点的部分改成使用\u00B7(中线小数点的Unicode标准转义格式),Cairo对这种转义的兼容性更好:
library(Cairo) library(grid) num <- sprintf("%.2f", round(27.382, 2)) num <- gsub("\\.","\\u00B7", num) # 改用Unicode标准转义写法 my_text <- bquote(italic("I")^2 ~ " = " ~ .(num)) CairoPDF("cairoTest1.pdf", width = 10, height = 5) grid.text(my_text, x=unit(.5, "npc"), y=unit(.5,"npc"), gp=gpar(fontfamily = "Helvetica", col = "black")) dev.off()
方法2:换用支持完整Unicode的字体
Helvetica是较传统的字体,部分Unicode特殊字符可能没有对应的字形,换成DejaVu Sans、Arial Unicode MS这类支持全Unicode字符集的字体即可:
library(Cairo) library(grid) num <- sprintf("%.2f", round(27.382, 2)) num <- gsub("\\.","\\xB7", num) my_text <- bquote(italic("I")^2 ~ " = " ~ .(num)) CairoPDF("cairoTest2.pdf", width = 10, height = 5) grid.text(my_text, x=unit(.5, "npc"), y=unit(.5,"npc"), gp=gpar(fontfamily = "DejaVu Sans", col = "black")) # 替换为支持Unicode的字体 dev.off()
方法3:直接用plotmath原生语法构建表达式
跳过字符串替换步骤,直接在表达式中用plotmath内置的cdot符号生成中线小数点,这是Cairo完美兼容的原生写法,兼容性最优:
library(Cairo) library(grid) val <- round(27.382, 2) # 拆分数值的整数和小数部分,用plotmath的cdot连接 my_expr <- bquote(italic("I")^2 ~ " = " ~ .(floor(val)) ~ cdot ~ .(sub(".*\\.", "", sprintf("%.2f", val)))) CairoPDF("cairoTest3.pdf", width = 10, height = 5) grid.text(my_expr, x=unit(.5, "npc"), y=unit(.5,"npc"), gp=gpar(fontfamily = "Helvetica", col = "black")) dev.off()
以上三种方法均可解决CairoPDF导出空白的问题,其中方法3利用plotmath原生符号,避免了字符编码和字体字形的兼容性问题,推荐优先使用。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

