【发布时间】:2017-03-06 19:15:39
【问题描述】:
我的应用程序中有一些代码可以选择字体。它直观地显示了当前字体的示例:
代码在这里:
void CExportSettingsDlg::OnPaint()
{
CPaintDC dc( this ); // device context for painting
// This will draw the sample text for us using the current font
DrawSampleText( &dc );
// Do not call CDialog::OnPaint() for painting messages
}
void CExportSettingsDlg::DrawSampleText(CDC *pDC)
{
CDC dcMem;
CPen *pOldPen;
CBrush *pOldBrush;
CBitmap *pBmpOld;
CFont *pOldFont, fntSample;
LOGFONT lfSampleFont;
int nFontHeightPixels, iBackModeOld;
COLORREF crTextColourOld;
CString strSample;
ASSERT( pDC != NULL );
ASSERT( m_plfCurrentFont != NULL );
if( pDC != NULL && m_plfCurrentFont != NULL )
{
strSample.LoadString( IDS_STR_SAMPLE );
dcMem.CreateCompatibleDC( NULL );
// Select our gdi stuff into dc
pBmpOld = (CBitmap*)dcMem.SelectObject( &m_bmpSample );
pOldPen = (CPen*)dcMem.SelectStockObject( BLACK_PEN );
pOldBrush = (CBrush*)dcMem.SelectStockObject( WHITE_BRUSH );
// Create the font
fntSample.CreateFontIndirect( m_plfCurrentFont );
// Get it back out so that we can adjust the font size correctly
fntSample.GetLogFont( &lfSampleFont );
// Font height in pixels
nFontHeightPixels = theApp.GetFontHeightPixels(lfSampleFont.lfHeight, &dcMem);
// Update font
lfSampleFont.lfHeight = nFontHeightPixels;
fntSample.DeleteObject();
fntSample.CreateFontIndirect( &lfSampleFont );
// Erase display (will draw white rectangle with black border)
dcMem.Rectangle( m_rctSampleMem );
// Select our font and colour values and modes
pOldFont = (CFont*)dcMem.SelectObject( &fntSample );
crTextColourOld = dcMem.SetTextColor( m_crCurrentFontColour );
iBackModeOld = dcMem.SetBkMode( TRANSPARENT );
// Display the text
dcMem.DrawText( strSample, m_rctSampleText, DT_SINGLELINE|DT_VCENTER|DT_CENTER );
// Blast main memory dc to display
pDC->BitBlt( m_rctSample.left, m_rctSample.top,
m_rctSample.Width(), m_rctSample.Height(),
&dcMem, 0, 0, SRCCOPY );
// Restore old font and colour values and modes
dcMem.SelectObject( pOldFont );
dcMem.SetTextColor( crTextColourOld );
dcMem.SetBkMode( iBackModeOld );
dcMem.SelectObject( pBmpOld );
dcMem.SelectObject( pOldPen );
dcMem.SelectObject( pOldBrush );
// Release memory
dcMem.DeleteDC();
fntSample.DeleteObject();
// brushes and pens don't need deleting as they are stock objects
}
}
现在,我有其他代码显示标准 CFontDialog,用户还可以在其中设置字体颜色:
如您所见,在此对话框中,它使用透明背景作为字体示例,因此显示白色文本。但公平地说,由于我使用的蒙皮,它显示得更多。
在我的窗口上,我使用的是白色背景。所以你看到了我的问题。仅此而已。你看不到。 :)
没有变得复杂,并且考虑到我是色盲(红色/绿色)的事实,我们可以使用一种简单的技术来始终确保 my 示例中的示例背景始终适合给定正在渲染的字体颜色?
谢谢。
【问题讨论】:
-
可能相关:Formula to determine brightness of RGB color。使用白色背景,只要字体亮度在下半部分,从 0.5 开始切换到黑色背景。我相信 Windows 使用类似的方案来决定桌面快捷方式项目文本的颜色。
-
@IInspectable 这个问题有很多答案,其中大部分都超出了我的想象。我理解你所描述的,但是哪个答案可以做到这一点?
-
接受答案的所有公式都可以使用。我可能会选择第一个或第二个,因为它们更容易计算。它们采用 RGB 值(您的字体颜色)并计算 [0 .. 1] 范围内的单个亮度值(0 为暗,1 为亮)。使用该值来决定背景:从 [0 .. 0.5) 的值使用明亮的背景,从 [0.5 .. 1] 的值使用深色背景。
-
假设您不处理透明度,您是否考虑过使用与前景色按位相反的 RGB 颜色作为背景?它可以制作一些生动的背景。
-
假设 rgbfg 是前景色。 DWORD rgbbg = (~rgbfg) & 0x00ffffff;或多或少...