-1

我想用GetTextExtentPoint32像素来计算字符串的大小。GetTextExtentPoint32具有以下语法:

BOOL GetTextExtentPoint32(
  _In_  HDC     hdc,
  _In_  LPCTSTR lpString,
  _In_  int     c,
  _Out_ LPSIZE  lpSize
);

hdc [in]设备上下文的句柄在哪里。

问题:

我正在使用以下代码在libharu中加载字体

    //-----UTF8 Encoding
    HPDF_UseUTFEncodings(pdf);
    const char *fontname = HPDF_LoadTTFontFromFile(pdf, "FreeSans.ttf", HPDF_TRUE);
    HPDF_Font font = HPDF_GetFont(pdf, fontname, "UTF-8");

如何将设备句柄传递/计算给GetTextExtentPoint32()

更新: 我在分辨率 (1920x1080) 的显示器上使用 Win-7。我的目标是使用Libharu库生成 PDF 报告。我想以像素为单位计算字符串的长度,为此,我想使用GetTextExtentPoint32()

4

2 回答 2

1

因此,要使用 libharu 获取 PDF 中文本字符串的宽度,请使用HPDF_Font_TextWidth(). 这将返回一个HPDF_TextWidth结构;使用它的width领域。宽度将以em 的 1/10001000 em测量,我不确定哪个(使用 TrueType 用于 em 正方形的任何“em”意义),我假设 PDF 本身用于测量。您必须查看 HPDF 文档的其余部分。

我不确定这是否考虑到字距调整。

确认:HPDF的通用字体处理源码,HDPF的TrueType字体处理源码,Apple的TrueType字体参考。准确的计算是

一个字形的宽度 = Advance_width(units) * 1000 / units_per_em

于 2016-10-14T13:26:38.537 回答
0

Windows GDI 使用像素。Haru PDF 使用点(72 点/英寸)。Haru PDF中没有直接的等价物GetTextExtentPoint32()

如果您想以 PDF 格式复制 GDI 结果,您需要:

[1] 调用GetTextExtentPoint32()以获取 GDI 像素中的文本大小。

[2] 以像素为单位的宽度除以设备上下文分辨率(像素/英寸),然后乘以 72 得到点。调用GetDeviceCaps(hdc, LOGPIXELSX)以获取像素/英寸。调用这个结果fTargetWidth。这是您期望字符串的宽度。

[3] 在编写 PDF 时,调用HPDF_Font_TextWidth()以获取从 Haru 看到的字符串的宽度。如果 PDF 宽度大于 GDI 的“点”宽度,请稍微缩小间距,减去超出字符范围的部分:

// how long is this string?
HPDF_TextWidth htw = HPDF_Font_TextWidth(pdfFont, (HPDF_BYTE *)string, len);
// convert to actual points
fWidth = (htw.width * fontPoints) / 1000.f;
// does it overflow?
if(fWidth > fTargetWidth && htw.numchars > 0)
{   excess = fWidth - fTargetWidth;    // by how much
    charSpace = -excess / htw.numchars;  // note negative
    // tighten up the spacing
    HPDF_Page_SetCharSpace(page, charSpace);
}

HPDF_Page_TextOut (page, x, y, string);
HPDF_Page_SetCharSpace(page, 0.f);      // reset

由于某种原因,HPDF_Page_SetWordSpace()似乎没有任何效果。

同样的字体,同样的大小,怎么会有这么大的宽度差异呢?所见即所得:o)

于 2016-12-16T00:18:16.067 回答