我正在使用 PoDoFo 提取字符位移以正确更新文本矩阵。这是我的一个代码片段:
PdfString str, ucode_str;
std::stack<PdfVariant> *stack;
const PdfFontMetrics *f_metrics;
...
/* Convert string to UTF8 */
str = stack->top().GetString();
ucode_str = ts->font->GetEncoding()->ConvertToUnicode(str, ts->font);
stack->pop();
c_str = (char *) ucode_str.GetStringUtf8().c_str();
/* Font metrics to obtain a character displacement */
f_metrics = ts->font->GetFontMetrics();
for (j = 0; j < strlen(c_str); j++) {
str_w = f_metrics->CharWidth(c_str[j]);
/* Adjust text matrix using str_w */
...
}
它适用于某些 PDF 文件(str_w
包含有用的宽度),但不适用于其他文件。在这些情况下str_w
包含0.0
. 我查看了 PoDoFo0.9.5
源代码,发现CharWidth()
所有子类都实现了PdfFontMetrics
.
在这个字符串转换过程中我是否遗漏了一些重要的东西?
从 04.08.2017 更新
@mkl 在审查 PoDoFo 的代码方面做得非常好。但是,我意识到我必须获得一些不同的参数。准确地说,我需要一个以文本空间单位表示的字形宽度(请参阅PDF 参考1.7、5.1.3 Glyph Positioning and Metrics ) ,但其实现方式如下:CharWidth()
PdfFontMetricsObject.cpp
double PdfFontMetricsObject::CharWidth(unsigned char c) const
{
if (c >= m_nFirst && c <= m_nLast &&
c - m_nFirst < static_cast<int>(m_width.GetSize())) {
double dWidth = m_width[c - m_nFirst].GetReal();
return (dWidth * m_matrix.front().GetReal() * this->GetFontSize() + this->GetFontCharSpace()) * this->GetFontScale() / 100.0;
}
if (m_missingWidth != NULL)
return m_missingWidth->GetReal();
else
return m_dDefWidth;
}
宽度是使用附加乘数(如字体大小、字符空间等)计算的。我真正需要的dWidth * m_matrix.front().GetReal()
只是。因此,我决定GetGlyphWidth(int c)
从同一个文件中实现,例如:
double PdfFontMetricsObject::GetGlyphWidth(int c) const
{
if (c >= m_nFirst && c <= m_nLast &&
c - m_nFirst < static_cast<int>(m_width.GetSize())) {
double dWidth = m_width[c - m_nFirst].GetReal();
return dWidth * m_matrix.front().GetReal();
}
return 0.0;
}
并调用这个而不是CharWidth()
从第一个列表中调用。