Files
Leviathan/Client/Game/engine/Ui/KTextRender.cpp
T
2026-06-01 12:46:52 +02:00

1335 lines
37 KiB
C++

#include "stdafx.h"
#include "KViewport.h"
#include "KTextRender.h"
#include "KPrimitiveSprite.h"
#include "KTextPhrase.h"
#include "KTextCacheManager.h"
#include "KTextEmoticonRender.h"
#include "KResourceManager.h"
#include <renderer/XFreeType.h>
#include <kfile/KFileManager.h>
#include <toolkit/nsl.h>
#include "shlobj.h"
#ifdef _COUNTRY_ME_
#include "KPangoCairo.h"
#endif
namespace
{
const int COLOR_VALUE = 1024;
};
XFreeType * KTextRender::s_pFreeType = new XFreeType;
K3DRenderDevice * KTextRender::m_pDevice = NULL;
KTextRender::FontMap KTextRender::m_mapFontInfo;
int KTextRender::m_nDefaultCodePage = CP_ACP; // AziaMafia DEFAUT UTF-8
HDC KTextRender::m_hDC;
bool bUseFreeType = false;
bool KTextRender::s_bIsOsVista = false;
std::string KTextRender::s_strLocale;
const char *KTextRender::KDEFAULT_FONT_NAME = "Default";
const char *KTextRender::KDEFAULT_FONT_NAME2 = "font_default"; /// 2010.11.05 - prodongi
const char *KTextRender::KDEFAULT_FONT_01 = "font_01";
const char *KTextRender::KDEFAULT_FONT_02 = "font_02";
const char *KTextRender::KDEFAULT_FONT_03 = "font_03"; // 2010.08.26 - prodongi
const int KTextRender::KDEFAULT_FONT_SIZE = 9;
KTextRender::StringTableHandler* KTextRender::s_pStringTableHandler;
float KTextRender::m_fFreeTypeSizeRatio = 1.0f;
bool KTextRender::m_bIncreaseEnglishFontSize= false;
int KTextRender::m_nFreeTypeYOffset = 0;
unsigned char KTextRender::s_randColor[1024];
int KTextRender::s_nColorValue = 0;
#ifdef _COUNTRY_ME_
KFontManager KTextRender::s_fontManager;
#endif
void KTextRender::GenerateRandColor()
{
for( int i(0); COLOR_VALUE>i; i++ )
{
s_randColor[i] = rand()%255;
}
}
unsigned char KTextRender::GetNextRandColor()
{
if( s_nColorValue > COLOR_VALUE )
s_nColorValue = 0;
return s_randColor[s_nColorValue++];
}
static int incSizeIfNoMultiByte( const char *str, int nFontSize )
{
const unsigned char *p = (const unsigned char *)str;
while( *p )
{
if( *p & 0x80 ) return nFontSize;
++p;
}
return nFontSize+2;
}
KTextRender::FREETYPE_TEXT_FONT_INFO::FREETYPE_TEXT_FONT_INFO( const char *szAlias, const char *szFontFileName,bool *returnSuccess )
{
pFontStream = NULL;
if(returnSuccess)
*returnSuccess = true;
//pFontStream = NULL;
bIsFreeType = true;
KStream *pFontResource = KFileManager::Instance().CreateStreamFromResource( szFontFileName );
if( !pFontResource )
{
TCHAR szFontPath[_MAX_PATH];
if( SHGetFolderPath( NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, szFontPath ) == E_FAIL )
{
assert(0 && "FREETYPE_TEXT_FONT_INFO - resource not found!!" );
*returnSuccess = false;
}
else
{
std::string path = szFontPath;
path += "\\";
path += szFontFileName;
FILE *fp = fopen(path.c_str(),"rb");
if(fp)
{
fseek( fp, 0, SEEK_END );
size_t fsize = ftell( fp );
fseek( fp, 0, SEEK_SET );
pFontStream = new char[fsize];
fread( pFontStream, sizeof(char)*fsize, 1, fp );
if( !s_pFreeType->IsInitialized() ) s_pFreeType->Init();
if( !s_pFreeType->LoadFont( szAlias, pFontStream, fsize ) )
{
assert(0 && "FREETYPE_TEXT_FONT_INFO - LoadFont Failed!!" );
delete [] pFontStream;
if(returnSuccess)
*returnSuccess = false;
}
KFileManager::Instance().DeleteStream( pFontResource );
fclose( fp );
}
else
{
assert(0 && "FREETYPE_TEXT_FONT_INFO - resource not found!!" );
*returnSuccess = false;
}
}
}
else
{
pFontStream = new char[ pFontResource->GetLength() ];
pFontResource->Read( pFontStream, pFontResource->GetLength() );
if( !s_pFreeType->IsInitialized() ) s_pFreeType->Init();
if( !s_pFreeType->LoadFont( szAlias, pFontStream, pFontResource->GetLength() ) )
{
assert(0 && "FREETYPE_TEXT_FONT_INFO - LoadFont Failed!!" );
delete [] pFontStream;
if(returnSuccess)
*returnSuccess = false;
}
KFileManager::Instance().DeleteStream( pFontResource );
}
}
#ifndef _COUNTRY_ME_
/// 2011.02.23 isSpriteScroll 추가 - prodongi
KTextRender::KTextRender(LPCSTR lpszText, KColor color, LPCSTR lpszFontName, int nSize,
DWORD & dwWidth, DWORD & dwHeight, DWORD dwAlign, DWORD dwFlag, bool bStaticSize, KColor color_fx, float fZPos/*0.0f*/, bool bRandomColor/*=false*/, bool bUseEmoticonFilter, bool isSpriteScroll )
:m_dwWidth(dwWidth), m_dwHeight(dwHeight), m_pEmoticonLayerRender(NULL), m_prSprite(NULL)
{
//assert( _CrtCheckMemory() );
//if( _CrtCheckMemory() == 0 )
// SDEBUGLOG("_CrtCheckMemory - KTextRender::KTextRender");
// SDEBUGLOG("KTextRender::GetStringSize - text[%s], font[%s]", lpszText, lpszFontName);
int bufferImgWidth = 0; /// 2011.02.23 Text Image의 사이즈- prodongi
int bufferImgHeight = 0;
DWORD dwTextColor = DWORD((color.a << 24) | (color.r << 16) | (color.g << 8) | (color.b));
TEXT_FONT_INFO * pFontInfo = _FindFont(lpszFontName, nSize);
if( pFontInfo && pFontInfo->bIsFreeType && m_bIncreaseEnglishFontSize ) nSize = incSizeIfNoMultiByte( lpszText, nSize );
// InitTextRender가 불려지지 않았으므로
if(!m_pDevice)
{
assert(false && "please call InitTextRender");
}
m_prSprite = new KSpritePrimitive(false); // [MEMORY_LEAK] 2012. 3. 2 - marine 메모리 해제해줌..
m_spResSprite = new KResSprite; // [MEMORY_LEAK] 2012. 3. 2 - marine 메모리 해제해줌..
std::string strText = lpszText;
for( size_t i = 0; i < strText.size(); ++i )
{
//if( strText[i] == 0x1D ) strText[i] = '&';
if( strText[i] == 0x1E ) strText[i] = '<';
if( strText[i] == 0x1F ) strText[i] = '>';
}
// emoticon
bool bExistEmoticon = false;
DWORD dwOldHeight = dwHeight;
if( bUseEmoticonFilter )
CheckEmoticon( strText, lpszFontName, nSize, dwFlag, dwWidth, dwHeight, bStaticSize, fZPos );
if( dwOldHeight != dwHeight ) bExistEmoticon = true;
m_spTexture = KTextCacheManager::GetInstance()->FindCache( strText.c_str(), color, lpszFontName, nSize, dwWidth, dwHeight, dwFlag, color_fx);
if(m_spTexture != NULL)
{
if (isSpriteScroll) /// 2011.03.22 - prodongi
{
m_spResSprite->SetTexture(m_spTexture, m_spTexture->GetTextOriImgRect());
m_prSprite->SetRes(m_spResSprite);
m_prSprite->setScrollImgUv(m_spTexture->GetTextOriImgWidth(), m_spTexture->GetTextOriImgHeight());
}
else
{
m_spResSprite->SetTexture(m_spTexture, NULL);
m_prSprite->SetRes(m_spResSprite);
}
return;
}
KRect rcTexRect;
if( pFontInfo == NULL || !pFontInfo->bIsFreeType )
{
BYTE *pBitmapBuffer = NULL;
BITMAPINFO bmi;
ZeroMemory( &bmi.bmiHeader, sizeof(bmi.bmiHeader) );
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = dwWidth;
bmi.bmiHeader.biHeight = -int(dwHeight);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
//bmi.bmiHeader.biBitCount = 16;
bmi.bmiHeader.biBitCount = 32;
HBITMAP hBmBitmap = CreateDIBSection( m_hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBuffer, NULL, 0 );
//DWORD dwStride = dwWidth * 2;
DWORD dwStride = dwWidth * 4;
if ( dwStride % 4 )
dwStride = ((dwStride / 4) + 1) * 4;
ZeroMemory( pBitmapBuffer, dwStride * dwHeight );
WIN32_TEXT_FONT_INFO * pInfo = (WIN32_TEXT_FONT_INFO *)_FindFont(lpszFontName, nSize);
if(!pInfo)
{
if( strlen(lpszFontName) > 0 )
{
KTextRender::AddFont(lpszFontName,nSize);
pInfo = (WIN32_TEXT_FONT_INFO *)_FindFont(lpszFontName, nSize);
}
else
{
pInfo = (WIN32_TEXT_FONT_INFO *)_FindFont("default", nSize);
}
}
HBITMAP hBitmapOld = reinterpret_cast<HBITMAP>( ::SelectObject(m_hDC, hBmBitmap));
HFONT hFontOld;
// Font Flag Setting
if(dwFlag & KTFLAG_BOLD)
{
hFontOld = reinterpret_cast<HFONT>(::SelectObject(m_hDC,pInfo->hBoldFont ) );
}
else if(dwFlag & KTFLAG_UNDER)
{
hFontOld = reinterpret_cast<HFONT>(::SelectObject(m_hDC,pInfo->hUnderLineFont ) );
}
else if(dwFlag & KTFLAG_STRIKE)
{
hFontOld = reinterpret_cast<HFONT>(::SelectObject(m_hDC,pInfo->hStrikeOutFont ) );
}
else
{
hFontOld = reinterpret_cast<HFONT>(::SelectObject(m_hDC, pInfo->hDefaultFont) );
}
SetTextAlign(m_hDC, TA_TOP );
DWORD dwColor = RGB(255,255,255);
if(dwFlag & KTFLAG_INVERSE)
{
SetBkMode( m_hDC, TRANSPARENT );
SetBkColor( m_hDC, 0x00000000 );
SetTextColor( m_hDC, dwColor );
}
else
{
SetBkMode( m_hDC, TRANSPARENT );
SetBkColor( m_hDC, 0x00000000 );
SetTextColor( m_hDC, dwColor );
}
unsigned int i;
for(i = 2; i < dwWidth+4;)
i *= 2;
DWORD dwTexWidth = i;
for(i = 2; i < dwHeight+4;)
i *= 2;
DWORD dwTexHeight = i;
RECT rcRect;
rcRect.left = 0; rcRect.top = 0; rcRect.right = dwWidth; rcRect.bottom = dwHeight;
rcTexRect.left = 0; rcTexRect.top = 0; rcTexRect.right = dwWidth; rcTexRect.bottom = dwHeight;
// MIMI
if( bExistEmoticon )
{
// 전체 height 의 절반에서 폰트 height 의 절반을 뺀것이 top
rcRect.top = dwHeight/2 - dwOldHeight/2;
rcRect.top += 2;
}
::DrawText(m_hDC,
strText.c_str(),
static_cast<int>(strText.size()),
&rcRect,
dwAlign | DT_NOPREFIX
#ifdef _COUTNRY_ME_ // sonador #2.4.10.2
| DT_RTLREADING
#endif
);
m_spTexture = m_pDevice->CreateTexture(dwTexWidth,dwTexHeight, K3DFMT_A8R8G8B8 );
if(m_spTexture == NULL)
return;
int nStride;
DWORD* pImgBuf32;
m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32),nStride);
assert(pImgBuf32 && "m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32),nStride);");
if( NULL == pImgBuf32 )
{
return;
}
nStride /= sizeof(DWORD);
int textoffset = 0;
if ( dwFlag & KTFLAG_GLOW )
{
textoffset = 2;
//unsigned short wGlowColor = unsigned short((0x6 << 12) | (0xa << 8) | (0xa << 4) | 0xa);
DWORD dwGlowColor = DWORD((0x60 << 24) | (0xa0 << 16) | (0xa0 << 8) | 0xa0);
//for(i = 0; i < dwHeight; ++i)
//{
// WORD *pImg = (WORD*)&pBitmapBuffer[i*dwStride];
// for(unsigned int j = 0; j < dwWidth; ++j)
// {
// if( *pImg++ )
// {
// *(pImgBuf16 + (i+0) * nStride + (j+0)) = wGlowColor;
// *(pImgBuf16 + (i+0) * nStride + (j+1)) = wGlowColor;
// *(pImgBuf16 + (i+0) * nStride + (j+2)) = wGlowColor;
// *(pImgBuf16 + (i+0) * nStride + (j+3)) = wGlowColor;
// *(pImgBuf16 + (i+0) * nStride + (j+4)) = wGlowColor;
// *(pImgBuf16 + (i+1) * nStride + (j+0)) = wGlowColor;
// *(pImgBuf16 + (i+2) * nStride + (j+0)) = wGlowColor;
// *(pImgBuf16 + (i+3) * nStride + (j+0)) = wGlowColor;
// *(pImgBuf16 + (i+4) * nStride + (j+0)) = wGlowColor;
// *(pImgBuf16 + (i+1) * nStride + (j+4)) = wGlowColor;
// *(pImgBuf16 + (i+2) * nStride + (j+4)) = wGlowColor;
// *(pImgBuf16 + (i+3) * nStride + (j+4)) = wGlowColor;
// *(pImgBuf16 + (i+4) * nStride + (j+4)) = wGlowColor;
// *(pImgBuf16 + (i+4) * nStride + (j+1)) = wGlowColor;
// *(pImgBuf16 + (i+4) * nStride + (j+2)) = wGlowColor;
// *(pImgBuf16 + (i+4) * nStride + (j+3)) = wGlowColor;
// }
// }
//}
for(i = 0; i < dwHeight; ++i)
{
DWORD *pImg = (DWORD*) &pBitmapBuffer[i*dwStride];
for(unsigned int j = 0; j < dwWidth; ++j)
{
if( *pImg++ )
{
*(pImgBuf32 + (i+0) * nStride + (j+0)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+0) * nStride + (j+1)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+0) * nStride + (j+2)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+0) * nStride + (j+3)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+0) * nStride + (j+4)) = dwGlowColor;
if( i != dwHeight - 1 )
{
*(pImgBuf32 + (i+1) * nStride + (j+0)) = dwGlowColor;
*(pImgBuf32 + (i+2) * nStride + (j+0)) = dwGlowColor;
*(pImgBuf32 + (i+3) * nStride + (j+0)) = dwGlowColor;
*(pImgBuf32 + (i+4) * nStride + (j+0)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+1) * nStride + (j+4)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+2) * nStride + (j+4)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+3) * nStride + (j+4)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+4) * nStride + (j+4)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+4) * nStride + (j+1)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+4) * nStride + (j+2)) = dwGlowColor;
if( j != dwWidth - 1 ) *(pImgBuf32 + (i+4) * nStride + (j+3)) = dwGlowColor;
}
}
}
}
}
if ( dwFlag & KTFLAG_GLOW || dwFlag & KTFLAG_OUTLINE )
{
int so = 2;
if ( !(dwFlag & KTFLAG_GLOW) )
{
textoffset = 1;
so = 1;
}
//unsigned short wShadowColor = unsigned short((0xf << 12) | (0x4 << 8) | (0x4 << 4) | 0x4);
//for(i = 0; i < dwHeight; ++i)
//{
// WORD *pImg = (WORD*)&pBitmapBuffer[i*dwStride];
// for(unsigned int j = 0; j < dwWidth; ++j)
// {
// if( *pImg++ )
// {
// *(pImgBuf16 + (i+so-1) * nStride + (j+so-1)) = wShadowColor;
// *(pImgBuf16 + (i+so-1) * nStride + (j+so)) = wShadowColor;
// *(pImgBuf16 + (i+so-1) * nStride + (j+so+1)) = wShadowColor;
// *(pImgBuf16 + (i+so) * nStride + (j+so-1)) = wShadowColor;
// *(pImgBuf16 + (i+so) * nStride + (j+so+1)) = wShadowColor;
// *(pImgBuf16 + (i+so+1) * nStride + (j+so-1)) = wShadowColor;
// *(pImgBuf16 + (i+so+1) * nStride + (j+so)) = wShadowColor;
// *(pImgBuf16 + (i+so+1) * nStride + (j+so+1)) = wShadowColor;
// }
// }
//}
DWORD dwShadowColor = DWORD((0xf0 << 24) | (0x40 << 16) | (0x40 << 8) | 0x40);
for(i = 0; i < dwHeight; ++i)
{
DWORD *pImg = (DWORD*)&pBitmapBuffer[i*dwStride];
for(unsigned int j = 0; j < dwWidth; ++j)
{
if( *pImg++ )
{
if( i + so - 1 < dwHeight )
{
if( j + so - 1 < dwWidth ) *(pImgBuf32 + (i+so-1) * nStride + (j+so-1)) = dwShadowColor;
if( j + so < dwWidth ) *(pImgBuf32 + (i+so-1) * nStride + (j+so)) = dwShadowColor;
if( j + so + 1 < dwWidth ) *(pImgBuf32 + (i+so-1) * nStride + (j+so+1)) = dwShadowColor;
}
if( i + so < dwHeight )
{
if( j + so - 1 < dwWidth ) *(pImgBuf32 + (i+so) * nStride + (j+so-1)) = dwShadowColor;
if( j + so + 1 < dwWidth ) *(pImgBuf32 + (i+so) * nStride + (j+so+1)) = dwShadowColor;
}
if( i + so + 1 < dwHeight )
{
if( j + so - 1 < dwWidth ) *(pImgBuf32 + (i+so+1) * nStride + (j+so-1)) = dwShadowColor;
if( j + so < dwWidth ) *(pImgBuf32 + (i+so+1) * nStride + (j+so)) = dwShadowColor;
if( j + so + 1 < dwWidth ) *(pImgBuf32 + (i+so+1) * nStride + (j+so+1)) = dwShadowColor;
}
}
}
}
}
else if ( dwFlag & KTFLAG_SHADOW )
{
//unsigned short wShadowColor = unsigned short((0xf << 12) | (0x4 << 8) | (0x4 << 4) | 0x4);
//for(i = 0; i < dwHeight; ++i)
//{
// WORD *pImg = (WORD*)&pBitmapBuffer[i*dwStride];
// for(unsigned int j = 0; j < dwWidth; ++j)
// {
// if( *pImg++ )
// *(pImgBuf16 + (i+1) * nStride + (j+1)) = wShadowColor;
// }
//}
DWORD dwShadowColor = DWORD((0xff << 24) | (0x40 << 16) | (0x40 << 8) | 0x40);
for(i = 0; i < dwHeight; ++i)
{
DWORD *pImg = (DWORD*)&pBitmapBuffer[i*dwStride];
for(unsigned int j = 0; j < dwWidth; ++j)
{
if( *pImg++ )
{
if( i != dwHeight - 1 && j != dwWidth - 1 )
*(pImgBuf32 + (i+1) * nStride + (j+1)) = dwShadowColor;
}
}
}
}
//unsigned short wTextColor = unsigned short((0xf << 12) | ((color.b>>4) << 8) | ((color.g>>4) << 4) | (color.r>>4));
//for(i = 0; i < dwHeight; ++i)
//{
// WORD *pImg = (WORD*)&pBitmapBuffer[i*dwStride];
// for(unsigned int j = 0; j < dwWidth; ++j)
// {
// if( *pImg++ )
// *(pImgBuf16 + (i+textoffset) * nStride + (j+textoffset)) = wTextColor;
// }
//}
for(i = 0; i < dwHeight; ++i)
{
DWORD *pImg = (DWORD*)&pBitmapBuffer[i*dwStride];
for(unsigned int j = 0; j < dwWidth; ++j)
{
if( *pImg++ )
{
if( i + textoffset < dwHeight && j + textoffset < dwWidth )
{
if( bRandomColor )
{
dwTextColor = DWORD((0xFF << 24) | (GetNextRandColor() << 16) | (GetNextRandColor() << 8) | (GetNextRandColor()));
}
*(pImgBuf32 + (i+textoffset) * nStride + (j+textoffset)) = dwTextColor;
}
}
else if( dwFlag & KTFLAG_INVERSE )
{
if( i + textoffset + 3 < dwHeight && j + textoffset < dwWidth )
{
*(pImgBuf32 + (i+textoffset) * nStride + (j+textoffset)) = 0xFFCDCDCD;
}
}
}
}
m_spTexture->Unlock();
SelectObject(m_hDC, hFontOld);
SelectObject(m_hDC, hBitmapOld);
DeleteObject(hBmBitmap);
}
else
{
//SDEBUGLOG("KTextRender::KTextRender s_pFreeType->Draw - begin");
//SDEBUGLOG("\tKTextRender::KTextRender - text[%s], font[%s], %p", lpszText, lpszFontName, s_pFreeType);
//SDEBUGLOG("\tKTextRender::KTextRender - %s, %s, %d, %d", strText.c_str(), lpszFontName, strText.size(), m_nDefaultCodePage);
/*if( _CrtCheckMemory() == 0 )
SDEBUGLOG("_CrtCheckMemory - KTextRender::KTextRender s_pFreeType->Draw - begin");*/
// assert( _CrtCheckMemory() );
rcTexRect.left = 0; rcTexRect.top = 0; rcTexRect.right = dwWidth; rcTexRect.bottom = dwHeight;
wchar_t *pBuffer = new wchar_t[ strText.size()+1 ];
// assert( _CrtCheckMemory() );
int len = ::MultiByteToWideChar( m_nDefaultCodePage, 0, strText.c_str(), strText.size(), pBuffer, strText.size() );
// assert( _CrtCheckMemory() );
pBuffer[len] = 0;
// assert( _CrtCheckMemory() );
s_pFreeType->SetFontColor( color.b, color.g, color.r ); //순서에 문제가 n있음.
s_pFreeType->SetEffectColor( color_fx.b, color_fx.g, color_fx.r );//순서에 문제가 있음.
int nWidth, nHeight;
// 폰트 이펙트 불일치는 일단 이렇게 땜빵. -_-
int nFlag = 0;/*XFreeType::FT_SHADOW*/;
if( dwFlag & KTFLAG_SHADOW ) nFlag = XFreeType::FT_SHADOW_LV1;
if( dwFlag & KTFLAG_GLOW ) nFlag = XFreeType::FT_STROKE_LV2;
if( dwFlag & KTFLAG_GLOW2X ) nFlag = XFreeType::FT_STROKE_LV3;
// 2010. 8. 20 - marine <out><b>태그가 적용되지 않아서 추가
if( dwFlag & KTFLAG_OUTLINE) nFlag = XFreeType::FT_OUTLINE;
if( dwFlag & KTFLAG_BOLD) nFlag = XFreeType::FT_BOLD;
/*if( _CrtCheckMemory() == 0 )
SDEBUGLOG("_CrtCheckMemory - KTextRender::KTextRender s_pFreeType->Draw - 2");*/
// assert( _CrtCheckMemory() );
//SDEBUGLOG("\tKTextRender::KTextRender - text[%s], font[%s], %p, text_w[%ws]", lpszText, lpszFontName, s_pFreeType,pBuffer);
//SDEBUGLOG("\tKTextRender::KTextRender - %s, %s, %d, %d", strText.c_str(), lpszFontName, len, m_nDefaultCodePage);
//
/*
LPCSTR lpszText, KColor color, LPCSTR lpszFontName, int nSize,
DWORD & dwWidth, DWORD & dwHeight, DWORD dwAlign, DWORD dwFlag, bool bS
*/
// assert( _CrtCheckMemory() );
const XAlphaImage *pImg = s_pFreeType->Draw( lpszFontName, pBuffer, &nWidth, &nHeight, nSize*m_fFreeTypeSizeRatio, nFlag, m_nFreeTypeYOffset, dwFlag & KTFLAG_UNDER, dwFlag & KTFLAG_INVERSE, false, pFontInfo->bHinting );
//SDEBUGLOG("KTextRender::KTextRender s_pFreeType->Draw - end");
delete [] pBuffer;
if( pImg == NULL ) return;
DWORD dwTexWidth = pImg->GetWidth(), dwTexHeight = pImg->GetHeight();
if (isSpriteScroll) /// 2011.02.23 - prodongi
{
dwTexWidth = dwWidth;
bufferImgWidth = pImg->GetWidth();
bufferImgHeight = pImg->GetHeight();
}
int nExpX, nExpY;
K3DRenderDevice::GetSquareSize( dwTexWidth,dwTexHeight, nExpX, nExpY );
m_spTexture = m_pDevice->CreateTexture(nExpX, nExpY, K3DFMT_A8R8G8B8 );
if(m_spTexture == NULL)
return;
int nStride;
//WORD * pImgBuf16 = NULL;
char * pImgBuf32 = NULL;
rcTexRect.left = 0; rcTexRect.top = 0; rcTexRect.right = dwTexWidth; rcTexRect.bottom = dwTexHeight;
m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32),nStride);
assert( pImgBuf32 && "m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32),nStride);");
if( !pImgBuf32 ) return;
size_t nBufSize = pImg->GetWidth() * pImg->GetHeight();
const XAlphaImage::Pixel *p = pImg->GetBuffer();
int nSrcStride = pImg->GetWidth(); /// 2011.02.23 - prodongi
DWORD* pDstColor;
DWORD* pSrcColor;
DWORD tempColor;
for(UINT y = 0; y < rcTexRect.bottom; y++ )
{
pDstColor = ( DWORD* )pImgBuf32; /// tex
pSrcColor = ( DWORD* )p; /// img
for( UINT x = 0; x < rcTexRect.right; x++ )
{
if( bRandomColor )
{
if( pSrcColor[x] != 0 )
{
tempColor = pSrcColor[x];
pDstColor[x] = DWORD((0xFF000000 & tempColor) | (GetNextRandColor() << 16) | (GetNextRandColor() << 8) | (GetNextRandColor()));
}
else
{
if (x < nSrcStride) /// 2011.02.23 - prodongi
pDstColor[x] = pSrcColor[x];
}
}
else
{
if (x < nSrcStride) /// 2011.02.23 - prodongi
pDstColor[x] = pSrcColor[x];
}
}
pImgBuf32 += nStride;
p += nSrcStride;
}
//memcpy( pImgBuf16, pImg->GetBuffer(), dwTexWidth*dwTexHeight*2 );
m_spTexture->Unlock();
}
// 이제 Sprite에 Texture를 세팅해 주자
m_spResSprite->SetTexture(m_spTexture, &rcTexRect);
m_prSprite->SetRes(m_spResSprite);
if (isSpriteScroll) /// 2011.02.23 - prodongi
{
m_spTexture->SetTextOriImgRect(rcTexRect);
m_spTexture->SetTextOriImgSize(bufferImgWidth, bufferImgHeight);
m_prSprite->setScrollImgUv(bufferImgWidth, bufferImgHeight);
}
// Cache에도 등록
KTextCacheManager::GetInstance()->RegisterCache( strText.c_str(), color, lpszFontName, nSize,
dwWidth, dwHeight, dwFlag, color_fx, m_spTexture);
}
#endif
KTextRender::~KTextRender()
{
Clear();
}
void KTextRender::Clear()
{
m_spResSprite->SetTexture( NULL, NULL );
m_prSprite->SetRes( NULL );
SAFE_DELETE(m_prSprite);
SAFE_DELETE(m_pEmoticonLayerRender );
}
void KTextRender::SetPosition( float fXPos, float fYPos, float fZPos)
{
m_prSprite->SetPosition(fXPos,fYPos,fZPos);
if( m_pEmoticonLayerRender ) m_pEmoticonLayerRender->SetOffset( static_cast<int>(fXPos), static_cast<int>(fYPos) );
}
void KTextRender::SetVisibility( float vis )
{
m_prSprite->SetVisibility(vis);
}
void KTextRender::SetClipRect(const KRect & rcRect)
{
m_rcClipRect = rcRect;
m_prSprite->SetClipRect(&m_rcClipRect);
}
void KTextRender::Render( KViewportObject *viewport, bool isFront/* = false*/ )
{
viewport->Register(m_prSprite, isFront);
if( m_pEmoticonLayerRender ) m_pEmoticonLayerRender->Render( viewport, isFront );
}
#ifdef _COUNTRY_ME_
void KTextRender::InitTextRender( K3DRenderDevice * pDevice, int nCodePage, LPCTSTR strFontName )
{
m_pDevice = pDevice;
KFontManager::GetInstance()->Create( strFontName );
}
void KTextRender::DestroyAll()
{
KFontManager::GetInstance()->Destroy();
}
#else
void KTextRender::InitTextRender( K3DRenderDevice * pDevice )
{
m_pDevice = pDevice;
m_hDC = CreateCompatibleDC( NULL );
SetMapMode( m_hDC, MM_TEXT );
if( !s_pFreeType->IsInitialized() ) s_pFreeType->Init();
//if( !s_pFreeType->Init() ) assert(0 && "KTextRender::InitTextRender - Init Failed!!" );
}
void KTextRender::DestroyAll()
{
//SDEBUGLOG( "KTextRender::DestroyAll()" );
TEXT_FONT_INFO* info;
bool res = m_mapFontInfo.get_first_value( info );
while ( res )
{
delete info;
res = m_mapFontInfo.get_next_value( info );
}
m_mapFontInfo.clear();
s_pFreeType->DeInit();
delete s_pFreeType;
s_pFreeType = NULL;
DeleteDC(m_hDC);
}
#endif
int KTextRender::GetFontHeight( int nFontSize )
{
return (int)(nFontSize*1.5f);
}
void KTextRender::GetStringSize(LPCSTR lpszFontName, int nFontSize, BOOL bBold, LPCSTR lpszString, int nStringLen,
DWORD *pStringWidth, DWORD * pStringHeight)
{
TEXT_FONT_INFO * pInfo = _FindFont(lpszFontName, nFontSize);
if( pInfo && pInfo->bIsFreeType && m_bIncreaseEnglishFontSize )
nFontSize = incSizeIfNoMultiByte( lpszString, nFontSize );
std::string strString( lpszString );
for( size_t i = 0; i < strString.size(); ++i )
{
if( strString[i] == 0x1E )
strString[i] = '<';
if( strString[i] == 0x1F )
strString[i] = '>';
}
if( pInfo == NULL )
{
if( strlen(lpszFontName) > 0 )
{
KTextRender::AddFont(lpszFontName,nFontSize);
pInfo = _FindFont(lpszFontName, nFontSize);
}
}
// lenahyang 2012.09.06
if( pInfo == NULL )
{
pInfo = _FindFont( "default", nFontSize );
if( pInfo == NULL )
{
*pStringWidth = 0;
*pStringHeight = 0;
return;
}
}
assert( pInfo && "TEXT_FONT_INFO == NULL 여기 어쩌다 들어 오는데 고치시오~" );
if( pInfo && pInfo->bIsFreeType )
{
// assert( _CrtCheckMemory() );
//SDEBUGLOG("KTextRender::GetStringSize - begin (bIsFreeType)");
//SDEBUGLOG("\tKTextRender::GetStringSize - %p, %s, %d, %s, %d",s_pFreeType, lpszFontName, nFontSize, lpszString, nStringLen);
wchar_t *pBuffer = new wchar_t[ nStringLen+1 ];
// assert( _CrtCheckMemory() );
int len = ::MultiByteToWideChar( m_nDefaultCodePage, 0, strString.c_str(), nStringLen, pBuffer, nStringLen );
// assert( _CrtCheckMemory() );
pBuffer[len] = 0;
// assert( _CrtCheckMemory() );
// 2010.07.20 - prodongi
if( !s_pFreeType->GetSize( lpszFontName, pBuffer, (int*)pStringWidth, (int*)pStringHeight, nFontSize*m_fFreeTypeSizeRatio, pInfo->bHinting ) )
//if( !s_pFreeType->GetSize( lpszFontName, pBuffer, (int*)pStringWidth, (int*)pStringHeight, nFontSize*m_fFreeTypeSizeRatio ) )
{
//SDEBUGLOG("\tKTextRender::GetStringSize - end1");
*pStringWidth = 0;
*pStringHeight = 0;
delete [] pBuffer;
//SDEBUGLOG("KTextRender::GetStringSize - end1.end");
return;
}
//SDEBUGLOG("\tKTextRender::GetStringSize - end2");
(*pStringHeight) = GetFontHeight( nFontSize );
delete [] pBuffer;
//SDEBUGLOG("KTextRender::GetStringSize - end2.end");
return;
}
WIN32_TEXT_FONT_INFO *pWin32Info = (WIN32_TEXT_FONT_INFO *)pInfo;
HFONT hFontOld;
if(bBold)
{
hFontOld = (HFONT)::SelectObject(m_hDC,pWin32Info->hBoldFont);
}
else
hFontOld = (HFONT)::SelectObject(m_hDC, pWin32Info->hDefaultFont);
SIZE size;
GetTextExtentPoint32( m_hDC, strString.c_str(), nStringLen, &size );
*pStringWidth = size.cx; *pStringHeight = size.cy;
}
void KTextRender::SetFontHinting( LPCSTR lpszFontName, bool bHinting )
{
TEXT_FONT_INFO* pFontInfo = _FindFont( lpszFontName, -1 );
if ( pFontInfo )
pFontInfo->SetHinting( bHinting );
}
bool KTextRender::AddFreeTypeFont( LPCSTR lpszFontName, LPCSTR lpszFontFileName )
{
// 이미 Load한 Font는 Add할 필요가 없다.
if(_FindFont(lpszFontName,-1) )
{
return true;
}
bool rSuc;
FREETYPE_TEXT_FONT_INFO *pInfo = new FREETYPE_TEXT_FONT_INFO( lpszFontName, lpszFontFileName, &rSuc );
if(rSuc)
{
// SDEBUGLOG( "AddFreeTypeFont : %s %s\n", lpszFontName, lpszFontFileName );
hashPr_font::Key key( lpszFontName, -1 );
m_mapFontInfo.add( key, pInfo );
}
else
{
SAFE_DELETE(pInfo);
}
return rSuc;
}
void KTextRender::AddFont(LPCSTR lpszFontName, int nFontSize )
{
// 이미 Load한 Font는 Add할 필요가 없다.
if(_FindFont(lpszFontName,nFontSize) )
{
return;
}
#ifdef _COUNTRY_TL_
DWORD iCharSet = THAI_CHARSET;
#else
DWORD iCharSet = DEFAULT_CHARSET;
#endif
WIN32_TEXT_FONT_INFO * pInfo = WIN32_TEXT_FONT_INFO::CreateTextFont();
int nHeight = -MulDiv( nFontSize, (INT)(GetDeviceCaps(m_hDC, LOGPIXELSY)), 72 );
// 미리 폰트를 생성하자.
pInfo->hDefaultFont = ::CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE,
FALSE, FALSE, iCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH, lpszFontName );
int nCWeight = FW_BOLD;
//일본 비스타 버전에서 BOLD 폰트가 깨지는 문제가 발생.. 뭐냐!!!
if( s_bIsOsVista && ( s_strLocale.length() > 0 && _stricmp( s_strLocale.c_str(), "Shift-JIS" ) == 0 ) )
nCWeight = FW_SEMIBOLD;
pInfo->hBoldFont = ::CreateFont(nHeight,0,0,0,nCWeight, FALSE,
FALSE, FALSE, iCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH, lpszFontName );
pInfo->hUnderLineFont = ::CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE,
TRUE, FALSE, iCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH, lpszFontName);
pInfo->hStrikeOutFont = ::CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE,
FALSE, TRUE, iCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH, lpszFontName);
hashPr_font::Key key( lpszFontName, nFontSize );
m_mapFontInfo.add( key, pInfo );
//_oprint( "AddFont : %s %d\t\n", lpszFontName, nFontSize );
//#ifdef _DEBUG
// const char* pTempText = "abc defg, hijklmn";
// DWORD nW, nH;
// GetStringSize( lpszFontName, nFontSize, false, pTempText, strlen(pTempText), &nW, &nH );
// _oprint( "Text Len : [%d] [%d] %s\n", nW, nH, pTempText );
//#endif
return;
}
KTextRender::TEXT_FONT_INFO * KTextRender::_FindFont(LPCSTR lpszFontName, int nFontSize)
{
if( strlen( lpszFontName ) <= 0 ) return NULL;
TEXT_FONT_INFO* info;
hashPr_font::Key key( lpszFontName, nFontSize );
if ( m_mapFontInfo.lookup( key, info ) )
{
return info;
}
return NULL;
}
// MIMI 2005/08/10
void KTextRender::CheckEmoticon( std::string & strText, LPCSTR lpszFontName, int nFontSize, DWORD dwFlag, DWORD & dwWidth, DWORD & dwHeight, bool bStaticSize, float fZPos )
{
//_LEAK_SUN
SAFE_DELETE( m_pEmoticonLayerRender );
m_pEmoticonLayerRender = new KTextEmoticonRender; // [MEMORY_LEAK] 2012. 3. 2 - marine 메모리 해제해줌..
m_pEmoticonLayerRender->CheckEmoticon( strText, lpszFontName, nFontSize, dwFlag, dwWidth, dwHeight, bStaticSize, fZPos );
}
const int KTextRender::GetTextSize( const char* szBuf )
{
// 이모티콘 필터링 한 후 글자수 리턴
//return m_pEmoticonLayerRender->GetTextSize(szBuf);
return KTextEmoticonRender::GetTextSize(szBuf);
}
void KTextRender::GetEmoticonFilterText( std::string & strBuf )
{
KTextEmoticonRender::GetText( strBuf );
}
// KDebugRenderer Implement
KDebugRenderer *KDebugRenderer::s_pDebugRenderer = NULL;
KDebugRenderer::KDebugRenderer()
{
m_vPosition = K3DVector(0.0f,0.0f,KDRE_RENDER_LAYER);
}
void KDebugRenderer::Clear()
{
for(unsigned int i = 0;i < m_vtDebugItem.size(); ++i)
{
m_vtDebugItem.at(i).Destroy();
}
m_vtDebugItem.clear();
}
KDebugRenderer & KDebugRenderer::GetInstance()
{
static KDebugRenderer debugObj;
return debugObj;
}
void KDebugRenderer::Render(KViewportObject * pViewport, DWORD flag, const K3DMatrix * pAttachMat )
{
float fYPos = m_vPosition.y;
for(unsigned int i = 0; i <m_vtDebugItem.size(); ++i)
{
m_vtDebugItem.at(i).SetPosition(m_vPosition.x, fYPos, m_vPosition.z);
m_vtDebugItem.at(i).Render(pViewport);
if(m_vtDebugItem.at(i).pTextPharse)
{
fYPos += m_vtDebugItem.at(i).pTextPharse->GetHeight();
}
}
}
bool KDebugRenderer::AddDebugItem(LPCSTR lpszDebugName, LPCSTR lpszDebugInfo)
{
if( _FindDebugItem(lpszDebugName) != -1)
return false;
DEBUG_ITEM item;
item.SetDebugInfo(lpszDebugName, lpszDebugInfo);
m_vtDebugItem.push_back(item);
return true;
}
bool KDebugRenderer::AddDebugItem(LPCSTR lpszDebugName, double DebugInfo)
{
char buff[512];
sprintf(buff,"%.1f", DebugInfo);
return AddDebugItem(lpszDebugName, buff);
}
bool KDebugRenderer::RemoveDebugItem(LPCSTR lpszDebugName)
{
int nIndex = _FindDebugItem(lpszDebugName);
if(nIndex < 0)
return false;
m_vtDebugItem.at(nIndex).Destroy();
m_vtDebugItem.erase(m_vtDebugItem.begin() + nIndex);
return true;
}
bool KDebugRenderer::ModifyDebugItem(LPCSTR lpszDebugName, LPCSTR lpszDebugInfo)
{
int nIndex = _FindDebugItem(lpszDebugName);
if(nIndex < 0)
return false;
m_vtDebugItem.at(nIndex).SetDebugInfo(lpszDebugName, lpszDebugInfo);
return true;
}
bool KDebugRenderer::ModifyDebugItem(LPCSTR lpszDebugName, double DebugInfo)
{
char buff[512];
sprintf(buff,"%.1f", DebugInfo);
return ModifyDebugItem(lpszDebugName, buff);
}
int KDebugRenderer::_FindDebugItem(LPCSTR lpszDebugName)
{
for(unsigned int i = 0; i < m_vtDebugItem.size(); ++i)
{
if(m_vtDebugItem.at(i).sDebugName == lpszDebugName)
return i;
}
return -1;
}
void KDebugRenderer::DEBUG_ITEM::Destroy()
{
SAFE_DELETE(pTextPharse);
}
void KDebugRenderer::DEBUG_ITEM::SetDebugInfo(LPCSTR lpszDebugName, LPCSTR lpszDebugInfo)
{
sDebugName = lpszDebugName;
SAFE_DELETE(pTextPharse);
DWORD dwWidth =512;
KSize size = KTextPhrase::GetStringSize(lpszDebugInfo, dwWidth);
if(size.width == 0 || size.height == 0)
return;
pTextPharse = new KTextPhrase(size.width, size.height);
#ifdef _COUNTRY_ME_
pTextPharse->SetAlign(KTextParagraph::KTALIGN_LEFT | KTextParagraph::KTALIGN_TOP);
#else
pTextPharse->SetAlign(KTextRender::KTALIGN_LEFT | KTextRender::KTALIGN_TOP);
#endif
pTextPharse->AddString( lpszDebugInfo);
}
void KDebugRenderer::DEBUG_ITEM::SetPosition(float fXPos, float fYPos, float fZPos)
{
if(pTextPharse)
{
pTextPharse->SetPosition(fXPos,fYPos,fZPos);
}
}
void KDebugRenderer::DEBUG_ITEM::Render(KViewportObject * pViewportObject)
{
if(pTextPharse)
{
pTextPharse->Render(pViewportObject);
}
}
//추가
int KTextRender::CalcCarretPos( const char *szAlias, const wchar_t *wszString, int x,int nFontSize, int ft )
{
// assert( _CrtCheckMemory() );
return KTextRender::s_pFreeType->CalcCarretPos(szAlias, nFontSize, ft,wszString, x );
}
void KTextRender::GetFreeTypeTextWidth( const wchar_t *text, size_t len, LPSIZE lpSize )
{
lpSize->cx = 0;
lpSize->cy = 13;
// assert( _CrtCheckMemory() );
KTextRender::s_pFreeType->GetSize( KTextRender::KDEFAULT_FONT_NAME, text, (int*)&lpSize->cx, NULL, 13 );
}
// 2010.05.06 - prodongi
void KTextRender::modifyEmoticonSize(std::string const& aniName, int width, int height)
{
if (!m_pEmoticonLayerRender) return ;
m_pEmoticonLayerRender->modifyEmoticonSize(aniName, width, height);
}
void KTextRender::setSpriteScroll(bool scroll, DWORD type, float v, float margin) /// 2011.01.18 - prodongi
{
m_prSprite->initScroll(scroll, type, v, margin);
}
#ifdef _COUNTRY_ME_
BYTE Get5x5FilteredAlphaValue( LPBYTE pSrc, int x, int y, int w, int h, int nStride )
{
static double dWeight[5][5] =
{
{ 0.0, 0.1, 0.2, 0.1, 0.0 },
{ 0.1, 0.3, 0.5, 0.3, 0.1 },
{ 0.2, 0.5, 0.7, 0.5, 0.2 },
{ 0.1, 0.3, 0.5, 0.3, 0.1 },
{ 0.0, 0.1, 0.2, 0.1, 0.0 }
};
double dAlpha = 0.;
LPDWORD pdwValue;
KColor color;
for ( int i = -2; i < 3; ++i )
{
if ( y + i >= 0 && y + i < h )
{
for ( int j = -2; j < 3; ++j )
{
if ( x + j >= 0 && x + j < w )
{
pdwValue = (LPDWORD)(pSrc + (x + j) * 4 + (y + i) * nStride);
color = *pdwValue;
dAlpha += color.a * dWeight[i + 2][j + 2];
}
}
}
}
if ( dAlpha > 255 )
dAlpha = 255;
return (BYTE)(dAlpha);
}
void BitBlt_Premultiplied2Nonmultiplied( LPVOID pSrc, LPVOID pDst, int nWidth, int nHeight, int nSrcStride, int nDstStride, bool bGlow )
{
LPBYTE pbSrc = (LPBYTE)pSrc;
LPBYTE pbDst = (LPBYTE)pDst;
LPDWORD pdwSrc, pdwDst;
KColor pxSrc, pxDst;
int x, y;
if ( bGlow )
{
for ( y = 0; y < nHeight; y++ )
{
pdwDst = (DWORD *)pbDst;
for( x = 0; x < nWidth; x++ )
{
BYTE bAlpha = Get5x5FilteredAlphaValue( pbSrc, x, y, nWidth, nHeight, nSrcStride );
if ( bAlpha > 0 )
{
pxDst.a = bAlpha;
pxDst.g = 0;
pxDst.b = 74;
pxDst.r = 128;
*pdwDst++ = pxDst.color;
}
else
*pdwDst++ = 0;
}
pbDst += nDstStride;
}
}
pbSrc = (LPBYTE)pSrc;
pbDst = (LPBYTE)pDst;
for ( y = 0; y < nHeight; y++ )
{
pdwSrc = (DWORD *)pbSrc;
pdwDst = (DWORD *)pbDst;
for( x = 0; x < nWidth; x++ )
{
pxSrc.color = *pdwSrc++;
if ( pxSrc.a > 0 )
{
pxDst.r = pxSrc.r * 255 / pxSrc.a;
pxDst.g = pxSrc.g * 255 / pxSrc.a;
pxDst.b = pxSrc.b * 255 / pxSrc.a;
pxDst.a = pxSrc.a;
*pdwDst++ = pxDst.color;
}
else
*pdwDst++;
}
pbSrc += nSrcStride;
pbDst += nDstStride;
}
}
KTextRender::KTextRender( KTextParagraph* pString, DWORD dwWidth, DWORD dwHeight, DWORD dwLineGap, DWORD dwAlign, bool bRandomColor )
: m_dwWidth( dwWidth ), m_dwHeight( dwHeight ), m_pEmoticonLayerRender( 0 )
{
// InitTextRender가 불려지지 않았으므로
if(!m_pDevice)
{
assert(false && "please call InitTextRender");
}
m_prSprite = new KSpritePrimitive(false);
m_spResSprite = new KResSprite;
if ( dwWidth == 0 || dwHeight == 0 )
return;
DWORD dwOldHeight = dwHeight;
m_spTexture = KTextCacheManager::GetInstance()->FindCache(
pString->GetString().c_str(),
pString->GetAttr()->dwColor,
pString->GetAttr()->strFontName.c_str(),
pString->GetAttr()->nFontSize,
dwWidth, dwHeight,
pString->GetAttrHash(),
pString->GetAttr()->bShadow + pString->GetAttr()->bBold * 2);
if (m_spTexture != NULL)
{
m_spResSprite->SetTexture(m_spTexture, NULL);
m_prSprite->SetRes(m_spResSprite);
return;
}
// 2010.09.07 왜 주석 처리가 되어 있나??? - prodongi
KTextLayout layout( dwWidth, dwHeight, dwLineGap, dwAlign );
layout.Render( pString );
int nStride;
char * pImgBuf32 = NULL;
KRect rcTexRect;
rcTexRect.left = 0; rcTexRect.top = 0; rcTexRect.right = dwWidth; rcTexRect.bottom = dwHeight;
m_spTexture = m_pDevice->CreateTexture(dwWidth,dwHeight, K3DFMT_A8R8G8B8 );
assert( m_spTexture && "m_spTexture = m_pDevice->CreateTexture(dwTexWidth,dwTexHeight, K3DFMT_A8R8G8B8 )");
if(m_spTexture == NULL)
return;
m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32), nStride);
assert( pImgBuf32 && "m_spTexture->LockRect(&rcTexRect, reinterpret_cast<void **>(&pImgBuf32),nStride);");
if( !pImgBuf32 )
return;
// 2010.09.07 왜 주석 처리가 되어 있나??? - prodongi
BitBlt_Premultiplied2Nonmultiplied( layout.GetImage(), pImgBuf32, dwWidth, dwHeight, layout.GetImageStride(), nStride, pString->GetAttr()->bGlow );
m_spTexture->Unlock();
m_spResSprite->SetTexture(m_spTexture, &rcTexRect);
m_prSprite->SetRes(m_spResSprite);
KTextCacheManager::GetInstance()->RegisterCache(
pString->GetString().c_str(),
pString->GetAttr()->dwColor,
pString->GetAttr()->strFontName.c_str(),
pString->GetAttr()->nFontSize,
dwWidth, dwHeight,
pString->GetAttrHash(),
pString->GetAttr()->bShadow + pString->GetAttr()->bBold * 2,
m_spTexture);
}
#endif