static HENHMETAFILE create_emf(void) { const RECT rect = {0, 0, 100, 100}; HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Marshaling Test\0Test\0\0"); ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL); return CloseEnhMetaFile(hdc); }
static HMETAFILE create_mf(void) { RECT rect = {0, 0, 100, 100}; HDC hdc = CreateMetaFileA(NULL); ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL); return CloseMetaFile(hdc); }
static void MDescButton_FillRect(HDC hdc, int x, int y, int width, int height, COLORREF cl) { int oldMode = SetBkMode(hdc, OPAQUE); COLORREF oldColor = SetBkColor(hdc, cl); RECT rc; SetRect(&rc, x, y, x + width, y + height); ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); SetBkMode(hdc, oldMode); SetBkColor(hdc, oldColor); }
static void vprint(int x, int y, int w, char *format, va_list va) { HDC dc = GetDC(wnd); RECT rc; rc.top = y; rc.bottom = y+16; rc.left = x - w/2; rc.right = rc.left + w; char buf[128]; int n = vsprintf(buf, format, va); SetTextAlign(dc, TA_CENTER); ExtTextOutA(dc, x, y, ETO_OPAQUE, &rc, buf, n, 0); ReleaseDC(wnd, dc); }
//----------------------------------------------------------------------------- // Prepares the font by drawing all the characters on the device context. //----------------------------------------------------------------------------- bool Font::PrepareFont( HDC hDC, bool measure ) { SIZE size; char string[2]; // Find the spacing between the characters based on the line height. if( GetTextExtentPoint32A( hDC, string, 1, &size ) == 0 ) return false; m_spacing = (short)ceil( size.cy * 0.1f ); // Set the position to start drawing at. unsigned long x = m_spacing; unsigned long y = 0; // Draw each character on the DC and move to the next position. for( char c = 32; c < 127; c++ ) { string[0] = c; if( GetTextExtentPoint32A( hDC, string, 1, &size ) == 0 ) return false; if( (unsigned long)( x + size.cx + m_spacing ) > m_textureWidth ) { x = m_spacing; y += size.cy + 1; } // Ensure there is enough room to draw the character. if( y + size.cy > m_textureHeight ) return false; // Draw the character if not measuring. if( !measure ) { if( ExtTextOutA( hDC, x + 0, y + 0, ETO_OPAQUE, NULL, string, 1, NULL ) == 0 ) return false; m_textureCoords[c - 32][0] = (float)( x - m_spacing ) / m_textureWidth; m_textureCoords[c - 32][1] = (float)( y ) / m_textureHeight; m_textureCoords[c - 32][2] = (float)( x + size.cx + m_spacing ) / m_textureWidth; m_textureCoords[c - 32][3] = (float)( y + size.cy ) / m_textureHeight; } x += size.cx + ( 2 * m_spacing ); } return true; }
/* * * prochooking shadow functions, function calls to the associated API functions get redirected here * */ BOOL WINAPI ShadowExtTextOutA(HDC textdc, int x, int y, UINT fuoptions, CONST RECT *lprc, LPCSTR lptext, UINT cb, CONST INT *lpdx) { BOOL bRet = FALSE; // write to text buffer if it isnt a glyph if ((fuoptions & ETO_GLYPH_INDEX) != ETO_GLYPH_INDEX) { WriteToTextBuffer(lptext, cb); } // pass on call to real function UnhookFunction((PHOOKREC)&_hrExtTextOutA); bRet = ExtTextOutA(textdc, x, y, fuoptions, lprc, lptext, cb, lpdx); HookFunction((PHOOKREC)&_hrExtTextOutA); return bRet; }
static void MDescButton_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1) { int oldMode = SetBkMode(hdc, OPAQUE); COLORREF oldColor = SetBkColor(hdc, 0); RECT rc; SetRect(&rc, x, 0, x + width, 0); for (int i = y + height; --i >= y;) { COLORREF color = RGB( ((height - i - 1)*rgb0->rgbRed + i*rgb1->rgbRed) / height, ((height - i - 1)*rgb0->rgbGreen + i*rgb1->rgbGreen) / height, ((height - i - 1)*rgb0->rgbBlue + i*rgb1->rgbBlue) / height); rc.top = rc.bottom = i; ++rc.bottom; SetBkColor(hdc, color); ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); } SetBkMode(hdc, oldMode); SetBkColor(hdc, oldColor); }
//Hook TextOutA的过程 DLLEXPORT BOOL WINAPI NHExtTextOutA(HDC hdc, int X, //当前需要绘制的文本的起始位置 int Y, UINT fuOptions, CONST RECT *lprc, LPCTSTR lpString, UINT cbCount, CONST INT *lpDx) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; // restore RestoreWin32Api(&g_ExtTextOutAHook, HOOK_NEED_CHECK); /* if (cbCount != 0) { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHExtTextOutA : %s (%s) (%d)\n", "start", lpString, cbCount); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHExtTextOutA : lpString(%s), cbCount(%d)\n", lpString, cbCount); pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); hWPT = WindowFromPoint(pt); dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); dwThreadIdCurr = GetCurrentThreadId(); if(dwThreadIdWithPoint == dwThreadIdCurr) { if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbCount)) && (cbCount > 0)) { g_nTextAlign = GetTextAlign(hdc); g_nExtra = GetTextCharacterExtra(hdc); GetCurrentPositionEx(hdc, &g_CurPos); GetTextMetrics(hdc, &g_tm); g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; //findword.c中的代码,取出当前字符的矩形范围 GetStringRect(hdc, (LPSTR)lpString, cbCount, X, Y, &g_rcTotalRect, lpDx); bRecAllRect = TRUE; if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; AddToTextOutBuffer(hdc, (LPSTR)lpString, cbCount, X, Y, lpDx); } else { GetDCOrgEx(hdc, &g_dwDCOrg); //findword.c中的代码,取出当前位置下的单词 GetCurMousePosWord(hdc, (LPSTR)lpString, cbCount, X, Y, lpDx); } } } } // call ExtTextOutA ExtTextOutA(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); HookWin32Api(&g_ExtTextOutAHook, HOOK_NEED_CHECK); return TRUE; }
HRESULT cFont::InitDeviceObjects(LPDIRECT3DDEVICE9 pDevice) { HRESULT hr; this->m_pDevice= pDevice; m_fTextScale = 1.0f; if (dwFontHeight > 40)dwWidth = dwHeight = 1024; else if (dwFontHeight > 20)dwWidth = dwHeight = 512; else dwWidth = dwHeight = 256; D3DCAPS9 d3dCaps; pDevice->GetDeviceCaps(&d3dCaps); if (dwWidth > d3dCaps.MaxTextureWidth) { m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)dwWidth; dwWidth =dwHeight = d3dCaps.MaxTextureWidth; } hr = pDevice->CreateTexture(dwWidth, dwHeight, 1,0, D3DFMT_A4R4G4B4,D3DPOOL_MANAGED, &m_pTexture, 0); if (FAILED(hr))return hr; DWORD* pBitmapBits; BITMAPINFO bmi; ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)dwWidth; bmi.bmiHeader.biHeight = -(int)dwHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; HDC hDC = CreateCompatibleDC(NULL); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0); SetMapMode(hDC, MM_TEXT); INT nHeight = -MulDiv(dwFontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72); DWORD dwBold = (dwFontFlags & D3DFONT_BOLD) ? FW_EXTRABOLD : FW_NORMAL; DWORD dwItalic = (dwFontFlags & D3DFONT_ITALIC) ? TRUE : FALSE; HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, strFontName); if (NULL == hFont) return E_FAIL; HGDIOBJ hPrevBitmap = SelectObject(hDC, hbmBitmap); HGDIOBJ hPrevFont = SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255, 255, 255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); DWORD x = 0; DWORD y = 0; char str[2] = "x"; SIZE size; for (int c = 32; c <= MAX_CHAR_INDEX; c++) { str[0] = c; GetTextExtentPoint32A(hDC, str, 1, &size); if ((DWORD)(x + size.cx + 1) > dwWidth) { x = 0; y += size.cy + 1; } ExtTextOutA(hDC, x + 0, y + 0, ETO_OPAQUE, NULL, str, 1, NULL); m_fTexCoords[c - 32][0] = ((FLOAT)(x + 0)) / dwWidth; m_fTexCoords[c - 32][1] = ((FLOAT)(y + 0)) / dwWidth; m_fTexCoords[c - 32][2] = ((FLOAT)(x + 0 + size.cx)) / dwWidth; m_fTexCoords[c - 32][3] = ((FLOAT)(y + 0 + size.cy)) / dwWidth; x += size.cx + 1; } D3DLOCKED_RECT d3dlr; m_pTexture->LockRect(0, &d3dlr, 0, 0); BYTE* pDstRow = (BYTE*)d3dlr.pBits; WORD* pDst16; BYTE bAlpha; for (y = 0; y < dwHeight; y++) { pDst16 = (WORD*)pDstRow; for (x = 0; x < dwWidth; x++) { bAlpha = (BYTE)((pBitmapBits[dwWidth*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (bAlpha << 12) | 0x0fff; } else { *pDst16++ = 0x0000; } } pDstRow += d3dlr.Pitch; } m_pTexture->UnlockRect(0); SelectObject(hDC, hPrevBitmap); SelectObject(hDC, hPrevFont); DeleteObject(hbmBitmap); DeleteDC(hDC); DeleteObject(hFont); return S_OK; }
LRESULT DisasmCtl_OnPaint(DisasmCtl_struct *cc, WPARAM wParam, LPARAM lParam) { HDC hdc=(HDC)wParam; PAINTSTRUCT ps; RECT rect; HANDLE oldfont; int x=0, y=0; char text[MAX_PATH]; u32 addr; SIZE size; RECT clip; int curaddr=-1; BOOL ispc; addr = cc->addr; // Setup everything for rendering if (hdc == NULL) hdc = BeginPaint(cc->hwnd, &ps); oldfont = SelectObject(hdc, cc->font); GetClientRect(cc->hwnd, &rect); for(;;) { ispc = (addr == cc->pc) ? TRUE : FALSE; x = 0; addr += cc->disinst(addr, text); GetTextExtentPoint32A(hdc, text, (int)strlen(text), &size); if (size.cy+y >= rect.bottom) break; // adjust clipping values if (y+(size.cy*2) >= rect.bottom) clip.bottom = rect.bottom; else clip.bottom = y+size.cy; // Draw the address text clip.left = x; clip.top = y; clip.right = rect.right; if (ispc) { SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); } else { SetTextColor(hdc, cc->text_color); SetBkColor(hdc, cc->bg_color); } ExtTextOutA(hdc, x, y, ETO_OPAQUE | ETO_CLIPPED, &clip, text, strlen(text), 0); y += size.cy; } // Let's clean up, and we're done SelectObject(hdc, oldfont); if ((HDC)wParam == NULL) EndPaint(cc->hwnd, &ps); return FALSE; }
void EditBox_OnPaint(struct Box_s *pbox, HDC hdc, RECT rcClip, int x, int y, int paintmask) { struct editboxdata_s *data = pbox->boxdata; struct Box_s *child = pbox->child; RECT rcBox, rc; /* If box is not visible, punt */ if (!(pbox->flags & BOX_VISIBLE)) { return; } /* Set up the box rect */ rcBox.left = x; rcBox.top = y; rcBox.right = rcBox.left + pbox->w - 1; rcBox.bottom = rcBox.top + pbox->h - 1; /* Clip the box rect against the draw rect */ rc.left = MAX(rcBox.left, rcClip.left); rc.right = MIN(rcBox.right, rcClip.right); rc.top = MAX(rcBox.top, rcClip.top); rc.bottom = MIN(rcBox.bottom, rcClip.bottom); /* If nothing to draw, punt */ if ((rc.right <= rc.left) || (rc.bottom <= rc.top)) { return; } Box_OnPaint(pbox, hdc, rcClip, x, y, paintmask); if (data->text) { COLORREF oldfgcol; int oldbkmode; HFONT oldfont; RECT draw = rcBox; WCHAR firsthalf[1024], *secondhalf; RECT measure = rcBox; int pass = 0, xtext; oldbkmode = SetBkMode(hdc, TRANSPARENT); oldfgcol = SetTextColor(hdc, pbox->fgcol); if (pbox->font) { oldfont = SelectObject(hdc, pbox->font); } else { oldfont = SelectObject(hdc, tahoma11_f); } pass = data->curpos - data->curpos % 40; if (data->hidetext) { int i; for (i = 0; i < data->curpos - pass; i++) { firsthalf[i] = L'*'; } firsthalf[i] = 0; secondhalf = malloc((wcslen(data->text + data->curpos) + 1) * sizeof(WCHAR)); for (i = 0; i < (int)wcslen(data->text + data->curpos); i++) { secondhalf[i] = L'*'; } secondhalf[i] = 0; } else { wcsncpy(firsthalf, data->text + pass, data->curpos - pass); firsthalf[data->curpos - pass] = 0; secondhalf = data->text + data->curpos; } if (Util_OldWinVer()) { char *ansifirst = Util_ConvertWCHARToANSI(firsthalf); char *ansisecond = Util_ConvertWCHARToANSI(secondhalf); measure.right = measure.left; DrawTextA(hdc, ansifirst, (int)strlen(ansifirst), &measure, DT_CALCRECT | DT_NOPREFIX); ExtTextOutA(hdc, draw.left + 2, draw.top + 2, ETO_CLIPPED, &rc, ansifirst, (UINT)strlen(ansifirst), NULL); xtext = draw.left + 2 + measure.right - measure.left; if (Box_HasFocus(pbox)) { MoveToEx(hdc, xtext, draw.top + 2, NULL); LineTo(hdc, xtext, draw.top + 18); } ExtTextOutA(hdc, xtext, draw.top + 2, ETO_CLIPPED, &rc, ansisecond, (UINT)strlen(ansisecond), NULL); if (pbox->font) { SelectObject(hdc, oldfont); } SetBkMode(hdc, oldbkmode); SetTextColor(hdc, oldfgcol); } else { measure.right = measure.left; DrawTextW(hdc, firsthalf, (int)wcslen(firsthalf), &measure, DT_CALCRECT | DT_NOPREFIX); ExtTextOutW(hdc, draw.left + 2, draw.top + 2, ETO_CLIPPED, &rc, firsthalf, (UINT)wcslen(firsthalf), NULL); xtext = draw.left + 2 + measure.right - measure.left; if (Box_HasFocus(pbox)) { MoveToEx(hdc, xtext, draw.top + 2, NULL); LineTo(hdc, xtext, draw.top + 18); } ExtTextOutW(hdc, xtext, draw.top + 2, ETO_CLIPPED, &rc, secondhalf, (UINT)wcslen(secondhalf), NULL); } if (pbox->font) { SelectObject(hdc, oldfont); } SetBkMode(hdc, oldbkmode); SetTextColor(hdc, oldfgcol); } }
int CD3DFont::Init() { // Create vertex buffer for the letters HRESULT hr; // Prepare to create a bitmap unsigned int* pBitmapBits; BITMAPINFO bmi; ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)m_dwTexWidth; bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a DC and a bitmap for the font HDC hDC = CreateCompatibleDC(nullptr); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, nullptr, 0); SetMapMode(hDC, MM_TEXT); // create a GDI font HFONT hFont = CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, _T("Tahoma")); if (nullptr == hFont) return E_FAIL; HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap); HGDIOBJ hOldFont = SelectObject(hDC, hFont); // Set text properties SetTextColor(hDC, 0xFFFFFF); SetBkColor(hDC, 0); SetTextAlign(hDC, TA_TOP); TEXTMETRICW tm; GetTextMetricsW(hDC, &tm); m_LineHeight = tm.tmHeight; // Loop through all printable characters and output them to the bitmap // Meanwhile, keep track of the corresponding tex coords for each character. int x = 0, y = 0; char str[2] = "\0"; for (int c = 0; c < 127 - 32; c++) { str[0] = c + 32; SIZE size; GetTextExtentPoint32A(hDC, str, 1, &size); if ((int)(x + size.cx + 1) > m_dwTexWidth) { x = 0; y += m_LineHeight; } ExtTextOutA(hDC, x + 1, y + 0, ETO_OPAQUE | ETO_CLIPPED, nullptr, str, 1, nullptr); m_fTexCoords[c][0] = ((float)(x + 0)) / m_dwTexWidth; m_fTexCoords[c][1] = ((float)(y + 0)) / m_dwTexHeight; m_fTexCoords[c][2] = ((float)(x + 0 + size.cx)) / m_dwTexWidth; m_fTexCoords[c][3] = ((float)(y + 0 + size.cy)) / m_dwTexHeight; x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i) } // Create a new texture for the font // possible optimization: store the converted data in a buffer and fill the texture on creation. // That way, we can use a static texture ID3D11Texture2D* buftex; D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(D3D::GetBaseBufferFormat(), m_dwTexWidth, m_dwTexHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); hr = device->CreateTexture2D(&texdesc, nullptr, &buftex); if (FAILED(hr)) { PanicAlert("Failed to create font texture"); return hr; } D3D::SetDebugObjectName(buftex, "texture of a CD3DFont object"); // Lock the surface and write the alpha values for the set pixels D3D11_MAPPED_SUBRESOURCE texmap; hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap); if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__); for (y = 0; y < m_dwTexHeight; y++) { u32* pDst32 = (u32*)((u8*)texmap.pData + y * texmap.RowPitch); for (x = 0; x < m_dwTexWidth; x++) { const u8 bAlpha = (pBitmapBits[m_dwTexWidth * y + x] & 0xff); *pDst32++ = (((bAlpha << 4) | bAlpha) << 24) | 0xFFFFFF; } } // Done updating texture, so clean up used objects context->Unmap(buftex, 0); hr = D3D::device->CreateShaderResourceView(buftex, nullptr, ToAddr(m_pTexture)); if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__); SAFE_RELEASE(buftex); SelectObject(hDC, hOldbmBitmap); DeleteObject(hbmBitmap); SelectObject(hDC, hOldFont); DeleteObject(hFont); // setup device objects for drawing m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader); if (m_pshader == nullptr) PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__); D3D::SetDebugObjectName(m_pshader.get(), "pixel shader of a CD3DFont object"); D3DBlob vsbytecode; D3D::CompileShader(DX11::D3D::ShaderType::Vertex, fontvertshader, vsbytecode); if (vsbytecode.Data() == nullptr) PanicAlert("Failed to compile vertex shader, %s %d\n", __FILE__, __LINE__); m_vshader = D3D::CreateVertexShaderFromByteCode(vsbytecode); if (m_vshader.get() == nullptr) PanicAlert("Failed to create vertex shader, %s %d\n", __FILE__, __LINE__); D3D::SetDebugObjectName(m_vshader.get(), "vertex shader of a CD3DFont object"); const D3D11_INPUT_ELEMENT_DESC desc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode.Data(), vsbytecode.Size(), ToAddr(m_InputLayout)); if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); D3D11_BLEND_DESC blenddesc; blenddesc.AlphaToCoverageEnable = FALSE; blenddesc.IndependentBlendEnable = FALSE; blenddesc.RenderTarget[0].BlendEnable = TRUE; blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; hr = D3D::device->CreateBlendState(&blenddesc, ToAddr(m_blendstate)); CHECK(hr == S_OK, "Create font blend state"); D3D::SetDebugObjectName(m_blendstate.get(), "blend state of a CD3DFont object"); D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false); hr = D3D::device->CreateRasterizerState(&rastdesc, ToAddr(m_raststate)); CHECK(hr == S_OK, "Create font rasterizer state"); D3D::SetDebugObjectName(m_raststate.get(), "rasterizer state of a CD3DFont object"); D3D11_BUFFER_DESC vbdesc = CD3D11_BUFFER_DESC(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); if (FAILED(hr = device->CreateBuffer(&vbdesc, nullptr, ToAddr(m_pVB)))) { PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__); return hr; } D3D::SetDebugObjectName(m_pVB.get(), "vertex buffer of a CD3DFont object"); return S_OK; }