예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
파일: Font.cpp 프로젝트: BornHunter/CGSF
//-----------------------------------------------------------------------------
// 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;
}
예제 #6
0
/*
 *
 * 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;
}
예제 #7
0
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);
}
예제 #8
0
//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;
}
예제 #9
0
파일: cFont.cpp 프로젝트: WildeSE/D3D-Menu
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;
}
예제 #10
0
파일: disasm.c 프로젝트: DavideD/BizHawk
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;
}
예제 #11
0
파일: edit.c 프로젝트: twonds/chesspark
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);

	}
}
예제 #12
0
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;
}