GetTextExtentPoint导致别名

问题描述

可能与之相关的人

GetTextExtentPoint和GetTextExtentPoint32给我带来了糟糕的一天。

它们是MSDN提供的唯一一种测量文本的方法,但是它们有两个缺陷,但是似乎没有其他人有这些问题。

首先,他们不考虑换行符。他们将测量结果视为一根长的衬管。

第二个也是最重要的一点是,当我执行DrawText()时,它们会导致混叠。我正在将ClearType用于HFONT,但仍会绘制出别名文本。

请让我确切地知道问题所在。或者,我可能必须创建自己的测量文本功能

EDIT _________

// 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,FW_norMAL,false,CLEAR_TYPE_QUALITY,face_name);
}

RECT Box{0,640,480);
POINT pos{};
HFONT font = createFont("MyFavouriteFont",30);
HDC canvas = CreateCompatableDC(NULL);
HBITMAP bmp = CreateCompatibleBitmap(NULL,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,&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,-1,DT_LEFT);

BitBlt(dest_ctx,pos.x,pos.y,Box.right,Box.bottom,canvas,SRCcopY);
}

解决方案_____ 我已经发布了一个解决方案作为答案。我不喜欢这样做。正如我之前说的,似乎没有其他人有这个问题,所以没有其他人会需要解决方案。

解决方法

正如我之前所说,使用任何文本测量功能时,似乎没有人得到块状文本。我在使用它们中的任何一个时都知道。

我注意到的是,调用这些函数需要一个上下文,而这些函数似乎正在破坏上下文。即使我在上下文中选择了一种新字体,我仍然会得到块状文本输出。

因此,我即时创建了一个上下文,并在其中添加了所需的字体。并根据该上下文进行测量,收集结果并删除该上下文。我对此进行了测试,并且由于我的原始上下文不受影响,因此文本绘制得很流畅。

原因我讨厌这种方法: -我担心要动态创建和删除上下文。

- I dont think GetTextExtent should currupt my context in the first place.

如果你们有更好的方法,或者知道我的问题,或者为什么我不应该在发这个问题。

EDIT _________ 看完MSDN上的键盘教程后,我看到作者在哪里使用窗口上下文而不是内存上下文来调用GetTextExtent。看来GetTextExtent和其他度量功能仅旨在与窗口上下文一起使用。这对我来说非常好,因为我不喜欢创建内存上下文。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...