ClearType会破坏透明度 [英] ClearType ruins transparency

查看:78
本文介绍了ClearType会破坏透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个位图,其背景需要替换为另一个位图的一部分。一切正常,直到我在 WindowsXP 上启用 ClearFont



为了更好地解释我的问题,让我们将第一个位图标记为 bmpDestination ,然后将第二个位图标记为 bmpSource



此处 [ ^ ]是 bmpSource 的样子。



这里 [ ^ ]是 bmpDestination 的样子。



此处 [ ^ ClearType 打开时,>]是他们合并的错误结果。



ClearType 改变了某些部分文字背景颜色,所以它们不是白色的不再( RGB(255,255,255))但是白色和文字颜色的组合。



我我正在使用 BitBlt()单色位图来创建掩码,并模拟透明度。我也尝试过使用 TransparentBlt(),但结果相同。



如何组合 bmpSource bmpDestination ,当启用 ClearType 时,我可以创建正确的结果吗?



感谢您的帮助。



祝你好运。

I have a bitmap which background needs to be replaced with part of another bitmap. Everything works fine until I enable ClearFont on my WindowsXP.

In order to explain my problem better, let us label first bitmap as bmpDestination and second as bmpSource.

Here[^] is how the bmpSource looks like.

Here[^] is how bmpDestination looks like.

And here[^] is the incorrect result of their combining when ClearType is on.

ClearType alters some parts of the text background color, so they aren't white anymore ( RGB( 255, 255, 255 ) ) but a combination of white and text color.

I am using BitBlt() and monochrome bitmap to create a mask, and to simulate transparency. I have tried using TransparentBlt() too, but got the same result.

How can I combine bmpSource and bmpDestination, when ClearType is enabled, so I can create correct result ?

Thank you for your help.

Best regards.

推荐答案

我把它添加到你以前的帖子里它很乱,所以你可能错过了它。



有很多方法可以解决它但它们都很慢并且有所不同您必须在两者之间进行选择的结果。没有完美的解决方案,因为它是Windows Cleartype实现中的一个错误或过度瞄准。



我玩过,我得出了与此作者完全相同的结论< br $> b $ b

http://theartofdev.wordpress.com/2014/04/21/text-rendering-methods-comparison-or-gdi-vs-gdi-revised/ [ ^ ]



I added this to your previous post it got messy so you probably missed it.

There are ways around it but they are all slow and give different results which you have to choose between. There is no perfect solution because it is a bug or over-sight in windows Cleartype implementation.

I played around and I came to the exact same conclusions as this author

http://theartofdev.wordpress.com/2014/04/21/text-rendering-methods-comparison-or-gdi-vs-gdi-revised/[^]

Conclusions

-GDI text rendering provides the best visual quality but doesn’t support transparent background.
-Native GDI rendering provides the best performance.
-GDI+ with anti-aliasing and typographic format provides the best performance and visual quality for transparent background rendering.
-GraphicsPath rendering method visual quality4 and performance is disappointing.
-Text rendered in each rendering method is visually different.
-As Microsoft will improve their fonts and display resolution (DPI) will raise, GDI+ text rendering will improve to a point where GDI has no significant visual benefit.

I have studied carefully the code from your previous answer and managed to handle WM_WINDOWPOSCHANGED properly for multiple windows but I can not handle slight flickering.



造成闪烁的原因是列表框绘制每个项目的方式,你需要自己绘图来解决问题,列表框上有很多文章闪烁并解决它。



如果您需要窗口,可以直接添加字体...所以让我们看看具体的代码。



首先创建一个文本字符串,我们将在FONT中调用该属性


What is causing the flicker is the way the listbox draws each item you need to do you own drawing to solve the problem there are plenty of articles on listbox flicker and solving it.

Ok to do the font simply attach the font if you need to the window .. so lets look at specific code.

First make a text string we are going to call the property in out case "FONT"

//this is the property title of the FONT to attach to our window
#define TEXTPROP TEXT("FONT")



下一个句柄WM_FONT


Next handle WM_FONT

case WM_SETFONT:
LOGFONT lf;
HFONT OldFont, Newfont;
GetObject((HFONT)wParam, sizeof(lf), &lf);                  // Get proposed font
if (lf.lfQuality != NONANTIALIASED_QUALITY){                // If its antialiased we can't use
	lf.lfQuality = NONANTIALIASED_QUALITY;              // So change it to non antialiased
	Newfont = CreateFontIndirect(&lf);                  // Create a new font 
	OldFont = (HFONT) GetProp(hwnd, TEXTPROP);	    // Get the old font
	if (OldFont != 0) DeleteObject(OldFont);            // If valid delete it
	SetProp(hwnd, TEXTPROP, (HANDLE)Newfont);           // Set new font to window property
} else Newfont = (HFONT) wParam;                            // Use the font provided
return ::DefSubclassProc( hwnd, WM_SETFONT, (WPARAM)Newfont, lParam); // Treat it as usual





