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;
}
Exemple #2
0
void InitWinFonts( )
{
	INT32 FontSlot[WIN_LASTFONT];
	memset( WinFonts, 0, sizeof( WinFonts ) );
    
	GetWinFontInfo();
	
	for (int i = 0; i<WIN_LASTFONT; i++)
	{
		FontSlot[i] = CreateWinFont(FontInfo[i].LogFont);
		SetWinFontForeColor(FontSlot[i], &FontInfo[i].Color);
	}

	//can't use switch here, because FONT12ARIAL, LARGEFONT1... are variables
	for (int i=0; i<MAX_WINFONTMAP; i++)
		{
		 if (i == FONT12ARIAL)
		   {WinFontMap[i] = FontSlot[WIN_12POINTARIAL];}
		 else if (i == LARGEFONT1)
		   {WinFontMap[i] = FontSlot[WIN_LARGEFONT1];}
		 else if (i == SMALLFONT1)
		   {WinFontMap[i] = FontSlot[WIN_SMALLFONT1];}
		 else if  (i == TINYFONT1)
		   {WinFontMap[i] = FontSlot[WIN_TINYFONT1];}
		 else if  (i == FONT12POINT1)
		   {WinFontMap[i] = FontSlot[WIN_12POINTFONT1];}
		 else if  (i == COMPFONT)
		   {WinFontMap[i] = FontSlot[WIN_COMPFONT];}
		 else if  (i == SMALLCOMPFONT)
		   {WinFontMap[i] = FontSlot[WIN_SMALLCOMPFONT];}
		 else if  (i == FONT10ROMAN)
		   {WinFontMap[i] = FontSlot[WIN_10POINTROMAN];}
		 else if  (i == FONT12ROMAN)
		   {WinFontMap[i] = FontSlot[WIN_12POINTROMAN];}
		 else if  (i == FONT14SANSERIF)
		   {WinFontMap[i] = FontSlot[WIN_14POINTSANSSERIF];}
		 else if  (i == MILITARYFONT1)
		   {WinFontMap[i] = FontSlot[WIN_BLOCKYFONT];}
		 else if  (i == FONT10ARIAL)
		   {WinFontMap[i] = FontSlot[WIN_10POINTARIAL];}
		 else if  (i == FONT14ARIAL)
		   {WinFontMap[i] = FontSlot[WIN_14POINTARIAL];}
		 else if  (i == FONT10ARIALBOLD)
		   {WinFontMap[i] = FontSlot[WIN_10POINTARIALBOLD];}
		 else if  (i == BLOCKFONT)
		   {WinFontMap[i] = FontSlot[WIN_BLOCKYFONT];}
		 else if  (i == BLOCKFONT2)
		   {WinFontMap[i] = FontSlot[WIN_BLOCKYFONT2];}
		 else if  (i == FONT12ARIALFIXEDWIDTH)
		   {WinFontMap[i] = FontSlot[WIN_12POINTARIALFIXEDFONT];}
		 else if  (i == FONT16ARIAL)
		   {WinFontMap[i] = FontSlot[WIN_16POINTARIAL];}
		 else if  (i == BLOCKFONTNARROW)
		   {WinFontMap[i] = FontSlot[WIN_BLOCKFONTNARROW];}
		 else if  (i == FONT14HUMANIST)
		   {WinFontMap[i] = FontSlot[WIN_14POINTHUMANIST];}
		 else {WinFontMap[i] = -1;}
		}
}
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 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;
		}
	}
}