如何使用 PoDoFo 设置 PDF 中整段文本或单个单词的颜色?
数据小许
在支持 GraphicsState.SetNonStrokingColor 的 PoDoFo 版本中,先设置非描边颜色,再调用 DrawText,就能改变普通填充文本的颜色。如果只想给某个单词着色,可以把文本拆成几段,切换颜色后分别绘制。
为什么要设置非描边颜色?
PDF 区分填充颜色和描边颜色。普通文本默认以填充方式显示,因此需要设置非描边颜色。PoDoFo 对应的接口是 painter.GraphicsState.SetNonStrokingColor(...),声明见官方 PdfPainter.h。
创建 PdfColor 对象本身不会改变绘制状态,还需要将它传给颜色设置接口。
如何将整段文本设为红色?
将原示例中注释掉的颜色设置部分替换为下面的调用,放在 DrawText 之前:
painter.TextState.SetFont(*font, 18.0);
painter.GraphicsState.SetNonStrokingColor(
PdfColor(1.0, 0.0, 0.0));
painter.DrawText(
"Hello World!", 56.69, page.GetRect().Height - 56.69);
这里使用 RGB 颜色,各分量的范围为 0.0 到 1.0,(1.0, 0.0, 0.0) 表示红色。PoDoFo 仓库也有一条针对示例颜色设置方式的修正记录。
颜色设置会影响后续使用该绘制状态的操作,不会修改已经绘制的文字。如果只想临时改变颜色,可以成对使用 Save() 和 Restore()。
如何只将一个单词设为红色?
以 Hello World! 为例,将 World 显示为红色,其余文字保持黑色。保留原示例的文档、页面和字体初始化代码,将原来的单次 DrawText 调用替换为:
painter.TextState.SetFont(*font, 18.0);
const double x = 56.69;
const double y = page.GetRect().Height - 56.69;
const double prefixWidth =
font->GetStringLength("Hello ", painter.TextState);
const double wordWidth =
font->GetStringLength("World", painter.TextState);
painter.GraphicsState.SetNonStrokingColor(
PdfColor(0.0, 0.0, 0.0));
painter.DrawText("Hello ", x, y);
painter.Save();
painter.GraphicsState.SetNonStrokingColor(
PdfColor(1.0, 0.0, 0.0));
painter.DrawText("World", x + prefixWidth, y);
painter.Restore();
painter.DrawText("!", x + prefixWidth + wordWidth, y);
GetStringLength 根据字体和当前 PdfTextState 计算文本宽度,返回值以 PDF 单位计,可用于确定下一段文字的起点,详见官方 PdfFont 文档。测量 Hello 时需要保留末尾空格,否则单词之间会缺少间隔。
使用时需要注意什么?
- 原问题没有提供 PoDoFo 版本。以上写法以安装版本提供这些接口为前提;如果成员不存在,应核对对应版本的头文件和API 迁移说明,避免混用不同版本的示例。
- 在解引用
font前检查SearchFont("Arial")的返回值,并单独处理字体查找失败的情况。 - 分段示例适用于这里的简单英文单行文本。涉及复杂文字塑形、连字或自动换行时,需要结合实际排版过程处理,不能假定在任意位置拆分后字形和间距都保持不变。
- 绘制结束后,保留原示例中的
painter.FinishDrawing(),再调用document.Save(...)。
备注:内容仅供参考。
