gpt4 book ai didi

c - 给定目标打印机的 DPI,如何计算某种字体的某些打印文本的大小?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:30:37 28 4
gpt4 key购买 nike

我有一个正在将数据打印到打印机的应用程序。现在,我已经将字体大小硬编码为 18 磅,计算了所有与打印相关的坐标和偏移量(对于特定的 18 磅字体),然后我就开始打印了。我这样做只是作为开发我的应用程序的基础。

现在,我希望能够根据字体大小和字体动态调整所有内容(应该是这样)。

我写了下面的测试代码,没有任何错误检查,(C) 得到字体的逻辑大小:

void GetTextSize(char *input, size_t inputSize, char *fontName, size_t fontSize, SIZE *size)
{
if(input == NULL || size == NULL || fontName == NULL)
{
return;
}
else
{
HFONT hFont = NULL;
LOGFONT lf;
HDC hdc = NULL;

memset(&lf, 0, sizeof(lf));

// Get the device context of the entire screen
hdc = GetDC(NULL);

// Set the face-name
strcpy(lf.lfFaceName, fontName);

// Set the font height
lf.lfHeight = -MulDiv(fontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);

// Set the font weight
lf.lfWeight = FW_NORMAL;

// Create the font
hFont = CreateFontIndirect(&lf);

// Re-associate the obtained device context with the font just created
SelectObject(hdc, hFont);

// Get the required dimensions for the text
GetTextExtentPoint32(hdc, input, inputSize, &size);

// Free resources
ReleaseDC(NULL, hdc);
DeleteObject(hFont);
hFont = NULL;
hdc = NULL;
}
}

基本上,

  1. 获取整个屏幕的设备上下文。
  2. 使用 CreateFontIndirect 创建所需的字体和 LOGFONT结构。
  3. 将设备上下文与创建的字体重新关联。
  4. 使用 GetTextExtentPoint32 以逻辑单位计算字体宽度.

以上代码导致 size 变量包含:cx = 241, cy = 34。 (我的显示器的 DPI 是 96)

我如何将这些值映射到实际打印尺寸?由于默认的文本映射模式是 MM_TEXT ,这些 cxcy 值对应于像素。

我需要这样做有两个原因:

  1. 我需要将长行分成多行。因为我知道以英寸为单位的页面宽度,所以我只需要以英寸为单位的文本宽度。
  2. 我需要根据字体大小决定从哪里开始打印。

根据打印机规范,每毫米点数为 8;即,DPI 约为 203.2。

最佳答案

您的代码已经接近您的需要。您需要修复句柄泄漏,设备上下文需要在删除之前恢复:

    HGDIOBJ hOldFont = SelectObject(hdc, hFont);

// Get the required dimensions for the text
GetTextExtentPoint32A(hdc, input, strlen(input), size);

// Free resources
SelectObject(hdc, hOldFont);
::ReleaseDC(NULL, hdc);
DeleteObject(hFont);

接下来要做什么很大程度上取决于您希望结果的准确性。屏幕上 15 磅的字体在纸上也是 15 磅。因此,如果您想找到适合论文的最宽字符串,那么您将从以下位置获得:

 int maxWidth = (int)(paperWidthInInches * GetDeviceCaps(hdc, LOGPIXELSX));

请注意 DrawTextEx() 函数如何处理大量将文本放入纸中的繁重工作。它需要一个您设置为纸张大小的 RECT,它会自动呈现文本以适合该矩形。您通常希望使用 DT_WORDBREAK 选项让它在字边界处自动换行文本。使用 DT_CALCRECT 选项计算页面布局而不实际渲染文本。 DRAWTEXTPARAMS.uiLengthDrawn 值将被更新以告诉您当字符串不适合页面时从哪里开始打印字符串。

现在只需将打印机设备上下文传递给 DrawTextEx(),您就可以将文本呈现给打印机。传递从 CreateDC() 获得的设备上下文。 PrintDlg() 函数可以方便地让用户选择打印机。

这是个好消息。坏消息是 GDI 不提供真正设备无关的文本呈现。特别是对于监视器,渲染文本的宽度被巧妙地改变以固定像素网格。这提供了高度可读的文本,但会在具有更高 DPI 的设备(例如打印机)上抛出布局。差异很小,一行文本上只有几个像素,字体越大,差异越小。由于自动换行,这些小差异往往会在打印文本上变成大差异。

为避免这种情况,您需要使用打印机设备上下文来计算页面布局。通过将 RECT 传递给仅适合一行的 DrawTextEx() 来找出每行的结束位置。您现在呈现在屏幕上的内容当然不会完美,您需要一些肘部空间来呈现可能更宽的字符串。 DirectWrite 为真正独立于设备的文本呈现提供了一个 API。

关于c - 给定目标打印机的 DPI,如何计算某种字体的某些打印文本的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16986275/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com