你有责任删除在NCDESTROY中创建的任何字体WM_SETFONT



Your responsibility to delete any font WM_SETFONT created in NCDESTROY

case WM_NCDESTROY: 
   HFONT Font = (HFONT) GetProp(hwnd, TEXTPROP);           // Fetch the font property
   if (Font != 0) DeleteObject(Font);                      // If valid delete the font 
   RemoveProp(hwnd, TEXTPROP);                             // Remove the window property   
   ::RemoveWindowSubclass(hwnd, TreeProc, 0 );
   return ::DefSubclassProc( hwnd, message, wParam, lParam);





它现在像任何普通窗口一样处理WM_FONT 。



最后我将所有创作内容放入辅助函数中



It now handles the WM_FONT like any normal window.

Finally I put all the creation stuff into a helper function

// ** LdB Consolidate function to create a listbox and do all the repeat stuff
HWND CreateListBox (HWND parent,    // Parent window to insert this control in
		    TCHAR* title,   // List box title text
		    int x, int y,   // x,y co-ordinate of parent for the insert
		    int cx, int cy, // Width and Height of the control
		    int id,	    // Id of the control
 		    HFONT hFont) {  // Handle to any special font (0 = default)
DWORD dwStyle;
HWND TreeView;
  
   TreeView = CreateWindowEx(0, WC_TREEVIEW, title, 
		WS_VISIBLE | WS_CHILD | WS_BORDER 
		| TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 
		x, y, cx, cy,	parent, (HMENU)id, 0, NULL);

   dwStyle = GetWindowLong( TreeView , GWL_STYLE);
   dwStyle |= TVS_CHECKBOXES;
   SetWindowLongPtr( TreeView , GWL_STYLE, dwStyle );
   SetWindowSubclass( TreeView, TreeProc, 0, 0 );
   TreeView_SetBkColor(TreeView, RGB(0xFF, 0, 0xFF));
   // This checks font is not aliased by our handling of WM_FONT
   if (hFont == 0) hFont = (HFONT) SendMessage(TreeView, WM_GETFONT, 0, 0);
   SendMessage(TreeView, WM_SETFONT, (WPARAM)hFont, FALSE);
   return (TreeView);
};



你的创作现在看起来很简单


Your creation now looks this simple

HWND TreeView = CreateListBox(hwnd, (TCHAR*)TEXT("Tree View"),
    50, 10, 200, 200, ID_LISTBOX, 0);


哦,我忘记了我进一步改进了你的重绘并使其符合处理WM_PRINTCLIENT本身。



Oh I forgot I further improved your redraw and made it compliant to handling WM_PRINTCLIENT itself.

case WM_PAINT:
    {
    // usual stuff
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint( hwnd, &ps );
    // Simply get printclient to paint  
    ::SendMessage(hwnd, WM_PRINTCLIENT,(WPARAM) hdc, (LPARAM)(PRF_CLIENT) ); 
    EndPaint( hwnd, &ps );
    }
    return 0L;
case WM_PRINTCLIENT:
    {
    BITMAPINFO bmi;
    // Get parent client co-ordinates
    RECT rc;
    GetClientRect(GetParent(hwnd), &rc);
    // Create a memory DC
    HDC memDC = CreateCompatibleDC(0);
    // Create a DIB header for parent
    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = rc.right - rc.left;
    bmi.bmiHeader.biHeight = rc.bottom - rc.top;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    // Create a DIB bitmap
    HBITMAP tempBmp = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, 0, 0, 0);
    // Select tempBmp onto DC to force size and DIB change on the DC
    SelectObject(memDC, tempBmp );
    // Put parent background on our memory DC
    ::SendMessage( GetParent(hwnd), WM_PRINTCLIENT, (WPARAM) memDC,  (LPARAM)(PRF_CLIENT));
    // Now we can dispose of the DIB bitmap no longer needed
    DeleteObject(tempBmp);
    // map tree's coordinates to parent window
    POINT ptTreeUL;
    ptTreeUL.x = 0;
    ptTreeUL.y = 0;
    ClientToScreen( hwnd, &ptTreeUL );
    ScreenToClient( GetParent(hwnd), &ptTreeUL );
    GetClientRect( hwnd, &rc);
    // Transfer parent background to given DC
    BitBlt((HDC)wParam, 0, 0,  rc.right-rc.left, rc.bottom-rc.top,
	memDC, ptTreeUL.x, ptTreeUL.y, SRCCOPY );
    // Okay get treeview to draw on our memory DC
    DefSubclassProc(hwnd, WM_PRINTCLIENT, (WPARAM)memDC,  (LPARAM)(PRF_CLIENT));
    // Transfer the treeview DC onto finalDC excluding pink
    TransparentBlt((HDC)wParam, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
	memDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, RGB(0xFF, 0x00, 0xFF));
    // Finished with MemDC 
    DeleteObject(memDC);
    return (0); 
}


这篇关于ClearType会破坏透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