GetTextExtentPoint 导致别名
Posted
技术标签:
【中文标题】GetTextExtentPoint 导致别名【英文标题】:GetTextExtentPoint causes aliasing 【发布时间】:2021-01-01 07:36:33 【问题描述】:它可能与谁有关,
GetTextExtentPoint 和 GetTextExtentPoint32 给我带来了糟糕的一天。
它们是 MSDN 提供的唯一测量文本的方法,但它们有两个缺陷,但似乎没有其他人有这些问题。
首先,他们不考虑换行符。他们将测量视为一根长一根线。
其次,最重要的是,当我执行 DrawText() 时,它们会导致锯齿。我正在为 HFONT 使用 ClearType,但仍在绘制别名文本。
请让我确切知道是什么问题。或者我可能必须创建自己的测量文本函数。
编辑_________
// note font is created with CLEAR_TYPE_QUALITY
// so it should be antialiased
HFONT createFont(const char *face_name,int height)
return CreateFont(height,cHeight,0,0,0,FW_NORMAL,false,false,false,0,0,0,CLEAR_TYPE_QUALITY,0,face_name);
RECT box0,0,640,480);
POINT pos;
HFONT font = createFont("MyFavouriteFont",30);
HDC canvas = CreateCompatableDC(NULL);
HBITMAP bmp = CreateCompatibleBitmap(NULL,640,480);
SelectBitmap(canvas,bmp);
SelectFont(canvas,font);
SelectBrush(canvas,GetStockObject(DC_BRUSH));
SetDCBrushColor(RGB(255,255,255));
SetBkMode(TRANSPARENT);
SIZE measureText_Msdn(const char *s,HDC font)
SIZE sz;
GetTextExtentPoint(font,s,strlen(s),&sz);
return sz;
SIZE measureText_Custom(const char *s,HDC font)
SIZE sz;
TEXTMETRICSA metrics;
INT char_width, line_width;
// get char height
GetTextMetrics(font,&metrics);
while(*it)
if(*it == '\n' || *it == '\r')
if(line_width > sz.cx) sz.cx = line_width; // sz.cx stores max width
sz.cy += metrics.tmHeight;
line_width = 0;
else
GetCharWidth32(font,*it,*it,&char_width);
line_width += char_width;
++it;
if(line_width > sz.cx) sz.cx = line_width;
if(line_width > 0) sz.cy += metrics.tmHeight; // If there are no chars on this line, the line has no size
return sz;
void drawText(HDC dest_ctx)
auto s = ,"Text will look blocky";
measureText_Msdn(s,font);
// or measureText_Custom(s,font); will cause font to look blocky and ugly
// If you comment out measureText_* text will be drawn smooth.
FillRect(canvas, &box,(HBRUSH)GetCurrentObject(canvas,OBJ_BRUSH));
DrawTextA(canvas,s,-1,&box,DT_LEFT);
BitBlt(dest_ctx,pos.x,pos.y,box.right,box.bottom,
canvas,0,0,SRCCOPY);
解决方案_____ 我已经发布了一个解决方案作为答案。我不喜欢这样做。正如我之前所说,似乎没有其他人有这个问题,所以没有其他人需要解决方案。
【问题讨论】:
展示你的作品。在没有证据的情况下说“这行不通”在这里并没有多大意义。 既然the documentation 说计算高度时不考虑换行符,为什么会认为这是个问题呢?其次,通过“导致锯齿”,您是指适用于文本的标准抗锯齿 Windows 吗? @Andy 感谢您的 cmets。将在问题中添加我的工作。正如我所说,换行是我的问题,因为文本在一行上。但是,调用 GetTextExtent 函数然后调用 DrawText 会使文本看起来好像没有使用抗锯齿。我将提供一个示例代码。表达我使用 GetTextMetrics 和 GetCharWidth32 创建测量 gdi 文本的函数时的情况。我发现这两个问题也会导致问题。 【参考方案1】:正如我之前所说,在使用任何文本测量功能时,似乎没有人会得到块状文本。我在使用其中任何一个时都会得到它。
我注意到调用这些函数需要上下文,而这些函数似乎正在破坏上下文。即使我在上下文中选择了一种新字体,我仍然会得到块状文本输出。
因此,我动态创建了一个上下文并将所需的字体添加到其中。并使用该上下文进行测量,收集结果并删除该上下文。我对此进行了测试,我的文本绘制得很流畅,因为我的原始上下文不受影响。
我讨厌这种方法的原因: - 我害怕动态创建和删除上下文的开销。
- I dont think GetTextExtent should currupt my context in the first place.
如果你们有更好的方法,或者知道我的问题,或者为什么我不应该遇到这个问题,请发帖。
编辑_________ 在查看了 MSDN 上的使用键盘教程后,我看到作者在哪里使用窗口上下文而不是内存上下文来调用 GetTextExtent。看来 GetTextExtent 和其他测量功能仅适用于窗口上下文。这对我来说非常好,因为我不喜欢创建内存上下文。
【讨论】:
以上是关于GetTextExtentPoint 导致别名的主要内容,如果未能解决你的问题,请参考以下文章