forked from metin2/client
315 lines
6.3 KiB
C++
315 lines
6.3 KiB
C++
|
#include "StdAfx.h"
|
|||
|
#include "GrpText.h"
|
|||
|
#include "../eterBase/Stl.h"
|
|||
|
|
|||
|
#include "Util.h"
|
|||
|
|
|||
|
CGraphicFontTexture::CGraphicFontTexture()
|
|||
|
{
|
|||
|
Initialize();
|
|||
|
}
|
|||
|
|
|||
|
CGraphicFontTexture::~CGraphicFontTexture()
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
}
|
|||
|
|
|||
|
void CGraphicFontTexture::Initialize()
|
|||
|
{
|
|||
|
CGraphicTexture::Initialize();
|
|||
|
m_hFontOld = NULL;
|
|||
|
m_hFont = NULL;
|
|||
|
m_isDirty = false;
|
|||
|
m_bItalic = false;
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::IsEmpty() const
|
|||
|
{
|
|||
|
return m_fontMap.size() == 0;
|
|||
|
}
|
|||
|
|
|||
|
void CGraphicFontTexture::Destroy()
|
|||
|
{
|
|||
|
HDC hDC = m_dib.GetDCHandle();
|
|||
|
if (hDC)
|
|||
|
SelectObject(hDC, m_hFontOld);
|
|||
|
|
|||
|
m_dib.Destroy();
|
|||
|
|
|||
|
m_lpd3dTexture = NULL;
|
|||
|
CGraphicTexture::Destroy();
|
|||
|
stl_wipe(m_pFontTextureVector);
|
|||
|
m_charInfoMap.clear();
|
|||
|
|
|||
|
if (m_fontMap.size())
|
|||
|
{
|
|||
|
TFontMap::iterator i = m_fontMap.begin();
|
|||
|
|
|||
|
while(i != m_fontMap.end())
|
|||
|
{
|
|||
|
DeleteObject((HGDIOBJ)i->second);
|
|||
|
++i;
|
|||
|
}
|
|||
|
|
|||
|
m_fontMap.clear();
|
|||
|
}
|
|||
|
|
|||
|
Initialize();
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::CreateDeviceObjects()
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CGraphicFontTexture::DestroyDeviceObjects()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::Create(const char* c_szFontName, int fontSize, bool bItalic)
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
|
|||
|
strncpy(m_fontName, c_szFontName, sizeof(m_fontName)-1);
|
|||
|
m_fontSize = fontSize;
|
|||
|
m_bItalic = bItalic;
|
|||
|
|
|||
|
m_x = 0;
|
|||
|
m_y = 0;
|
|||
|
m_step = 0;
|
|||
|
|
|||
|
DWORD width = 256,height = 256;
|
|||
|
if (GetMaxTextureWidth() > 512)
|
|||
|
width = 512;
|
|||
|
if (GetMaxTextureHeight() > 512)
|
|||
|
height = 512;
|
|||
|
|
|||
|
if (!m_dib.Create(ms_hDC, width, height))
|
|||
|
return false;
|
|||
|
|
|||
|
HDC hDC = m_dib.GetDCHandle();
|
|||
|
|
|||
|
m_hFont = GetFont(GetDefaultCodePage());
|
|||
|
|
|||
|
m_hFontOld=(HFONT)SelectObject(hDC, m_hFont);
|
|||
|
SetTextColor(hDC, RGB(255, 255, 255));
|
|||
|
SetBkColor(hDC, 0);
|
|||
|
|
|||
|
if (!AppendTexture())
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HFONT CGraphicFontTexture::GetFont(WORD codePage)
|
|||
|
{
|
|||
|
HFONT hFont = NULL;
|
|||
|
TFontMap::iterator i = m_fontMap.find(codePage);
|
|||
|
|
|||
|
if(i != m_fontMap.end())
|
|||
|
{
|
|||
|
hFont = i->second;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LOGFONT logFont;
|
|||
|
|
|||
|
memset(&logFont, 0, sizeof(LOGFONT));
|
|||
|
|
|||
|
logFont.lfHeight = m_fontSize;
|
|||
|
logFont.lfEscapement = 0;
|
|||
|
logFont.lfOrientation = 0;
|
|||
|
logFont.lfWeight = FW_NORMAL;
|
|||
|
logFont.lfItalic = (BYTE) m_bItalic;
|
|||
|
logFont.lfUnderline = FALSE;
|
|||
|
logFont.lfStrikeOut = FALSE;
|
|||
|
logFont.lfCharSet = GetCharsetFromCodePage(codePage);
|
|||
|
logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
|||
|
logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
|||
|
logFont.lfQuality = ANTIALIASED_QUALITY;
|
|||
|
logFont.lfPitchAndFamily = DEFAULT_PITCH;
|
|||
|
//Tracenf("font: %s", GetFontFaceFromCodePage(codePage));
|
|||
|
strcpy(logFont.lfFaceName, m_fontName); //GetFontFaceFromCodePage(codePage));
|
|||
|
//strcpy(logFont.lfFaceName, GetFontFaceFromCodePage(codePage));
|
|||
|
|
|||
|
hFont = CreateFontIndirect(&logFont);
|
|||
|
|
|||
|
m_fontMap.insert(TFontMap::value_type(codePage, hFont));
|
|||
|
}
|
|||
|
|
|||
|
return hFont;
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::AppendTexture()
|
|||
|
{
|
|||
|
CGraphicImageTexture * pNewTexture = new CGraphicImageTexture;
|
|||
|
|
|||
|
if (!pNewTexture->Create(m_dib.GetWidth(), m_dib.GetHeight(), D3DFMT_A4R4G4B4))
|
|||
|
{
|
|||
|
delete pNewTexture;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
m_pFontTextureVector.push_back(pNewTexture);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::UpdateTexture()
|
|||
|
{
|
|||
|
if(!m_isDirty)
|
|||
|
return true;
|
|||
|
|
|||
|
m_isDirty = false;
|
|||
|
|
|||
|
CGraphicImageTexture * pFontTexture = m_pFontTextureVector.back();
|
|||
|
|
|||
|
if (!pFontTexture)
|
|||
|
return false;
|
|||
|
|
|||
|
WORD* pwDst;
|
|||
|
int pitch;
|
|||
|
|
|||
|
if (!pFontTexture->Lock(&pitch, (void**)&pwDst))
|
|||
|
return false;
|
|||
|
|
|||
|
pitch /= 2;
|
|||
|
|
|||
|
int width = m_dib.GetWidth();
|
|||
|
int height = m_dib.GetHeight();
|
|||
|
|
|||
|
DWORD * pdwSrc = (DWORD*)m_dib.GetPointer();
|
|||
|
|
|||
|
for (int y = 0; y < height; ++y, pwDst += pitch, pdwSrc += width)
|
|||
|
for (int x = 0; x < width; ++x)
|
|||
|
pwDst[x]=pdwSrc[x];
|
|||
|
|
|||
|
pFontTexture->Unlock();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::GetCharacterInfomation(WORD codePage, wchar_t keyValue)
|
|||
|
{
|
|||
|
TCharacterKey code(codePage, keyValue);
|
|||
|
|
|||
|
TCharacterInfomationMap::iterator f = m_charInfoMap.find(code);
|
|||
|
|
|||
|
if (m_charInfoMap.end() == f)
|
|||
|
{
|
|||
|
return UpdateCharacterInfomation(code);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return &f->second;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::UpdateCharacterInfomation(TCharacterKey code)
|
|||
|
{
|
|||
|
HDC hDC = m_dib.GetDCHandle();
|
|||
|
SelectObject(hDC, GetFont(code.first));
|
|||
|
|
|||
|
wchar_t keyValue = code.second;
|
|||
|
|
|||
|
if (keyValue == 0x08)
|
|||
|
keyValue = L' '; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ۴<D9B2> (<28>ƶ<EFBFBD> <20><><EFBFBD>½<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: NAME:\tTEXT -> TEXT\t:NAME <20><> <20><>ȯ<EFBFBD><C8AF> )
|
|||
|
|
|||
|
ABCFLOAT stABC;
|
|||
|
SIZE size;
|
|||
|
|
|||
|
if (!GetTextExtentPoint32W(hDC, &keyValue, 1, &size) || !GetCharABCWidthsFloatW(hDC, keyValue, keyValue, &stABC))
|
|||
|
return NULL;
|
|||
|
|
|||
|
size.cx = stABC.abcfB;
|
|||
|
if( stABC.abcfA > 0.0f )
|
|||
|
size.cx += ceilf(stABC.abcfA);
|
|||
|
if( stABC.abcfC > 0.0f )
|
|||
|
size.cx += ceilf(stABC.abcfC);
|
|||
|
size.cx++;
|
|||
|
|
|||
|
LONG lAdvance = ceilf( stABC.abcfA + stABC.abcfB + stABC.abcfC );
|
|||
|
|
|||
|
int width = m_dib.GetWidth();
|
|||
|
int height = m_dib.GetHeight();
|
|||
|
|
|||
|
if (m_x + size.cx >= (width - 1))
|
|||
|
{
|
|||
|
m_y += (m_step + 1);
|
|||
|
m_step = 0;
|
|||
|
m_x = 0;
|
|||
|
|
|||
|
if (m_y + size.cy >= (height - 1))
|
|||
|
{
|
|||
|
if (!UpdateTexture())
|
|||
|
{
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (!AppendTexture())
|
|||
|
return NULL;
|
|||
|
|
|||
|
m_y = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TextOutW(hDC, m_x, m_y, &keyValue, 1);
|
|||
|
|
|||
|
int nChrX;
|
|||
|
int nChrY;
|
|||
|
int nChrWidth = size.cx;
|
|||
|
int nChrHeight = size.cy;
|
|||
|
int nDIBWidth = m_dib.GetWidth();
|
|||
|
|
|||
|
|
|||
|
DWORD*pdwDIBData=(DWORD*)m_dib.GetPointer();
|
|||
|
DWORD*pdwDIBBase=pdwDIBData+nDIBWidth*m_y+m_x;
|
|||
|
DWORD*pdwDIBRow;
|
|||
|
|
|||
|
pdwDIBRow=pdwDIBBase;
|
|||
|
for (nChrY=0; nChrY<nChrHeight; ++nChrY, pdwDIBRow+=nDIBWidth)
|
|||
|
{
|
|||
|
for (nChrX=0; nChrX<nChrWidth; ++nChrX)
|
|||
|
{
|
|||
|
pdwDIBRow[nChrX]=(pdwDIBRow[nChrX]&0xff) ? 0xffff : 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
float rhwidth = 1.0f / float(width);
|
|||
|
float rhheight = 1.0f / float(height);
|
|||
|
|
|||
|
TCharacterInfomation& rNewCharInfo = m_charInfoMap[code];
|
|||
|
|
|||
|
rNewCharInfo.index = m_pFontTextureVector.size() - 1;
|
|||
|
rNewCharInfo.width = size.cx;
|
|||
|
rNewCharInfo.height = size.cy;
|
|||
|
rNewCharInfo.left = float(m_x) * rhwidth;
|
|||
|
rNewCharInfo.top = float(m_y) * rhheight;
|
|||
|
rNewCharInfo.right = float(m_x+size.cx) * rhwidth;
|
|||
|
rNewCharInfo.bottom = float(m_y+size.cy) * rhheight;
|
|||
|
rNewCharInfo.advance = (float) lAdvance;
|
|||
|
|
|||
|
m_x += size.cx;
|
|||
|
|
|||
|
if (m_step < size.cy)
|
|||
|
m_step = size.cy;
|
|||
|
|
|||
|
m_isDirty = true;
|
|||
|
|
|||
|
return &rNewCharInfo;
|
|||
|
}
|
|||
|
|
|||
|
bool CGraphicFontTexture::CheckTextureIndex(DWORD dwTexture)
|
|||
|
{
|
|||
|
if (dwTexture >= m_pFontTextureVector.size())
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CGraphicFontTexture::SelectTexture(DWORD dwTexture)
|
|||
|
{
|
|||
|
assert(CheckTextureIndex(dwTexture));
|
|||
|
m_lpd3dTexture = m_pFontTextureVector[dwTexture]->GetD3DTexture();
|
|||
|
}
|