void CBFontTT::DrawTextDD(BYTE* Text, int X, int Y, int Width, TTextAlign Align, int MaxHeight, int MaxLength) { CBRenderDD* m_Renderer = (CBRenderDD*)Game->m_Renderer; if(FAILED(CreateWinFont())) return; HDC hDC; m_Renderer->m_BackBuffer->GetDC(&hDC); HFONT OldFont = (HFONT)SelectObject(hDC, m_HFont); ::SetBkMode(hDC, TRANSPARENT); int TextX = 0; SetTextAlign(hDC, Align, Width, &TextX); BYTE* ConvertedText = CBTextUtils::ConvertToNative(Game->m_TextEncoding, Text, MaxLength); for(int i=0; i<m_Layers.GetSize(); i++) { ::SetTextColor(hDC, CBUtils::D3D2COLORREF(m_Layers[i]->m_Color)); FormatText(X + TextX+m_Layers[i]->m_OffsetX, Y+m_Layers[i]->m_OffsetY, ConvertedText, hDC, Width, MaxHeight); } ::SelectObject(hDC, OldFont); m_Renderer->m_BackBuffer->ReleaseDC(hDC); DeleteWinFont(); delete [] ConvertedText; }
CBFontTT::~CBFontTT(void) { DeleteWinFont(); ClearCache(); int i; for(i=0; i<m_Layers.GetSize(); i++) { delete m_Layers[i]; } m_Layers.RemoveAll(); SAFE_DELETE_ARRAY(m_Typeface); SAFE_DELETE_ARRAY(m_FontFile); }
int CBFontTT::GetLetterHeight() { if(FAILED(CreateWinFont())) return 0; HDC hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); HGDIOBJ OldFont = SelectObject(hDC, m_HFont); SIZE Size; GetTextExtentPoint32(hDC, "Ay", 2, &Size); ::SelectObject(hDC, OldFont); DeleteDC(hDC); DeleteWinFont(); return Size.cy; }
int CBFontTT::GetTextHeight(BYTE* Text, int Width) { if(FAILED(CreateWinFont())) return 0; HDC hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); HGDIOBJ OldFont = SelectObject(hDC, m_HFont); BYTE* ConvertedText = CBTextUtils::ConvertToNative(Game->m_TextEncoding, Text); int Ret = FormatText(0, 0, ConvertedText, hDC, Width, -1); delete [] ConvertedText; ::SelectObject(hDC, OldFont); DeleteDC(hDC); DeleteWinFont(); return Ret; }
int CBFontTT::GetTextWidth(BYTE* Text, int MaxLength) { int Ret = 0; if(FAILED(CreateWinFont())) return 0; HDC hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); HGDIOBJ OldFont = SelectObject(hDC, m_HFont); BYTE* ConvertedText = CBTextUtils::ConvertToNative(Game->m_TextEncoding, Text); if(Game->m_TextEncoding==TEXT_ANSI) { SIZE Size; int Length = strlen((char*)ConvertedText); GetTextExtentPoint32(hDC, (char*)ConvertedText, Length, &Size); Ret = Size.cx; } else if(Game->m_TextEncoding==TEXT_UTF8) { SIZE Size; int Length = wcslen((wchar_t*)ConvertedText); GetTextExtentPoint32W(hDC, (wchar_t*)ConvertedText, Length, &Size); Ret = Size.cx; } delete [] ConvertedText; ::SelectObject(hDC, OldFont); DeleteDC(hDC); DeleteWinFont(); return Ret; }
void ShutdownWinFonts( ) { for (int i=0; i<MAX_WINFONTMAP; i++) {DeleteWinFont(i);} }
void CBFontTT::DrawTextD3D(BYTE* Text, int X, int Y, int Width, TTextAlign Align, int MaxHeight, int MaxLength) { CBRenderD3D* m_Renderer = (CBRenderD3D*)Game->m_Renderer; // find cached surface, if exists int MinPriority = INT_MAX; int MaxPriority = 0; int MinIndex = -1; CBSurface* Surface = NULL; for(int i=0; i<NUM_CACHED_TEXTS; i++) { if(m_CachedTexts[i]==NULL) { MinPriority = 0; MinIndex = i; } else { MaxPriority = max(MaxPriority, m_CachedTexts[i]->m_Priority); if(strcmp(m_CachedTexts[i]->m_Text, (char*)Text)==0 && m_CachedTexts[i]->m_Align==Align && m_CachedTexts[i]->m_Width==Width && m_CachedTexts[i]->m_MaxHeight==MaxHeight && m_CachedTexts[i]->m_MaxLength==MaxLength) { Surface = m_CachedTexts[i]->m_Surface; m_CachedTexts[i]->m_Priority++; break; } else { if(m_CachedTexts[i]->m_Priority < MinPriority) { MinPriority = m_CachedTexts[i]->m_Priority; MinIndex = i; } } } } // not found, create one if(!Surface) { if(FAILED(CreateWinFont())) return; HDC hDC = ::CreateCompatibleDC(NULL); ::SetMapMode(hDC, MM_TEXT); HFONT OldFont = (HFONT)::SelectObject(hDC, m_HFont); ::SetTextColor(hDC, RGB(255,255,255)); ::SetBkColor(hDC, 0x00000000); int TextX = 0; SetTextAlign(hDC, Align, Width, &TextX); BYTE* ConvertedText = CBTextUtils::ConvertToNative(Game->m_TextEncoding, Text, MaxLength); //ExtTextOut(hDC, 0, 0, ETO_OPAQUE, NULL, (char*)Text, strlen((char*)Text), NULL); int Height = FormatText(TextX, 0, ConvertedText, hDC, Width, MaxHeight); Height = max(Height, 1); DWORD* BitmapBits; BITMAPINFO bmi; memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)Width; bmi.bmiHeader.biHeight = -(int)Height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; HBITMAP hbmBitmap = ::CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&BitmapBits, NULL, 0); HBITMAP OldBitmap = (HBITMAP)::SelectObject(hDC, hbmBitmap); FormatText(TextX, 0, ConvertedText, hDC, Width, MaxHeight); CBImage* Image = new CBImage(Game); Image->CreateFromRaw(BitmapBits, Width, Height); Surface = Image->CreateSurface(); delete Image; ::SelectObject(hDC, OldBitmap); ::SelectObject(hDC, OldFont); ::DeleteObject(hbmBitmap); ::DeleteDC(hDC); DeleteWinFont(); delete [] ConvertedText; // write surface to cache if(m_CachedTexts[MinIndex]!=NULL) delete m_CachedTexts[MinIndex]; m_CachedTexts[MinIndex] = new CBCachedTTFontText; m_CachedTexts[MinIndex]->m_Surface = Surface; m_CachedTexts[MinIndex]->m_Align = Align; m_CachedTexts[MinIndex]->m_Width = Width; m_CachedTexts[MinIndex]->m_MaxHeight = MaxHeight; m_CachedTexts[MinIndex]->m_MaxLength = MaxLength; m_CachedTexts[MinIndex]->m_Priority = MaxPriority + 1; CBUtils::SetString(&m_CachedTexts[MinIndex]->m_Text, (char*)Text); } // and paint it if(Surface) { RECT rc; SetRect(&rc, 0, 0, Surface->GetWidth(), Surface->GetHeight()); for(int i=0; i<m_Layers.GetSize(); i++) { DWORD Color = m_Layers[i]->m_Color; DWORD OrigForceAlpha = m_Renderer->m_ForceAlphaColor; if(m_Renderer->m_ForceAlphaColor!=0) { Color = DRGBA(D3DCOLGetR(Color), D3DCOLGetG(Color), D3DCOLGetB(Color), D3DCOLGetA(m_Renderer->m_ForceAlphaColor)); m_Renderer->m_ForceAlphaColor = 0; } Surface->DisplayTrans(X+m_Layers[i]->m_OffsetX, Y+m_Layers[i]->m_OffsetY, rc, Color); m_Renderer->m_ForceAlphaColor = OrigForceAlpha; } } }