Text 如何绘制GDI+;独立于新闻部的文本
我正在使用GDI+绘制文本。我最近注意到,当DPI更改时,此文本会自动缩放。有没有办法使GDI+文本绘图独立于DPI?例如,我想画一个不超过20像素的文本,而不考虑DPI。可能吗?如何做到这一点 下面是一个示例代码。我希望以恒定的大小绘制第一个文本,而不考虑DPI,第二个文本通常:Text 如何绘制GDI+;独立于新闻部的文本,text,gdi+,draw,dpi,Text,Gdi+,Draw,Dpi,我正在使用GDI+绘制文本。我最近注意到,当DPI更改时,此文本会自动缩放。有没有办法使GDI+文本绘图独立于DPI?例如,我想画一个不超过20像素的文本,而不考虑DPI。可能吗?如何做到这一点 下面是一个示例代码。我希望以恒定的大小绘制第一个文本,而不考虑DPI,第二个文本通常: case WM_PAINT: { inherited::WndProc(message); Canvas->Brush->Style = bsSolid;
case WM_PAINT:
{
inherited::WndProc(message);
Canvas->Brush->Style = bsSolid;
Canvas->Brush->Color = clWhite;
Canvas->FillRect(ClientRect);
// get GDI+ graphics from canvas
Gdiplus::Graphics graphics(Canvas->Handle);
// set text rendering hint
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintSystemDefault);
std::auto_ptr<Gdiplus::Font> pFont(new Gdiplus::Font(Canvas->Handle, Font->Handle));
std::auto_ptr<Gdiplus::SolidBrush> pBrush(new Gdiplus::SolidBrush(Gdiplus::Color(255, 0, 0, 0)));
std::auto_ptr<Gdiplus::StringFormat> pFormat(new Gdiplus::StringFormat());
Gdiplus::FontFamily fontFamily;
pFont->GetFamily(&fontFamily);
std::auto_ptr<Gdiplus::Font> pFont2(new Gdiplus::Font(&fontFamily, pFont->GetSize(),
pFont->GetStyle(), Gdiplus::UnitPixel));
Gdiplus::Unit test = pFont->GetUnit();
Gdiplus::Unit test2 = pFont2->GetUnit();
pFormat->SetAlignment(Gdiplus::StringAlignmentNear);
pFormat->SetLineAlignment(Gdiplus::StringAlignmentNear);
Gdiplus::StringFormatFlags flags = Gdiplus::StringFormatFlagsBypassGDI;
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionRightToLeft);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionVertical);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoWrap);
//flags = (Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoClip);
pFormat->SetFormatFlags(flags);
pFormat->SetTrimming(Gdiplus::StringTrimmingEllipsisCharacter);
pFormat->SetHotkeyPrefix(Gdiplus::HotkeyPrefixNone);
std::wstring text = L"This is a sample code";
Gdiplus::Unit prevPageUnit = graphics.GetPageUnit();
try
{
graphics.SetPageUnit(Gdiplus::UnitPixel);
// draw text
graphics.DrawString(text.c_str(), text.length(), pFont2.get(), Gdiplus::RectF(ClientRect.Left,
ClientRect.Top, ClientWidth, ClientHeight), pFormat.get(), pBrush.get());
}
__finally
{
graphics.SetPageUnit(prevPageUnit);
}
// draw text 2
graphics.DrawString(text.c_str(), text.length(), pFont.get(), Gdiplus::RectF(ClientRect.Left,
ClientRect.Top + 25, ClientWidth, ClientHeight), pFormat.get(), pBrush.get());
return;
}
case WM_PAINT:
{
继承::WndProc(消息);
画布->画笔->样式=bsSolid;
画布->画笔->颜色=白色;
Canvas->FillRect(ClientRect);
//从画布获取GDI+图形
图形(画布->句柄);
//设置文本呈现提示
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintSystemDefault);
std::auto_ptr pFont(新的Gdiplus::Font(画布->句柄,字体->句柄));
std::auto_ptr pBrush(新的Gdiplus::SolidBrush(Gdiplus::Color(255,0,0,0));
std::auto_ptr pFormat(新的Gdiplus::StringFormat());
Gdiplus::FontFamily FontFamily;
pFont->GetFamily(&fontFamily);
std::auto_ptr pFont2(新的Gdiplus::Font(&fontFamily,pFont->GetSize(),
pFont->GetStyle(),Gdiplus::UnitPixel));
Gdiplus::unittest=pFont->GetUnit();
Gdiplus::unittest2=pFont2->GetUnit();
pFormat->SetAlignment(Gdiplus::StringAlignmentNear);
pFormat->SetLineAlignment(Gdiplus::StringAlignmentNear);
Gdiplus::StringFormatFlags flags=Gdiplus::StringFormatFlagsBypassGDI;
//flags=(Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionRightToLeft);
//flags=(Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsDirectionVertical);
//flags=(Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoWrap);
//flags=(Gdiplus::StringFormatFlags)(flags | Gdiplus::StringFormatFlagsNoClip);
p格式->设置格式标志(标志);
p格式->设置修剪(Gdiplus::StringTrimmingEllipsisCharacter);
pFormat->SetHotkeyPrefix(Gdiplus::HotkeyPrefixNone);
std::wstring text=L“这是一个示例代码”;
Gdiplus::Unit prevPageUnit=graphics.GetPageUnit();
尝试
{
graphics.SetPageUnit(Gdiplus::UnitPixel);
//绘制文本
graphics.DrawString(text.c_str()、text.length()、pFont2.get()、Gdiplus::RectF(ClientRect.Left、,
ClientRect.Top、ClientWidth、ClientHeight)、pFormat.get()、pBrush.get();
}
__最后
{
graphics.SetPageUnit(prevPageUnit);
}
//绘制文本2
graphics.DrawString(text.c_str()、text.length()、pFont.get()、Gdiplus::RectF(ClientRect.Left、,
ClientRect.Top+25,ClientWidth,ClientHeight),pFormat.get(),pBrush.get();
返回;
}
这对我来说很有用
using namespace Gdiplus;
HDC hDC = ::GetDC( NULL );
int nDPI = ::GetDeviceCaps( hDC, LOGPIXELSY );
::ReleaseDC( NULL, hDC );
REAL fFontHeight = 96 / (REAL)nDPI * 8;
FontFamily fontFamily( L"Arial" );
Gdiplus::Font font( &fontFamily, fFontHeight, UnitPixel );
REAL fMeasuredFontHeight = font.GetHeight( &gr );
事实证明,尽管Gdiplus::Font是以像素为单位指定的,但它使用用户的DPI设置来调整生成的字体(即使该字体用于绘制位图!)。标准DPI为96是一个很好的值,用于确定调整字体大小的正确比率
在上面的代码片段中,所寻求的字体高度为8像素高
通过所有DPI设置,fMeasuredFontHeight几乎保持不变(大约为12)。我想提一点,与您的问题稍微无关。您不应该再在GDI+中使用
Graphics.DrawString
。它在.NET 2中被弃用。相反,Microsoft创建了TextRenderer.DrawString
在.NET中绘制文本有两种方法:
- GDI+(
和graphics.MeasureString
)graphics.DrawString
- GDI(
和textrender.MeasureText
)textrender.DrawText
- GDI+的无状态特性导致了一些性能问题,在GDI+中,设备上下文将被设置,然后在每次调用后恢复原始上下文
- Windows/Uniscribe和Avalon(Windows Presentation Foundation)的国际文本成形引擎已多次更新,但尚未针对GDI+进行更新,这导致对新语言的国际呈现支持的质量不尽相同
graphics.DrawString
调用旧的DrawText
API而不是GDI+。但他们无法使文本的换行和间距与GDI+完全匹配。因此,他们被迫保留graphics.DrawString
来调用GDI+(兼容性原因;调用graphics.DrawString
的人会突然发现他们的文本没有以前的包装方式)
创建了一个新的静态TextRenderer
类来包装GDI文本呈现。它有两种方法:
TextRenderer.MeasureText
TextRenderer.DrawText
注意:-
TextRenderer
是GDI的包装器-
graphics.DrawString仍然是GDI的包装器+
然后是如何处理所有现有的.NET控件的问题,例如:
标签
按钮
TextBox
他们想将它们切换到使用textrender
(即GDI),但必须小心。可能有人像在.NET1.1中那样依赖于控件的绘制。于是“兼容文本呈现”诞生了
默认情况下,应用程序中的控件的行为与.NET 1.1中的控件类似(它们是“兼容的”)
您可以通过调用以下命令来关闭兼容模式:
Application.SetCompatibleTextRenderingDefault(false);
这使您的应用程序更好、更快、具有更好的i
SetCompatibleTextRenderingDefault(true) SetCompatibleTextRenderingDefault(false)
======================================= ========================================
default opt-in
bad good
the one we don't want to use the one we want to use
uses GDI+ for text rendering uses GDI for text rendering
graphics.MeasureString TextRenderer.MeasureText
graphics.DrawString TextRenderer.DrawText
Behaves same as 1.1 Behaves *similar* to 1.1
Looks better
Localizes better
Faster
TextRenderingHint mapped by TextRenderer to LOGFONT quality
======================== =========================================================
ClearTypeGridFit CLEARTYPE_QUALITY (5) (Windows XP: CLEARTYPE_NATURAL (6))
AntiAliasGridFit ANTIALIASED_QUALITY (4)
AntiAlias ANTIALIASED_QUALITY (4)
SingleBitPerPixelGridFit PROOF_QUALITY (2)
SingleBitPerPixel DRAFT_QUALITY (1)
else (e.g.SystemDefault) DEFAULT_QUALITY (0)