3729 lines
103 KiB
C++
3729 lines
103 KiB
C++
// KTextParser.cpp: implementation of the KTextParser class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "KTextParser.h"
|
|
#include "KTextRender.h"
|
|
|
|
#include <toolkit/nsl.h>
|
|
|
|
#ifdef _COUNTRY_TL_
|
|
#include "./Localization/Thailand.h"
|
|
#endif
|
|
|
|
#ifdef _COUNTRY_ME_
|
|
#include "./Localization/MiddleEast.h"
|
|
|
|
KTextParser::StringTableHandler* KTextParser::s_pStringTableHandler;
|
|
KTextParser::mapEmoticon KTextParser::s_mapEmoticonFilter;
|
|
#endif
|
|
|
|
//#include "KNDBManager.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
bool KTextParser::s_bUseWordWrap = false;
|
|
|
|
|
|
KTextParser::KTextParser()
|
|
{
|
|
m_dwCurrentLineWidth = 0;
|
|
#ifndef _COUNTRY_ME_
|
|
m_CurrentTP.Init();
|
|
#endif
|
|
m_dwHAlign = KTextRender::KTALIGN_HCENTER;m_dwVAlign = KTextRender::KTALIGN_VCENTER;
|
|
m_bEditMode = false;
|
|
}
|
|
|
|
KTextParser::~KTextParser()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
// 2010.06.08 - prodongi
|
|
int KTextParser::AddString(LPCSTR lpszString, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit, bool scroll )
|
|
//int KTextParser::AddString(LPCSTR lpszString, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit)
|
|
{
|
|
#ifdef _COUNTRY_TL_
|
|
//태국에서 준 워드 브레이크 버그 문자열
|
|
//첫번째 <WB>태그를 넘겨 주는 버그가 있음
|
|
//2009-05-19 : hunee
|
|
//LPCSTR PPP = "睾納죵芽羽밝杆췬↕瓮擡ℓ紀";
|
|
//lpszString = PPP;
|
|
|
|
// 왠지 영문자와 숫자만으로 구성된 작은스트링들은 설정된 폭이 너무 작아서 이 루틴에서 짤려버리는 일이 많다.
|
|
// 따라서 따로 체크해서 기존루틴으로 처리.
|
|
if (LocalizationTL::isOnlyEnglishWord(lpszString))
|
|
{
|
|
// 2010.06.15 - prodongi
|
|
//_AddString(lpszString, 0, dwMaxWidth, bTagEnable, bUseSplit);
|
|
_AddString(lpszString, 0, dwMaxWidth, bTagEnable, bUseSplit, scroll);
|
|
return (int)m_vtTextPrimitive.size();
|
|
}
|
|
|
|
// 여기부터 복잡한 루틴이 들어갑니다.
|
|
/// 태그가 덕지덕지 붙은 스트링을 태그 다 떼고 잘라내서 순수 텍스트만 가지고 wordbreak를 건 후
|
|
/// 도로 태그를 원래 위치에 붙이는 무식한 코드 by 정동섭
|
|
|
|
TEXT_TOKEN token;
|
|
std::string fontName = "";
|
|
int fontSize = -1;
|
|
int nCount = 0;
|
|
|
|
while(1)
|
|
{
|
|
_GetNextToken(&token, lpszString, nCount);
|
|
if (token.dwType == TEXT_TOKEN::EOS)
|
|
break;
|
|
if (token.dwType == TEXT_TOKEN::FONT)
|
|
fontName = token.sText;
|
|
else if (token.dwType == TEXT_TOKEN::SIZE)
|
|
fontSize = token.dwFontSize;
|
|
} // 일단 이 string이 어떤 폰트와 어떤 크기로 찍히는 것인지를 살펴본다.
|
|
// string 내부에서 폰트와 크기가 여러번 변하는 놈이면 골룸
|
|
// 일단 한 스트링 안에서는 폰트, 크기가 처음부터 끝까지 일정하다고 가정하고 코딩
|
|
|
|
DWORD thaiAlphabetWidth = 0, thaiAlphabetHeight = 0;
|
|
|
|
if (fontName == "") fontName = m_CurrentTP.sFontName.c_str();
|
|
if (fontSize == -1) fontSize = m_CurrentTP.nFontSize;
|
|
|
|
std::vector<std::string> strLines;
|
|
nCount = 0;
|
|
while(1) // 이 루프에서는 <BR> 단위로 스트링을 잘라낸다.
|
|
{ // <BR>이 걸려있는 놈은 어차피 강제로 줄바꿈이 되는 놈일 테니 이놈들 단위로 잘라서 그 사이사이만 워드브레이킹 처리
|
|
strLines.push_back("");
|
|
while(1)
|
|
{
|
|
_GetNextToken(&token, lpszString, nCount);
|
|
// _GetNextToken(&token, test.c_str(), nCount);
|
|
if (token.dwType == TEXT_TOKEN::EOS || token.dwType == TEXT_TOKEN::BREAK)
|
|
break;
|
|
if (token.dwType == TEXT_TOKEN::TEXT)
|
|
strLines.back() += token.sText;
|
|
else
|
|
strLines.back() += token.sTokenText; // < > 을 포함한 태그 전체 문자열이 sTokenText에 들어간다.
|
|
}
|
|
if (token.dwType == TEXT_TOKEN::EOS)
|
|
break;
|
|
}
|
|
|
|
std::string strResult; // 이 변수에 최종결과가 들어간다.
|
|
|
|
for (int i=0; i<strLines.size(); i++) // <BR> 기준으로 잘라진 문자열 각각을 처리
|
|
{
|
|
int tagCount = 0;
|
|
std::vector<std::string> tagVector;
|
|
std::vector<int> tagPosition;
|
|
std::string strText;
|
|
while(1) // 이 루프에서 태그와 순수문자열을 분리한다.
|
|
{
|
|
int nowPos = tagCount;
|
|
_GetNextToken(&token, strLines[i].c_str(), tagCount);
|
|
if (token.dwType == TEXT_TOKEN::EOS)
|
|
break;
|
|
if (token.dwType == TEXT_TOKEN::TEXT)
|
|
strText += token.sText;
|
|
else
|
|
{
|
|
tagPosition.push_back(nowPos);
|
|
tagVector.push_back(token.sTokenText);
|
|
}
|
|
}
|
|
// 이제 tagvector에는 tag들이, strText에는 남겨진 스트링만 있다.
|
|
|
|
std::string strBreaked;
|
|
|
|
while(1)
|
|
{
|
|
const char* p = strText.c_str();
|
|
std::string sLine, sTmp;
|
|
int nCharCount = 0;
|
|
for (; *p != 0; )
|
|
{
|
|
nCharCount++;
|
|
|
|
DWORD nWidth = 0, nHeight = 15;
|
|
char nowChar[10] = {0, };
|
|
const char* p1 = LocalizationTL::CharNextTh(p);
|
|
memcpy(nowChar, p, p1-p);
|
|
p = p1;
|
|
sLine += nowChar;
|
|
// 이 스트링이 쓰여질 말칸에 주어진 스트링의 첫부분부터 세어서 몇글자나 들어갈지 체크하는 부분
|
|
// 여기까지 초 무식한 코드로 문자열 시작지점에서부터 1글자씩 증가시켜 나가면서
|
|
// 계속 부분 문자열 너비를 구해서 말칸의 너비를 초과하는 시점을 찾는다.
|
|
// 가변폭 폰트이기때문에 이럴 수 밖에 없었다.
|
|
KTextRender::GetStringSize(fontName.c_str(), fontSize, false, sLine.c_str(),(int)sLine.size(),&nWidth, &nHeight);
|
|
|
|
if (nWidth > dwMaxWidth)
|
|
{
|
|
LocalizationTL::g_TEWordBreak.n_ch = nCharCount-2; // 왜인지 정확히 모르겠는데 1글자 오버하는 경우가..
|
|
sTmp = LocalizationTL::g_TEWordBreak.BreakString(strText.c_str()); // 태국어 워드브레이킹을 건다.
|
|
break;
|
|
}
|
|
}
|
|
if (*p == 0)
|
|
{ // 이리로 빠졌으면 문자열 끝까지 돌았지만 말칸 너비를 초과 안 한 경우
|
|
strBreaked += strText; // 이 경우엔 워드브레이킹 필요 없음
|
|
break;
|
|
}
|
|
|
|
int nBR = sTmp.find("<WB>"); // 워드브레이킹 결과를 찾는다.
|
|
while (nBR == 0)
|
|
{
|
|
sTmp = sTmp.substr(4);
|
|
nBR = sTmp.find("<WB>");
|
|
}
|
|
|
|
if (nBR == std::string::npos)
|
|
{ // 워드브레이킹을 걸었지만 줄바꿈이 안 되었을 경우
|
|
strBreaked += sTmp; // 더이상의 처리 필요 없음
|
|
break;
|
|
}
|
|
else
|
|
{ // 줄바꿈이 되었을 경우
|
|
strBreaked += sTmp.substr(0, nBR); // 첫줄만 떼넨다.
|
|
strBreaked += "<WB>";
|
|
strText = strText.substr(nBR); // 나머지 부분을 가지고 처음부터 반복
|
|
} // 문자열이 다르면 한줄에 들어갈 글자수가 달라지기 때문에 처음부터 다시 세어야 함 (이놈의 가변폭 폰트..)
|
|
}
|
|
|
|
int BRcount = 0;
|
|
std::vector<int> BRPosition;
|
|
while(1)
|
|
{
|
|
_GetNextToken(&token, strBreaked.c_str(), BRcount);
|
|
if (token.dwType == TEXT_TOKEN::EOS)
|
|
break;
|
|
if (token.dwType == TEXT_TOKEN::BREAK)
|
|
BRPosition.push_back(BRcount-4);
|
|
}
|
|
// 이제 새로 생긴 <BR>이 어디 붙어있는지 모두 체크했다.
|
|
// 이제 도로 tag들을 원래 위치에 끼워 넣자
|
|
|
|
for (int j=0; j<tagVector.size(); j++)
|
|
{
|
|
int pos = tagPosition[j];
|
|
int prevBR = 0; // 이 tag 앞에 <BR> 이 몇개나 있냐?
|
|
for (int k=0; k<BRPosition.size(); k++)
|
|
{
|
|
if (BRPosition[k] > tagPosition[j] + (prevBR * 4)) break; // 이 태그 앞에 <WB>가 몇개나 있나 올바르게 찾으려면 태그 위치에
|
|
prevBR++; // 그 앞에 <WB>가 삽입되어서 밀려난 거리를 더해준 거리까지 감안해야 한다.
|
|
}
|
|
pos += (prevBR * 4); // tag 앞에 워드브레이킹때문에 새로 생긴 <BR>의 갯수*4만큼 tag의 위치를 뒤로 밀어야 제 위치로 들어간다.. <BR>이 4글자니까
|
|
strBreaked.insert(pos, tagVector[j]);
|
|
// 삽입된 tag의 길이만큼 그 tag 뒤에 있는 BR의 위치를 뒤로 밀어줘야 나중에 계산이 맞는다..
|
|
for (int k=0; k<BRPosition.size(); k++)
|
|
{
|
|
if (BRPosition[k] > tagPosition[j])
|
|
{
|
|
BRPosition[k] += tagVector[j].length();
|
|
}
|
|
}
|
|
}
|
|
|
|
strResult += strBreaked; // 모두 됐으면 원래 문자열을 만든다.
|
|
if (i < strLines.size()-1) // <BR>태그도 알맞게 넣어 준다.
|
|
strResult += "<BR>";
|
|
}
|
|
|
|
// 2010.06.08 - prodongi
|
|
_AddString(strResult.c_str(), 0, dwMaxWidth, bTagEnable, bUseSplit, scroll);
|
|
//_AddString(strResult.c_str(), 0, dwMaxWidth, bTagEnable, bUseSplit);
|
|
#else
|
|
// 2010.06.08 - prodongi
|
|
_AddString(lpszString, 0, dwMaxWidth, bTagEnable, bUseSplit, scroll );
|
|
//_AddString(lpszString, 0, dwMaxWidth, bTagEnable, bUseSplit);
|
|
#endif
|
|
|
|
#ifdef _COUNTRY_ME_
|
|
return (int)m_vtTextParagraph.size();
|
|
#else
|
|
return (int)m_vtTextPrimitive.size();
|
|
#endif
|
|
|
|
}
|
|
|
|
//#define _OLD_WORD_WRAP_
|
|
|
|
#ifdef _OLD_WORD_WRAP_
|
|
|
|
// 2010.06.08 - prodongi
|
|
void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit, bool scroll)
|
|
//void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit)
|
|
{
|
|
int nCount = 0;
|
|
BOOL bLoop = TRUE;
|
|
|
|
while ( bLoop)
|
|
{
|
|
m_CurrentTP.dwCount = nCount;
|
|
TEXT_TOKEN token;
|
|
if(!bTagEnable)
|
|
{
|
|
token.sText = lpszString;
|
|
token.dwType = TEXT_TOKEN::TEXT;
|
|
}
|
|
else
|
|
{
|
|
_GetNextToken(&token, lpszString, nCount);
|
|
}
|
|
|
|
switch(token.dwType)
|
|
{
|
|
case TEXT_TOKEN::TEXT:
|
|
{
|
|
// 줄바꿈이 있을때만 따로 리스트에 저장
|
|
if(m_CurrentTP.nBreak > 0 || m_CurrentTP.nPageBreak > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nBreak = m_CurrentTP.nPageBreak = 0; //줄바꿈 초기화
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
}
|
|
// 텍스트가 있으면
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
m_CurrentTP.sText += token.sText;
|
|
BOOL bBold = m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD; //BOLD 검사
|
|
DWORD dwStrWidth = 0, dwStrHeight = 0;
|
|
|
|
//문자열 가로,세로 얻기
|
|
/*KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size(),&dwStrWidth, &dwStrHeight);*/
|
|
std::string strTemp = m_CurrentTP.sText;
|
|
KTextRender::GetEmoticonFilterText( strTemp );
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
strTemp.c_str(),(int)strTemp.size(),&dwStrWidth, &dwStrHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize( "default", m_CurrentTP.nFontSize, bBold,
|
|
strTemp.c_str(),(int)strTemp.size(),&dwStrWidth, &dwStrHeight);
|
|
}
|
|
|
|
//현재 라인 가로 크기에 스트링 가로 크기 더하기
|
|
m_dwCurrentLineWidth += dwStrWidth;
|
|
|
|
// 한줄을 넘기게 되면 linebreak를 걸어주자
|
|
if( m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
//더해진 가로 크기에 스트링 가로 크기 다시 빼기
|
|
m_dwCurrentLineWidth -= dwStrWidth;
|
|
|
|
// 추가된 Primitive를 Line size로 자르자.
|
|
while (1)
|
|
{
|
|
int nBackLast_Space = 0;
|
|
int nOldLast_Space = 0;
|
|
int nLast_Space = 0;
|
|
int nMaxStr = 0;
|
|
DWORD dwWidth = 0, dwHeight = 0;
|
|
|
|
char * psz1 = const_cast<char *>(m_CurrentTP.sText.c_str());
|
|
char * psz2 = psz1;
|
|
char * last_space = NULL;
|
|
char * Oldlast_space = NULL;
|
|
char * Backlast_space = NULL;
|
|
|
|
|
|
// dwMaxWidth에 걸맞는 Size를 찾자.
|
|
int nWordSize = 0 ;
|
|
while(1)
|
|
{
|
|
if( !(*psz1) ) break;
|
|
psz2 = CharNext(psz1);
|
|
nMaxStr++;
|
|
|
|
if( (psz2 - psz1) == 2)
|
|
{
|
|
// 한 글자가 2byte 인 경우 (ex: 한글)
|
|
nMaxStr++;
|
|
|
|
nBackLast_Space = nOldLast_Space;
|
|
Backlast_space = Oldlast_space;
|
|
|
|
//이전 ' '
|
|
nOldLast_Space = nLast_Space;
|
|
Oldlast_space = last_space;
|
|
|
|
last_space = psz2+1; //' '의 다음문자 지정
|
|
nLast_Space = nMaxStr; //' '까지의 길이
|
|
}
|
|
|
|
if( *psz2 == ' ' )
|
|
{
|
|
nBackLast_Space = nOldLast_Space;
|
|
Backlast_space = Oldlast_space;
|
|
|
|
//이전 ' '
|
|
nOldLast_Space = nLast_Space;
|
|
Oldlast_space = last_space;
|
|
|
|
last_space = psz2+1; //' '의 다음문자 지정
|
|
nLast_Space = nMaxStr; //' '까지의 길이
|
|
}
|
|
|
|
nWordSize++;
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
}
|
|
|
|
// 문자 하나의 size가 maxwidth를 넘는 경우 그냥 하나 단위로 짜름
|
|
if(nWordSize == 1 && dwWidth > dwMaxWidth)
|
|
break;
|
|
|
|
// 바로 전 글자까지만 짜르면 된다.
|
|
if(m_dwCurrentLineWidth + dwWidth > dwMaxWidth)
|
|
{
|
|
// 이경우 2byte중 1byte만 남게 된 경우므로
|
|
// 아예 2byte를 다 잘라 버린다.
|
|
nMaxStr -= int(psz2 - psz1);
|
|
|
|
//위치가 앞으로 이동 된 경우
|
|
if( nMaxStr < nLast_Space )
|
|
{
|
|
if( nOldLast_Space == nLast_Space )
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nBackLast_Space;
|
|
last_space = Backlast_space;
|
|
}
|
|
else
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nOldLast_Space;
|
|
last_space = Oldlast_space;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
psz1 = psz2;
|
|
}
|
|
|
|
// 이미 한줄이 꽉찬 상태에서 새로 Text가 추가 되면
|
|
// 그냥 줄바꿈만 해주고 다시 계산해 준다.
|
|
if(nMaxStr == 0)
|
|
{
|
|
if(m_vtTextPrimitive.size() > 0)
|
|
m_vtTextPrimitive.back().bIsLineBreak = true; //줄바꿈 설정
|
|
|
|
m_dwCurrentLineWidth = 0;
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
// 다시 줄의 넓이를 계산한다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
}
|
|
|
|
// 만약 한줄에 다 들어가면 Loop 탈출
|
|
if(dwWidth < dwMaxWidth)
|
|
{
|
|
m_dwCurrentLineWidth = dwWidth;
|
|
break;
|
|
}
|
|
// 그게 아니면 다시 계산
|
|
else
|
|
continue;
|
|
}
|
|
|
|
std::string s;
|
|
|
|
// 자른후에 사용할 string 저장
|
|
int nCutSize = nMaxStr;
|
|
|
|
if( s_bUseWordWrap )
|
|
{
|
|
//크기가 모자람
|
|
if( nMaxStr < nLast_Space )
|
|
{
|
|
if( nOldLast_Space == nLast_Space )
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nBackLast_Space;
|
|
}
|
|
else
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nOldLast_Space;
|
|
}
|
|
}
|
|
|
|
if( nLast_Space != 0 )
|
|
nCutSize = nLast_Space;
|
|
}
|
|
|
|
s = m_CurrentTP.sText.c_str() + nCutSize;
|
|
|
|
// _performance_print( "백업 %s\n", s.c_str() );
|
|
|
|
// 다음행의 시작 스페이스는 날린다
|
|
while( nMaxStr && !s.empty() && s[0] == ' ' ) s.erase( 0, 1 );
|
|
|
|
m_CurrentTP.sText.resize(nCutSize); //크기 재설정
|
|
m_CurrentTP.bIsLineBreak = true; //줄바꿈 설정
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
|
|
// _performance_print( "저장 %s\n", m_CurrentTP.sText.c_str() );
|
|
|
|
//새로 시작
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
m_CurrentTP.sText = s; //복구
|
|
|
|
//땜방
|
|
// 남은 string이 한줄을 넘지 않는다면 loop 를 탈출!!
|
|
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
|
|
m_dwCurrentLineWidth = 0;
|
|
if(dwWidth <= dwMaxWidth)
|
|
{
|
|
// 현재남은 Line의 길이를 기억해야 한다.
|
|
m_dwCurrentLineWidth = dwWidth;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!bTagEnable)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
m_dwCurrentLineWidth = 0;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::TEXTCMD:
|
|
_AddString(token.sText.c_str(), nDepth + 1, dwMaxWidth,bTagEnable,bUseSplit);
|
|
break;
|
|
case TEXT_TOKEN::FONT:
|
|
// Font의 종류가 다르면
|
|
if(m_CurrentTP.sFontName != token.sText)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.sFontName = token.sText;
|
|
|
|
KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::SIZE:
|
|
if(m_CurrentTP.nFontSize != (int)token.dwFontSize)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.nFontSize = token.dwFontSize;
|
|
KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OFFSET:
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.dwOffset = token.dwOffset;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::COLOR:
|
|
// Color가 다르면
|
|
if(m_CurrentTP.Color.color != token.dwColor )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.Color = token.dwColor;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::BOLD:
|
|
if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD))
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Bold bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_BOLD;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNBOLD:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Bold bit Clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_BOLD;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNDER_LINE:
|
|
if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER))
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Underline bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_UNDER;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNDER_LINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Underline bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_UNDER;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::STRIKE_LINE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_STRIKE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::STRIKE_LINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_STRIKE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::SHADOW:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_SHADOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::SHADOWOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_SHADOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OUTLINE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_OUTLINE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OUTLINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_OUTLINE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOWOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::COLOR_FX:
|
|
{
|
|
if(m_CurrentTP.ColorFX.color != token.dwColor )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.ColorFX = token.dwColor;
|
|
}
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW2X:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW2X;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW2XOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW2X;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::INVERSE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_INVERSE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::INVERSE_OFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_INVERSE;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::BREAK:
|
|
m_CurrentTP.nBreak++;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.nBreak = 0;
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_dwCurrentLineWidth = 0;
|
|
break;
|
|
case TEXT_TOKEN::PAGEBREAK:
|
|
m_CurrentTP.nPageBreak++;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.nPageBreak = 0;
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_dwCurrentLineWidth = 0;
|
|
break;
|
|
case TEXT_TOKEN::EMOTICON:
|
|
case TEXT_TOKEN::NX3:
|
|
{
|
|
// Icon의 크기는 기본적으로 현재 Font Size의 2배
|
|
m_dwCurrentLineWidth += m_CurrentTP.nFontSize * 2;
|
|
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
// 줄을 넘어가면 줄바꿈을 해주자
|
|
if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
m_CurrentTP.bIsLineBreak = true;
|
|
m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
}
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// 그 전에 Text아닌 다른걸 넣었다면
|
|
else if(m_vtTextPrimitive.size() > 0 && m_vtTextPrimitive.back().dwIconType != KICON_TEXT)
|
|
{
|
|
// 줄을 넘어가면 줄바꿈을 해주자
|
|
if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
m_vtTextPrimitive.back().bIsLineBreak = true;
|
|
m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
}
|
|
}
|
|
|
|
// 한줄의 크기가 Icon보다 작은 경우는 전혀 고려하지 않았다
|
|
m_CurrentTP.dwIconType = token.dwType - TEXT_TOKEN::EMOTICON + KICON_EMOTICON;
|
|
m_CurrentTP.dwIconID = token.dwIconID;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.dwIconType = KICON_TEXT;
|
|
break;
|
|
}
|
|
|
|
case TEXT_TOKEN::HALIGN:
|
|
m_dwHAlign = token.dwAlign;
|
|
break;
|
|
|
|
case TEXT_TOKEN::VALIGN:
|
|
m_dwVAlign = token.dwAlign;
|
|
break;
|
|
// End Of String
|
|
case TEXT_TOKEN::EOS:
|
|
if(nDepth == 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_dwCurrentLineWidth = 0;
|
|
m_CurrentTP.Init();
|
|
}
|
|
bLoop = FALSE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
#ifndef _COUNTRY_ME_
|
|
|
|
|
|
//// 2010.06.08 - prodongi
|
|
//void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit, bool scroll, bool bUseSplitOffset/*false*/)
|
|
////void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit)
|
|
//{
|
|
// int nCount = 0;
|
|
// BOOL bLoop = TRUE;
|
|
//
|
|
// // 텍스트의 중간중간에 섞인 태그를 보관. bintitle. 2010.09.29.
|
|
// std::string strOldToken, strOldText, strOldTokenLineBreak;
|
|
//
|
|
// while ( bLoop)
|
|
// {
|
|
// m_CurrentTP.dwCount = nCount;
|
|
// TEXT_TOKEN token;
|
|
// token.dwType = TEXT_TOKEN::NONE;
|
|
//
|
|
// if(!bTagEnable)
|
|
// {
|
|
// token.sText = lpszString;
|
|
// token.dwType = TEXT_TOKEN::TEXT;
|
|
// }
|
|
// else
|
|
// {
|
|
// _GetNextToken(&token, lpszString, nCount);
|
|
// }
|
|
//
|
|
// // 텍스트의 중간중간에 섞인 태그를 보관. bintitle. 2010.09.29.
|
|
// if( bUseSplitOffset && !strOldText.empty() && token.dwType != TEXT_TOKEN::NONE && token.dwType != TEXT_TOKEN::TEXT &&
|
|
// !token.sTokenText.empty() && token.sTokenText != strOldToken )
|
|
// {
|
|
// strOldTokenLineBreak = strOldToken = token.sTokenText;
|
|
// strOldText.erase();
|
|
// }
|
|
//
|
|
// switch(token.dwType)
|
|
// {
|
|
// case TEXT_TOKEN::TEXT:
|
|
// {
|
|
// // 줄바꿈이 있을때만 따로 리스트에 저장
|
|
// if(m_CurrentTP.nBreak > 0 || m_CurrentTP.nPageBreak > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.sText.erase();
|
|
// m_CurrentTP.nBreak = m_CurrentTP.nPageBreak = 0; //줄바꿈 초기화
|
|
// m_CurrentTP.bIsLineBreak = false;
|
|
// }
|
|
// // 텍스트가 있으면
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// std::string s;
|
|
// s = lpszString+nCount;
|
|
// if( !s.empty() && s[0] != ' ' )
|
|
// m_CurrentTP.bContinue = true;
|
|
//
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.bContinue = false;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// if (token.sText.find("<WB>") != std::string::npos)
|
|
// {
|
|
// int xxxx=1;
|
|
// }
|
|
//
|
|
// // 보관한 태그를 끼워넣기. bintitle. 2010.29.
|
|
// if( bUseSplitOffset && !strOldToken.empty() && !token.sText.empty() && m_vtTextPrimitive.size() > 0 )
|
|
// {
|
|
// m_CurrentTP.sText += strOldToken + token.sText;
|
|
// strOldToken.erase();
|
|
// }
|
|
// else
|
|
// {
|
|
// m_CurrentTP.sText += token.sText;
|
|
// strOldText = token.sText;
|
|
// }
|
|
//
|
|
// // 이전.
|
|
// //m_CurrentTP.sText += token.sText;
|
|
//
|
|
// BOOL bBold = m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD; //BOLD 검사
|
|
// DWORD dwStrWidth = 0, dwStrHeight = 0;
|
|
//
|
|
// //문자열 가로,세로 얻기
|
|
// /*KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size(),&dwStrWidth,
|
|
//
|
|
// &dwStrHeight);*/
|
|
// std::string strTemp = m_CurrentTP.sText;
|
|
// KTextRender::GetEmoticonFilterText( strTemp );
|
|
//
|
|
// //땜방, sFontName 값이 없다.
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// strTemp.c_str(),(int)strTemp.size(),&dwStrWidth,
|
|
//
|
|
// &dwStrHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize( "default", m_CurrentTP.nFontSize, bBold,
|
|
// strTemp.c_str(),(int)strTemp.size(),&dwStrWidth, &dwStrHeight);
|
|
// }
|
|
//
|
|
// //현재 라인 가로 크기에 스트링 가로 크기 더하기
|
|
// m_dwCurrentLineWidth += dwStrWidth;
|
|
//
|
|
// // 한줄을 넘기게 되면 linebreak를 걸어주자
|
|
// // 2010.06.03 - prodongi
|
|
// if( !scroll && (m_dwCurrentLineWidth > dwMaxWidth))
|
|
// //if( m_dwCurrentLineWidth > dwMaxWidth)
|
|
// {
|
|
// //더해진 가로 크기에 스트링 가로 크기 다시 빼기
|
|
// m_dwCurrentLineWidth -= dwStrWidth;
|
|
//
|
|
// // 추가된 Primitive를 Line size로 자르자.
|
|
// while (1)
|
|
// {
|
|
// int nBackLast_Space = 0;
|
|
// int nOldLast_Space = 0;
|
|
// int nLast_Space = 0;
|
|
// int nMaxStr = 0;
|
|
// DWORD dwWidth = 0, dwHeight = 0;
|
|
//
|
|
// char * psz1 = const_cast<char *>(m_CurrentTP.sText.c_str());
|
|
// char * psz2 = psz1;
|
|
// char * last_space = NULL;
|
|
// char * Oldlast_space = NULL;
|
|
// char * Backlast_space = NULL;
|
|
//
|
|
//
|
|
// // dwMaxWidth에 걸맞는 Size를 찾자.
|
|
// int nWordSize = 0 ;
|
|
// while(1)
|
|
// {
|
|
// if( !(*psz1) ) break;
|
|
// psz2 = CharNext(psz1);
|
|
// nMaxStr++;
|
|
//
|
|
// if( (psz2 - psz1) == 2)
|
|
// {
|
|
// // 한 글자가 2byte 인 경우 (ex: 한글)
|
|
// nMaxStr++;
|
|
//
|
|
// nBackLast_Space = nOldLast_Space;
|
|
// Backlast_space = Oldlast_space;
|
|
//
|
|
// //이전 ' '
|
|
// nOldLast_Space = nLast_Space;
|
|
// Oldlast_space = last_space;
|
|
//
|
|
// last_space = psz2+1; //' '의 다음문자 지정
|
|
// nLast_Space = nMaxStr; //' '까지의 길이
|
|
// }
|
|
//
|
|
// if( *psz2 == ' ' )
|
|
// {
|
|
// nBackLast_Space = nOldLast_Space;
|
|
// Backlast_space = Oldlast_space;
|
|
//
|
|
// //이전 ' '
|
|
// nOldLast_Space = nLast_Space;
|
|
// Oldlast_space = last_space;
|
|
//
|
|
// last_space = psz2+1; //' '의 다음문자 지정
|
|
// nLast_Space = nMaxStr; //' '까지의 길이
|
|
// }
|
|
//
|
|
// nWordSize++;
|
|
//
|
|
// //땜방, sFontName 값이 없다.
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
// }
|
|
//
|
|
// // 문자 하나의 size가 maxwidth를 넘는 경우 그냥 하나 단위로 짜름
|
|
// if(nWordSize == 1 && dwWidth > dwMaxWidth)
|
|
// break;
|
|
//
|
|
// // 바로 전 글자까지만 짜르면 된다.
|
|
// if(m_dwCurrentLineWidth + dwWidth > dwMaxWidth)
|
|
// {
|
|
// // 이경우 2byte중 1byte만 남게 된 경우므로
|
|
// // 아예 2byte를 다 잘라 버린다.
|
|
// nMaxStr -= int(psz2 - psz1);
|
|
//
|
|
// //위치가 앞으로 이동 된 경우
|
|
// if( nMaxStr < nLast_Space )
|
|
// {
|
|
// if( nOldLast_Space == nLast_Space )
|
|
// {
|
|
// //이전 ' ' 으로 복구
|
|
// nLast_Space = nBackLast_Space;
|
|
// last_space = Backlast_space;
|
|
// }
|
|
// else
|
|
// {
|
|
// //이전 ' ' 으로 복구
|
|
// nLast_Space = nOldLast_Space;
|
|
// last_space = Oldlast_space;
|
|
// }
|
|
// }
|
|
//
|
|
// break;
|
|
// }
|
|
// psz1 = psz2;
|
|
// }
|
|
//
|
|
// // 이미 한줄이 꽉찬 상태에서 새로 Text가 추가 되면
|
|
// // 그냥 줄바꿈만 해주고 다시 계산해 준다.
|
|
// if(nMaxStr == 0)
|
|
// {
|
|
// if(m_vtTextPrimitive.size() > 0)
|
|
// m_vtTextPrimitive.back().bIsLineBreak = true; //줄바꿈 설정
|
|
//
|
|
// m_dwCurrentLineWidth = 0;
|
|
//
|
|
// //땜방, sFontName 값이 없다.
|
|
// // 다시 줄의 넓이를 계산한다.
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(),m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(),m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
// }
|
|
//
|
|
// // 만약 한줄에 다 들어가면 Loop 탈출
|
|
// if(dwWidth < dwMaxWidth)
|
|
// {
|
|
// m_dwCurrentLineWidth = dwWidth;
|
|
// break;
|
|
// }
|
|
// // 그게 아니면 다시 계산
|
|
// else
|
|
// continue;
|
|
// }
|
|
//
|
|
// std::string s;
|
|
//
|
|
// // 자른후에 사용할 string 저장
|
|
// int nCutSize = nMaxStr;
|
|
//
|
|
// if( s_bUseWordWrap )
|
|
// {
|
|
// //크기가 모자람
|
|
// if( nMaxStr < nLast_Space )
|
|
// {
|
|
// if( nOldLast_Space == nLast_Space )
|
|
// {
|
|
// //이전 ' ' 으로 복구
|
|
// nLast_Space = nBackLast_Space;
|
|
// }
|
|
// else
|
|
// {
|
|
// //이전 ' ' 으로 복구
|
|
// nLast_Space = nOldLast_Space;
|
|
// }
|
|
// }
|
|
//
|
|
// if( nLast_Space != 0 )
|
|
// nCutSize = nLast_Space;
|
|
// }
|
|
//
|
|
// s = m_CurrentTP.sText.c_str() + nCutSize;
|
|
//
|
|
// // _performance_print( "백업 %s\n", s.c_str() );
|
|
//
|
|
// // 다음행의 시작 스페이스는 날린다
|
|
// while( nMaxStr && !s.empty() && s[0] == ' ' ) s.erase( 0, 1 );
|
|
//
|
|
// m_CurrentTP.sText.resize(nCutSize); //크기 재설정
|
|
// m_CurrentTP.bIsLineBreak = true; //줄바꿈 설정
|
|
//
|
|
// if( s_bUseWordWrap )
|
|
// {
|
|
// //땜방, sFontName 값이 없다.
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(), nCutSize, &dwWidth, &dwHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(), nCutSize, &dwWidth, &dwHeight);
|
|
// }
|
|
//
|
|
// if( dwWidth <= dwMaxWidth )
|
|
// {
|
|
// if( nLast_Space != 0 && nMaxStr != nLast_Space )
|
|
// {
|
|
// //Space 몇개 있는가?
|
|
// std::vector<std::string> vecText;
|
|
// nsl::split( m_CurrentTP.sText.c_str(), vecText, " ", false );
|
|
//
|
|
// if( vecText.size()>1 )
|
|
// {
|
|
// std::string strText, strTemp;
|
|
// DWORD checkWidth, checkHeight, accumWidth;
|
|
// accumWidth = checkWidth = checkHeight = 0;
|
|
//
|
|
// std::vector<DWORD> vecTextWidthList;
|
|
//
|
|
// //단어들의 길이 계산
|
|
// for( unsigned int k(0); vecText.size()>k; k++ )
|
|
// {
|
|
// //땜방, sFontName 값이 없다.
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(),
|
|
//
|
|
// m_CurrentTP.nFontSize, bBold,
|
|
// vecText[k].c_str(), vecText[k].length(), &checkWidth,
|
|
//
|
|
// &checkHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", m_CurrentTP.nFontSize,
|
|
//
|
|
// bBold,
|
|
// vecText[k].c_str(), vecText[k].length(), &checkWidth,
|
|
//
|
|
// &checkHeight);
|
|
// }
|
|
//
|
|
// vecTextWidthList.push_back( checkWidth );
|
|
// accumWidth += checkWidth;
|
|
// }
|
|
//
|
|
// //여백 계산
|
|
// unsigned int nTotalBlankWidth = (dwMaxWidth-m_dwCurrentLineWidth)-(accumWidth);
|
|
// // 1줄에 여러 개의 primitive가 들어갈 경우 첫 primitive가 아닌 2번째 이상의 primitive에서 줄바꿈이 일어날 경우 줄바꿈 될 텍스트를 좌우정렬하려는 과정에서
|
|
// // 이미 앞에 들어가 있던 문자의 길이를 무시하려 하기 때문에 무조건 0부터 끝까지 기준으로 좌우정렬하려고 해서
|
|
// // 이미 있던 글자와 겹쳐지는 문제가 발생한다. 그래서 어디서부터 끝까지 좌우맞춤을 할 것인지 확실하게 정하기 위해 (dwMaxWidth-m_dwCurrentLineWidth) 로 고침
|
|
// //Blank의 길이 계산
|
|
// unsigned int nBlankWidth = nTotalBlankWidth/(vecText.size()-1);
|
|
// int accumWidthTemp = m_dwCurrentLineWidth;
|
|
// accumWidth = 0;
|
|
//
|
|
// for( unsigned int k(0); vecText.size()>k; k++ )
|
|
// {
|
|
// if( !bUseSplit )
|
|
// {
|
|
// m_CurrentTP.dwOffset = accumWidth;
|
|
//
|
|
// //마지막
|
|
// if( k == vecText.size()-1 )
|
|
// m_CurrentTP.bIsLineBreak = true;
|
|
// else
|
|
// m_CurrentTP.bIsLineBreak = false;
|
|
//
|
|
// m_CurrentTP.sText = vecText[k].c_str();
|
|
//
|
|
// if( nBlankWidth == nTotalBlankWidth )
|
|
// m_CurrentTP.nBlankWidth = 4;
|
|
// else
|
|
// m_CurrentTP.nBlankWidth = nBlankWidth;
|
|
//
|
|
// m_CurrentTP.bIsWordWrap = true;
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// }
|
|
// else
|
|
// {
|
|
// if( k==0 )
|
|
// {
|
|
// strText = vecText[k].c_str();
|
|
// }
|
|
// else
|
|
// {
|
|
// strTemp = nsl::format( "<OFFSET:%d>%s", accumWidthTemp, vecText[k].c_str() );
|
|
// }
|
|
//
|
|
// strText += strTemp;
|
|
// }
|
|
//
|
|
// accumWidth += vecTextWidthList[k]; //단어
|
|
// accumWidth += nBlankWidth; //Blank
|
|
// accumWidthTemp += vecTextWidthList[k]; //단어
|
|
// accumWidthTemp += nBlankWidth; //Blank
|
|
//
|
|
//
|
|
//
|
|
// }
|
|
//
|
|
// if( bUseSplit )
|
|
// {
|
|
// m_CurrentTP.bIsLineBreak = true;
|
|
// m_CurrentTP.sText = strText;
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// }
|
|
//
|
|
// m_CurrentTP.nBlankWidth = 0;
|
|
// m_CurrentTP.bIsWordWrap = false;
|
|
// }
|
|
// else
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// }
|
|
// }//if( nLast_Space != 0 && nMaxStr != nLast_Space )
|
|
// else
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// }
|
|
// }//if( dwWidth <= dwMaxWidth )
|
|
// else
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
//// assert(0 && "if( dwWidth <= dwMaxWidth )" );
|
|
// }
|
|
// }//if( s_bUseWordWrap )
|
|
// else
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// }
|
|
//
|
|
// //새로 시작
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.bIsLineBreak = false;
|
|
// m_CurrentTP.bIsWordWrap = false;
|
|
// //m_CurrentTP.sText = s; //복구
|
|
//
|
|
// // bintitle. 2010.09.29. 분할된 행에도 이전행의 <태그> 가 적용되어야 한다.
|
|
// if( bUseSplitOffset )
|
|
// {
|
|
// m_CurrentTP.sText = strOldTokenLineBreak + s; //복구
|
|
// strOldTokenLineBreak.erase();
|
|
// }
|
|
// else
|
|
// m_CurrentTP.sText = s; //복구
|
|
//
|
|
// //땜방
|
|
// // 남은 string이 한줄을 넘지 않는다면 loop 를 탈출!!
|
|
//
|
|
// if( m_CurrentTP.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
// m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
// }
|
|
//
|
|
// m_dwCurrentLineWidth = 0;
|
|
// if(dwWidth <= dwMaxWidth)
|
|
// {
|
|
// // 현재남은 Line의 길이를 기억해야 한다.
|
|
// m_dwCurrentLineWidth = dwWidth;
|
|
// break;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// if(!bTagEnable)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.sText.erase();
|
|
// m_dwCurrentLineWidth = 0;
|
|
// return;
|
|
// }
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::TEXTCMD:
|
|
// // 2010.06.08 - prodongi
|
|
// _AddString(token.sText.c_str(), nDepth + 1, dwMaxWidth, bTagEnable, bUseSplit, scroll);
|
|
// //_AddString(token.sText.c_str(), nDepth + 1, dwMaxWidth, bTagEnable, bUseSplit);
|
|
// break;
|
|
// case TEXT_TOKEN::FONT:
|
|
// // Font의 종류가 다르면
|
|
// if(m_CurrentTP.sFontName != token.sText)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.sFontName = token.sText;
|
|
//
|
|
// KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
// }
|
|
// break;
|
|
//
|
|
// case TEXT_TOKEN::SIZE:
|
|
// if(m_CurrentTP.nFontSize != (int)token.dwFontSize)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.nFontSize = token.dwFontSize;
|
|
// KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::OFFSET:
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.dwOffset = token.dwOffset;
|
|
// }
|
|
// break;
|
|
//
|
|
// // 그려질 오브젝트 y 오프셋 추가 적용
|
|
// case TEXT_TOKEN::OFFSETY:
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.nOffsetY = token.nOffsetY;
|
|
// }
|
|
// break;
|
|
//
|
|
// case TEXT_TOKEN::COLOR:
|
|
// // Color가 다르면
|
|
// if(m_CurrentTP.Color.color != token.dwColor )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.Color = token.dwColor;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::BOLD:
|
|
// if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD))
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// std::string s;
|
|
// s = lpszString+nCount;
|
|
// if( !s.empty() && s[0] != ' ' )
|
|
// m_CurrentTP.bContinue = true;
|
|
//
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.bContinue = false;
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // Bold bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_BOLD;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::UNBOLD:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// std::string s;
|
|
// s = lpszString+nCount;
|
|
// if( !s.empty() && s[0] != ' ' )
|
|
// m_CurrentTP.bContinue = true;
|
|
//
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.bContinue = false;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // Bold bit Clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_BOLD;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::UNDER_LINE:
|
|
// if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER))
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // Underline bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_UNDER;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::UNDER_LINEOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // Underline bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_UNDER;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::STRIKE_LINE:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_STRIKE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::STRIKE_LINEOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_STRIKE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::SHADOW:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_SHADOW;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::SHADOWOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_SHADOW;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::OUTLINE:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_OUTLINE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::OUTLINEOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_OUTLINE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::GLOW:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::GLOWOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::COLOR_FX:
|
|
// {
|
|
// if(m_CurrentTP.ColorFX.color != token.dwColor )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
// m_CurrentTP.ColorFX = token.dwColor;
|
|
// }
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::GLOW2X:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW2X;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::GLOW2XOFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // bit clear
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW2X;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::INVERSE:
|
|
// if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE) )
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// std::string s;
|
|
// s = lpszString+nCount;
|
|
// if( !s.empty() && s[0] != ' ' )
|
|
// m_CurrentTP.bContinue = true;
|
|
//
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.bContinue = false;
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit add
|
|
// m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_INVERSE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::INVERSE_OFF:
|
|
// if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE)
|
|
// {
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// std::string s;
|
|
// s = lpszString+nCount;
|
|
// if( !s.empty() && s[0] != ' ' )
|
|
// m_CurrentTP.bContinue = true;
|
|
//
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.bContinue = false;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // strike bit add
|
|
// m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_INVERSE;
|
|
// }
|
|
// break;
|
|
// case TEXT_TOKEN::CARET:
|
|
//
|
|
// break;
|
|
//
|
|
// case TEXT_TOKEN::CARET_OFF:
|
|
//
|
|
// break;
|
|
//
|
|
// case TEXT_TOKEN::BREAK:
|
|
// m_CurrentTP.nBreak++;
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.nBreak = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_dwCurrentLineWidth = 0;
|
|
// if (token.sTokenText == "<WB>")
|
|
// m_vtTextPrimitive.back().bIsLineBreak = true;
|
|
// break;
|
|
// case TEXT_TOKEN::PAGEBREAK:
|
|
// m_CurrentTP.nPageBreak++;
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.nPageBreak = 0;
|
|
// m_CurrentTP.sText.erase();
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_dwCurrentLineWidth = 0;
|
|
// break;
|
|
// case TEXT_TOKEN::EMOTICON:
|
|
// case TEXT_TOKEN::NX3:
|
|
// {
|
|
// // Icon의 크기는 기본적으로 현재 Font Size의 2배
|
|
// m_dwCurrentLineWidth += m_CurrentTP.nFontSize * 2;
|
|
//
|
|
// if(m_CurrentTP.sText.size() > 0)
|
|
// {
|
|
// // 줄을 넘어가면 줄바꿈을 해주자
|
|
// if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
// {
|
|
// m_CurrentTP.bIsLineBreak = true;
|
|
// m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
// }
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
//
|
|
// m_CurrentTP.bIsLineBreak = false;
|
|
// m_CurrentTP.sText.erase();
|
|
// }
|
|
//
|
|
// // 그 전에 Text아닌 다른걸 넣었다면
|
|
// else if(m_vtTextPrimitive.size() > 0 && m_vtTextPrimitive.back().dwIconType != KICON_TEXT)
|
|
// {
|
|
// // 줄을 넘어가면 줄바꿈을 해주자
|
|
// if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
// {
|
|
// m_vtTextPrimitive.back().bIsLineBreak = true;
|
|
// m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
// }
|
|
// }
|
|
//
|
|
// // 한줄의 크기가 Icon보다 작은 경우는 전혀 고려하지 않았다
|
|
// m_CurrentTP.dwIconType = token.dwType - TEXT_TOKEN::EMOTICON + KICON_EMOTICON;
|
|
// m_CurrentTP.dwIconID = token.dwIconID;
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.dwIconType = KICON_TEXT;
|
|
// break;
|
|
// }
|
|
//
|
|
// case TEXT_TOKEN::HALIGN:
|
|
// m_dwHAlign = token.dwAlign;
|
|
// break;
|
|
//
|
|
// case TEXT_TOKEN::VALIGN:
|
|
// m_dwVAlign = token.dwAlign;
|
|
// break;
|
|
// // End Of String
|
|
// case TEXT_TOKEN::EOS:
|
|
// if(nDepth == 0)
|
|
// {
|
|
// m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// m_CurrentTP.dwOffset = 0;
|
|
// m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
// m_dwCurrentLineWidth = 0;
|
|
// m_CurrentTP.Init();
|
|
// }
|
|
// bLoop = FALSE;
|
|
// break;
|
|
// default:
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// if( m_bEditMode && s_bUseWordWrap )
|
|
// {
|
|
// //라인 브레이크 별로, 스페이스 쪼개서 dwOffSet 재 설정
|
|
// if( !bUseSplit )
|
|
// {
|
|
// int nPrimitiveCount = m_vtTextPrimitive.size();
|
|
//
|
|
// DWORD checkWidth, checkHeight;
|
|
// DWORD dwTextWidth = 0;
|
|
//
|
|
// std::vector<DWORD> vecTextWidthList;
|
|
// std::vector<int> vecTextPrList;
|
|
//
|
|
// int nContinue = 0;
|
|
//
|
|
// for(int i = 0; i < nPrimitiveCount; ++i)
|
|
// {
|
|
// const KTextParser::TEXT_PRIMITIVE &textPr = GetPrimitive(i);
|
|
//
|
|
// BOOL bBold = textPr.dwFontFlag & KTextRender::KTFLAG_BOLD; //BOLD 검사
|
|
// BOOL bCheckWidth = false;
|
|
//
|
|
// //땜방, sFontName 값이 없다.
|
|
// if( textPr.sFontName.length() )
|
|
// {
|
|
// KTextRender::GetStringSize(textPr.sFontName.c_str(), textPr.nFontSize, bBold,
|
|
// textPr.sText.c_str(), textPr.sText.length(), &checkWidth, &checkHeight);
|
|
// }
|
|
// else
|
|
// {
|
|
// KTextRender::GetStringSize("default", textPr.nFontSize, bBold,
|
|
// textPr.sText.c_str(), textPr.sText.length(), &checkWidth, &checkHeight);
|
|
// }
|
|
//
|
|
// dwTextWidth += checkWidth;
|
|
//
|
|
// // 2010.06.08 - prodongi
|
|
// if (!scroll)
|
|
// {
|
|
// int nCheckWidth = dwMaxWidth - dwTextWidth;
|
|
// if( nCheckWidth < 0 )
|
|
// {
|
|
// //강제 변환
|
|
// dwTextWidth -= checkWidth;
|
|
// bCheckWidth = true;
|
|
// }
|
|
// else
|
|
// {
|
|
// vecTextPrList.push_back( i );
|
|
// vecTextWidthList.push_back( checkWidth );
|
|
//
|
|
// if( textPr.bContinue )
|
|
// nContinue++;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// vecTextPrList.push_back( i );
|
|
// vecTextWidthList.push_back( checkWidth );
|
|
//
|
|
// if( textPr.bContinue )
|
|
// nContinue++;
|
|
// }
|
|
//
|
|
// if( bCheckWidth || textPr.nBreak != 0 || textPr.nPageBreak != 0 || textPr.bIsLineBreak || i == nPrimitiveCount -1)
|
|
//
|
|
//
|
|
// {
|
|
// //dwOffSet 계산
|
|
// int nTotalBlankWidth = dwMaxWidth - dwTextWidth;
|
|
// if( nTotalBlankWidth < 0 )
|
|
// {
|
|
// assert( 0 );
|
|
// }
|
|
//
|
|
// std::string strFull;
|
|
// for( unsigned int k(0); vecTextPrList.size()>k; k++ )
|
|
// {
|
|
// KTextParser::TEXT_PRIMITIVE &w_textPr = GetPrimitive( vecTextPrList[k] );
|
|
//
|
|
// strFull += w_textPr.sText.c_str();
|
|
//
|
|
// if( !w_textPr.bContinue )
|
|
// strFull += " ";
|
|
//
|
|
// if( bCheckWidth && k == (vecTextPrList.size()-1) )
|
|
// w_textPr.bIsLineBreak = true;
|
|
// }
|
|
//
|
|
//// _performance_print( "%s\n", strFull.c_str() );
|
|
//
|
|
// //Space 몇개 있는가?
|
|
// std::vector<std::string> vecText;
|
|
// nsl::split( strFull.c_str(), vecText, " ", false );
|
|
//
|
|
// if( vecText.size() <=1 ) return;
|
|
//
|
|
// int nBlankWidth = nTotalBlankWidth/(vecText.size()-1);
|
|
//
|
|
// int nAccWidth = 0;
|
|
// for( unsigned int k(0); vecTextPrList.size()>k; k++ )
|
|
// {
|
|
// KTextParser::TEXT_PRIMITIVE &w_textPr = GetPrimitive( vecTextPrList[k] );
|
|
//
|
|
// w_textPr.dwOffset = nAccWidth;
|
|
//
|
|
// nAccWidth += vecTextWidthList[k];
|
|
//
|
|
// if( !w_textPr.bContinue )
|
|
// {
|
|
// if( textPr.bIsWordWrap )
|
|
// nAccWidth += nBlankWidth;
|
|
// }
|
|
// }
|
|
//
|
|
// nContinue = 0;
|
|
// dwTextWidth = 0;
|
|
// vecTextWidthList.erase( vecTextWidthList.begin(), vecTextWidthList.end() );
|
|
// vecTextPrList.erase( vecTextPrList.begin(), vecTextPrList.end() );
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
|
|
// 2010.06.08 - prodongi
|
|
void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit, bool scroll )
|
|
//void KTextParser::_AddString(LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit)
|
|
{
|
|
int nCount = 0;
|
|
BOOL bLoop = TRUE;
|
|
|
|
/// 2010.10.07 스트링을 분할 할때 스트링에 이모티콘 필터가 있으면
|
|
/// 필터 길이도 같이 계산이 되어서 분할이 제대로 안되는 것 같음,
|
|
/// 그래서 분할 할때는 필터를 제외하고, 분할 후에 다시 필터를 추가하도록 수정함- prodongi
|
|
//std::string strEmoticon;
|
|
|
|
while ( bLoop)
|
|
{
|
|
m_CurrentTP.dwCount = nCount;
|
|
TEXT_TOKEN token;
|
|
if(!bTagEnable)
|
|
{
|
|
token.sText = lpszString;
|
|
token.dwType = TEXT_TOKEN::TEXT;
|
|
}
|
|
else
|
|
{
|
|
_GetNextToken(&token, lpszString, nCount);
|
|
}
|
|
|
|
switch(token.dwType)
|
|
{
|
|
case TEXT_TOKEN::TEXT:
|
|
{
|
|
// 줄바꿈이 있을때만 따로 리스트에 저장
|
|
if(m_CurrentTP.nBreak > 0 || m_CurrentTP.nPageBreak > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.nBreak = m_CurrentTP.nPageBreak = 0; //줄바꿈 초기화
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
}
|
|
// 텍스트가 있으면
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
std::string s;
|
|
s = lpszString+nCount;
|
|
if( !s.empty() && s[0] != ' ' )
|
|
m_CurrentTP.bContinue = true;
|
|
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.bContinue = false;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
if (token.sText.find("<WB>") != std::string::npos)
|
|
{
|
|
int xxxx=1;
|
|
}
|
|
|
|
m_CurrentTP.sText += token.sText;
|
|
BOOL bBold = m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD; //BOLD 검사
|
|
DWORD dwStrWidth = 0, dwStrHeight = 0;
|
|
|
|
//문자열 가로,세로 얻기
|
|
/*KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size(),&dwStrWidth,
|
|
|
|
&dwStrHeight);*/
|
|
std::string strTemp = m_CurrentTP.sText;
|
|
KTextRender::GetEmoticonFilterText( strTemp );
|
|
|
|
|
|
/// 2010.10.07 이모티콘 체크, 이모티콘은 항상 스트링의 맨 앞에 오는 걸로 생각함 - prodongi
|
|
/*
|
|
size_t emoticonSize = 0;
|
|
if (strEmoticon.empty())
|
|
{
|
|
std::string strTokenTemp = token.sText;
|
|
KTextRender::GetEmoticonFilterText(strTokenTemp);
|
|
if (strTokenTemp != token.sText)
|
|
{
|
|
std::string::size_type pos = token.sText.find(strTokenTemp.c_str());
|
|
if (std::string::npos != pos)
|
|
{
|
|
strEmoticon = token.sText.substr(0, pos);
|
|
// calcul emoticon size
|
|
emoticonSize = m_CurrentTP.nFontSize + 6;//g_nEmoticonFilterOffset;
|
|
}
|
|
}
|
|
m_CurrentTP.sText = strTemp;
|
|
}
|
|
*/
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
strTemp.c_str(),(int)strTemp.size(),&dwStrWidth,
|
|
|
|
&dwStrHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize( "default", m_CurrentTP.nFontSize, bBold,
|
|
strTemp.c_str(),(int)strTemp.size(),&dwStrWidth, &dwStrHeight);
|
|
}
|
|
|
|
//현재 라인 가로 크기에 스트링 가로 크기 더하기
|
|
m_dwCurrentLineWidth += dwStrWidth;
|
|
|
|
// 한줄을 넘기게 되면 linebreak를 걸어주자
|
|
// 2010.06.03 - prodongi
|
|
if( !scroll && (m_dwCurrentLineWidth > dwMaxWidth))
|
|
//if( m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
//더해진 가로 크기에 스트링 가로 크기 다시 빼기
|
|
m_dwCurrentLineWidth -= dwStrWidth;
|
|
|
|
// 추가된 Primitive를 Line size로 자르자.
|
|
while (1)
|
|
{
|
|
int nBackLast_Space = 0;
|
|
int nOldLast_Space = 0;
|
|
int nLast_Space = 0;
|
|
int nMaxStr = 0;
|
|
DWORD dwWidth = 0, dwHeight = 0;
|
|
|
|
char * psz1 = const_cast<char *>(m_CurrentTP.sText.c_str());
|
|
char * psz2 = psz1;
|
|
char * last_space = NULL;
|
|
char * Oldlast_space = NULL;
|
|
char * Backlast_space = NULL;
|
|
|
|
|
|
// dwMaxWidth에 걸맞는 Size를 찾자.
|
|
int nWordSize = 0 ;
|
|
while(1)
|
|
{
|
|
if( !(*psz1) ) break;
|
|
/// 2010.11.24 - prodongi
|
|
psz2 = CharNextExA(KTextRender::GetDefaultCodePage(), psz1, 0);
|
|
//psz2 = CharNext(psz1);
|
|
nMaxStr++;
|
|
|
|
if( (psz2 - psz1) == 2)
|
|
{
|
|
// 한 글자가 2byte 인 경우 (ex: 한글)
|
|
nMaxStr++;
|
|
|
|
nBackLast_Space = nOldLast_Space;
|
|
Backlast_space = Oldlast_space;
|
|
|
|
//이전 ' '
|
|
nOldLast_Space = nLast_Space;
|
|
Oldlast_space = last_space;
|
|
|
|
last_space = psz2+1; //' '의 다음문자 지정
|
|
nLast_Space = nMaxStr; //' '까지의 길이
|
|
}
|
|
|
|
if( *psz2 == ' ' )
|
|
{
|
|
nBackLast_Space = nOldLast_Space;
|
|
Backlast_space = Oldlast_space;
|
|
|
|
//이전 ' '
|
|
nOldLast_Space = nLast_Space;
|
|
Oldlast_space = last_space;
|
|
|
|
last_space = psz2+1; //' '의 다음문자 지정
|
|
nLast_Space = nMaxStr; //' '까지의 길이
|
|
}
|
|
|
|
nWordSize++;
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nMaxStr, &dwWidth, &dwHeight);
|
|
}
|
|
|
|
// 문자 하나의 size가 maxwidth를 넘는 경우 그냥 하나 단위로 짜름
|
|
if(nWordSize == 1 && dwWidth > dwMaxWidth)
|
|
break;
|
|
|
|
// 바로 전 글자까지만 짜르면 된다.
|
|
if(m_dwCurrentLineWidth + dwWidth > dwMaxWidth)
|
|
{
|
|
// 이경우 2byte중 1byte만 남게 된 경우므로
|
|
// 아예 2byte를 다 잘라 버린다.
|
|
nMaxStr -= int(psz2 - psz1);
|
|
|
|
//위치가 앞으로 이동 된 경우
|
|
if( nMaxStr < nLast_Space )
|
|
{
|
|
if( nOldLast_Space == nLast_Space )
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nBackLast_Space;
|
|
last_space = Backlast_space;
|
|
}
|
|
else
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nOldLast_Space;
|
|
last_space = Oldlast_space;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
psz1 = psz2;
|
|
}
|
|
|
|
/// 2011.06.13 한 라인에 단어 한개가 추가 瑛?때, 최대 길이를 넘어간 경우의 예외 처리 - prodongi
|
|
/// 많은 테스트 필요
|
|
/// 2011.06.13 mantis 10254 - prodongi
|
|
/// 2011.07.25 redmine #18044 - prodongi
|
|
if( s_bUseWordWrap && 0 == nLast_Space && !bUseSplit)
|
|
{
|
|
std::string str = m_CurrentTP.sText;
|
|
|
|
// add line break
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.bIsLineBreak = true;
|
|
m_CurrentTP.bIsWordWrap = false;
|
|
m_CurrentTP.sText.clear();
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
|
|
// add new text
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
m_CurrentTP.sText = str;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
|
|
m_dwCurrentLineWidth = dwWidth;
|
|
|
|
m_CurrentTP.sText.clear();
|
|
|
|
break;
|
|
}
|
|
|
|
// 이미 한줄이 꽉찬 상태에서 새로 Text가 추가 되면
|
|
// 그냥 줄바꿈만 해주고 다시 계산해 준다.
|
|
if(nMaxStr == 0)
|
|
{
|
|
if(m_vtTextPrimitive.size() > 0)
|
|
m_vtTextPrimitive.back().bIsLineBreak = true; //줄바꿈 설정
|
|
|
|
m_dwCurrentLineWidth = 0;
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
// 다시 줄의 넓이를 계산한다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),m_CurrentTP.sText.length() , &dwWidth, &dwHeight);
|
|
}
|
|
|
|
// 만약 한줄에 다 들어가면 Loop 탈출
|
|
if(dwWidth < dwMaxWidth)
|
|
{
|
|
m_dwCurrentLineWidth = dwWidth;
|
|
break;
|
|
}
|
|
// 그게 아니면 다시 계산
|
|
else
|
|
continue;
|
|
}
|
|
|
|
std::string s;
|
|
|
|
// 자른후에 사용할 string 저장
|
|
int nCutSize = nMaxStr;
|
|
|
|
if( s_bUseWordWrap )
|
|
{
|
|
//크기가 모자람
|
|
if( nMaxStr < nLast_Space )
|
|
{
|
|
if( nOldLast_Space == nLast_Space )
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nBackLast_Space;
|
|
}
|
|
else
|
|
{
|
|
//이전 ' ' 으로 복구
|
|
nLast_Space = nOldLast_Space;
|
|
}
|
|
}
|
|
|
|
if( nLast_Space != 0 )
|
|
nCutSize = nLast_Space;
|
|
}
|
|
|
|
s = m_CurrentTP.sText.c_str() + nCutSize;
|
|
|
|
// _performance_print( "백업 %s\n", s.c_str() );
|
|
|
|
// 다음행의 시작 스페이스는 날린다
|
|
while( nMaxStr && !s.empty() && s[0] == ' ' ) s.erase( 0, 1 );
|
|
|
|
m_CurrentTP.sText.resize(nCutSize); //크기 재설정
|
|
m_CurrentTP.bIsLineBreak = true; //줄바꿈 설정
|
|
|
|
if( s_bUseWordWrap )
|
|
{
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nCutSize, &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(), nCutSize, &dwWidth, &dwHeight);
|
|
}
|
|
|
|
if( dwWidth <= dwMaxWidth )
|
|
{
|
|
if( nLast_Space != 0 && nMaxStr != nLast_Space )
|
|
{
|
|
//Space 몇개 있는가?
|
|
std::vector<std::string> vecText;
|
|
nsl::split( m_CurrentTP.sText.c_str(), vecText, " ", false );
|
|
|
|
if( vecText.size()>1 )
|
|
{
|
|
std::string strText, strTemp;
|
|
DWORD checkWidth, checkHeight, accumWidth;
|
|
accumWidth = checkWidth = checkHeight = 0;
|
|
|
|
std::vector<DWORD> vecTextWidthList;
|
|
|
|
//단어들의 길이 계산
|
|
for( unsigned int k(0); vecText.size()>k; k++ )
|
|
{
|
|
//땜방, sFontName 값이 없다.
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(),
|
|
|
|
m_CurrentTP.nFontSize, bBold,
|
|
vecText[k].c_str(), vecText[k].length(), &checkWidth,
|
|
|
|
&checkHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize,
|
|
|
|
bBold,
|
|
vecText[k].c_str(), vecText[k].length(), &checkWidth,
|
|
|
|
&checkHeight);
|
|
}
|
|
|
|
vecTextWidthList.push_back( checkWidth );
|
|
accumWidth += checkWidth;
|
|
}
|
|
|
|
/// 2010.10.05 - prodongi
|
|
/// 아래 방식 처럼 쓴다면 빈 칸 사이즈가 글자 수에 따라서 틀려지기 때문에 이상하게 보인다, 수정이 필요할 것 같음,,
|
|
|
|
//여백 계산
|
|
unsigned int nTotalBlankWidth = (dwMaxWidth-m_dwCurrentLineWidth)-(accumWidth);
|
|
// 1줄에 여러 개의 primitive가 들어갈 경우 첫 primitive가 아닌 2번째 이상의 primitive에서 줄바꿈이 일어날 경우 줄바꿈 될 텍스트를 좌우정렬하려는 과정에서
|
|
// 이미 앞에 들어가 있던 문자의 길이를 무시하려 하기 때문에 무조건 0부터 끝까지 기준으로 좌우정렬하려고 해서
|
|
// 이미 있던 글자와 겹쳐지는 문제가 발생한다. 그래서 어디서부터 끝까지 좌우맞춤을 할 것인지 확실하게 정하기 위해 (dwMaxWidth-m_dwCurrentLineWidth) 로 고침
|
|
//Blank의 길이 계산
|
|
unsigned int nBlankWidth = nTotalBlankWidth/(vecText.size()-1);
|
|
int accumWidthTemp = m_dwCurrentLineWidth;
|
|
/// 2011.04.15 - prodongi
|
|
//accumWidth = 0;
|
|
accumWidth = m_dwCurrentLineWidth;
|
|
|
|
/// 2011.04.15 m_vtTextPrimitive의 맨 마지막 텍스트가 현재 라인의 첫 텍스트라는 보장이 없기 때문에
|
|
/// 아래 처럼 accumWidth를 계산하면 텍스트가 겹처서 출력 될 수가 있다. - prodongi
|
|
/*
|
|
// 추가. bintitle. 2010.10.01.
|
|
// 이전 Primitive 에서 bIsLineBreak 가 아닌경우에는 이전 텍스트의 길이만큼 offset을 적용해야 다음 Primitive와 겹치지 않는다.
|
|
int nPrimitiveIndex = m_vtTextPrimitive.size();
|
|
if( !m_vtTextPrimitive.empty() && !m_vtTextPrimitive[ nPrimitiveIndex - 1 ].bIsLineBreak )
|
|
{
|
|
TEXT_PRIMITIVE oldPrimitive = m_vtTextPrimitive[ nPrimitiveIndex - 1 ];
|
|
|
|
if( oldPrimitive.sFontName.empty() )
|
|
{
|
|
KTextRender::GetStringSize("default", oldPrimitive.nFontSize, bBold,
|
|
oldPrimitive.sText.c_str(), oldPrimitive.sText.length(), &accumWidth, &checkHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize(oldPrimitive.sFontName.c_str(), oldPrimitive.nFontSize, bBold,
|
|
oldPrimitive.sText.c_str(), oldPrimitive.sText.length(), &accumWidth, &checkHeight);
|
|
}
|
|
}
|
|
*/
|
|
|
|
for( unsigned int k(0); vecText.size()>k; k++ )
|
|
{
|
|
if( !bUseSplit )
|
|
{
|
|
m_CurrentTP.dwOffset = accumWidth;
|
|
/*
|
|
/// 2010.10.08 두번째 텍스트 부터 첫 번째 텍스트의 이모티콘 사이즈를 더해 준다 - prodongi
|
|
if (0 != k && emoticonSize)
|
|
m_CurrentTP.dwOffset += emoticonSize;
|
|
*/
|
|
|
|
//마지막
|
|
if( k == vecText.size()-1 )
|
|
m_CurrentTP.bIsLineBreak = true;
|
|
else
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
|
|
m_CurrentTP.sText = vecText[k].c_str();
|
|
|
|
if( nBlankWidth == nTotalBlankWidth )
|
|
m_CurrentTP.nBlankWidth = 4;
|
|
else
|
|
m_CurrentTP.nBlankWidth = nBlankWidth;
|
|
|
|
m_CurrentTP.bIsWordWrap = true;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
}
|
|
else
|
|
{
|
|
if( k==0 )
|
|
{
|
|
strText = vecText[k].c_str();
|
|
}
|
|
else
|
|
{
|
|
strTemp = nsl::format( "<OFFSET:%d>%s", accumWidthTemp, vecText[k].c_str() );
|
|
}
|
|
|
|
strText += strTemp;
|
|
}
|
|
|
|
accumWidth += vecTextWidthList[k]; //단어
|
|
accumWidth += nBlankWidth; //Blank
|
|
accumWidthTemp += vecTextWidthList[k]; //단어
|
|
accumWidthTemp += nBlankWidth; //Blank
|
|
}
|
|
|
|
if( bUseSplit )
|
|
{
|
|
m_CurrentTP.bIsLineBreak = true;
|
|
m_CurrentTP.sText = strText;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
}
|
|
|
|
m_CurrentTP.nBlankWidth = 0;
|
|
m_CurrentTP.bIsWordWrap = false;
|
|
}
|
|
else
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
}
|
|
}//if( nLast_Space != 0 && nMaxStr != nLast_Space )
|
|
else
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
}
|
|
}//if( dwWidth <= dwMaxWidth )
|
|
else
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
// assert(0 && "if( dwWidth <= dwMaxWidth )" );
|
|
}
|
|
}//if( s_bUseWordWrap )
|
|
else
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
}
|
|
|
|
//새로 시작
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
m_CurrentTP.bIsWordWrap = false;
|
|
m_CurrentTP.sText = s; //복구
|
|
|
|
//땜방
|
|
// 남은 string이 한줄을 넘지 않는다면 loop 를 탈출!!
|
|
|
|
if( m_CurrentTP.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(m_CurrentTP.sFontName.c_str(), m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", m_CurrentTP.nFontSize, bBold,
|
|
m_CurrentTP.sText.c_str(),(int)m_CurrentTP.sText.size() , &dwWidth, &dwHeight);
|
|
}
|
|
|
|
m_dwCurrentLineWidth = 0;
|
|
if(dwWidth <= dwMaxWidth)
|
|
{
|
|
// 현재남은 Line의 길이를 기억해야 한다.
|
|
m_dwCurrentLineWidth = dwWidth;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!bTagEnable)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.sText.erase();
|
|
m_dwCurrentLineWidth = 0;
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::TEXTCMD:
|
|
// 2010.06.08 - prodongi
|
|
_AddString(token.sText.c_str(), nDepth + 1, dwMaxWidth, bTagEnable, bUseSplit, scroll);
|
|
//_AddString(token.sText.c_str(), nDepth + 1, dwMaxWidth, bTagEnable, bUseSplit);
|
|
break;
|
|
case TEXT_TOKEN::FONT:
|
|
// Font의 종류가 다르면
|
|
if(m_CurrentTP.sFontName != token.sText)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.sFontName = token.sText;
|
|
|
|
KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::SIZE:
|
|
if(m_CurrentTP.nFontSize != (int)token.dwFontSize)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.nFontSize = token.dwFontSize;
|
|
KTextRender::AddFont(m_CurrentTP.sFontName.c_str(),m_CurrentTP.nFontSize);
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OFFSET:
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.dwOffset = token.dwOffset;
|
|
}
|
|
break;
|
|
|
|
// 그려질 오브젝트 y 오프셋 추가 적용
|
|
case TEXT_TOKEN::OFFSETY:
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.nOffsetY = token.nOffsetY;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::COLOR:
|
|
// Color가 다르면
|
|
if(m_CurrentTP.Color.color != token.dwColor )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.Color = token.dwColor;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::BOLD:
|
|
if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD))
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
std::string s;
|
|
s = lpszString+nCount;
|
|
if( !s.empty() && s[0] != ' ' )
|
|
m_CurrentTP.bContinue = true;
|
|
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.bContinue = false;
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Bold bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_BOLD;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNBOLD:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_BOLD)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
std::string s;
|
|
s = lpszString+nCount;
|
|
if( !s.empty() && s[0] != ' ' )
|
|
m_CurrentTP.bContinue = true;
|
|
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.bContinue = false;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Bold bit Clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_BOLD;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNDER_LINE:
|
|
if(! (m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER))
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Underline bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_UNDER;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::UNDER_LINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_UNDER)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// Underline bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_UNDER;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::STRIKE_LINE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_STRIKE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::STRIKE_LINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_STRIKE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_STRIKE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::SHADOW:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_SHADOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::SHADOWOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_SHADOW)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_SHADOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OUTLINE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_OUTLINE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::OUTLINEOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_OUTLINE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_OUTLINE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOWOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::COLOR_FX:
|
|
{
|
|
if(m_CurrentTP.ColorFX.color != token.dwColor )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
m_CurrentTP.ColorFX = token.dwColor;
|
|
}
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW2X:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_GLOW2X;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::GLOW2XOFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_GLOW2X)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// bit clear
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_GLOW2X;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::INVERSE:
|
|
if(!(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE) )
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
std::string s;
|
|
s = lpszString+nCount;
|
|
if( !s.empty() && s[0] != ' ' )
|
|
m_CurrentTP.bContinue = true;
|
|
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.bContinue = false;
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag |= KTextRender::KTFLAG_INVERSE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::INVERSE_OFF:
|
|
if(m_CurrentTP.dwFontFlag & KTextRender::KTFLAG_INVERSE)
|
|
{
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
std::string s;
|
|
s = lpszString+nCount;
|
|
if( !s.empty() && s[0] != ' ' )
|
|
m_CurrentTP.bContinue = true;
|
|
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.bContinue = false;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// strike bit add
|
|
m_CurrentTP.dwFontFlag &= ~KTextRender::KTFLAG_INVERSE;
|
|
}
|
|
break;
|
|
case TEXT_TOKEN::CARET:
|
|
|
|
break;
|
|
|
|
case TEXT_TOKEN::CARET_OFF:
|
|
|
|
break;
|
|
|
|
case TEXT_TOKEN::BREAK:
|
|
m_CurrentTP.nBreak++;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.nBreak = 0;
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_dwCurrentLineWidth = 0;
|
|
/// 2010.10.05 <WB>는 무엇인가?? bIsLineBreak는 여기서 항상 true가 되야 될거 같음 - prodongi
|
|
//if (token.sTokenText == "<WB>")
|
|
m_vtTextPrimitive.back().bIsLineBreak = true;
|
|
break;
|
|
case TEXT_TOKEN::PAGEBREAK:
|
|
m_CurrentTP.nPageBreak++;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.nPageBreak = 0;
|
|
m_CurrentTP.sText.erase();
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_dwCurrentLineWidth = 0;
|
|
break;
|
|
case TEXT_TOKEN::EMOTICON:
|
|
case TEXT_TOKEN::NX3:
|
|
{
|
|
// Icon의 크기는 기본적으로 현재 Font Size의 2배
|
|
m_dwCurrentLineWidth += m_CurrentTP.nFontSize * 2;
|
|
|
|
if(m_CurrentTP.sText.size() > 0)
|
|
{
|
|
// 줄을 넘어가면 줄바꿈을 해주자
|
|
if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
m_CurrentTP.bIsLineBreak = true;
|
|
m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
}
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
|
|
m_CurrentTP.bIsLineBreak = false;
|
|
m_CurrentTP.sText.erase();
|
|
}
|
|
|
|
// 그 전에 Text아닌 다른걸 넣었다면
|
|
else if(m_vtTextPrimitive.size() > 0 && m_vtTextPrimitive.back().dwIconType != KICON_TEXT)
|
|
{
|
|
// 줄을 넘어가면 줄바꿈을 해주자
|
|
if(m_dwCurrentLineWidth > dwMaxWidth)
|
|
{
|
|
m_vtTextPrimitive.back().bIsLineBreak = true;
|
|
m_dwCurrentLineWidth = m_CurrentTP.nFontSize * 2;
|
|
}
|
|
}
|
|
|
|
// 한줄의 크기가 Icon보다 작은 경우는 전혀 고려하지 않았다
|
|
m_CurrentTP.dwIconType = token.dwType - TEXT_TOKEN::EMOTICON + KICON_EMOTICON;
|
|
m_CurrentTP.dwIconID = token.dwIconID;
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.dwIconType = KICON_TEXT;
|
|
break;
|
|
}
|
|
|
|
case TEXT_TOKEN::HALIGN:
|
|
m_dwHAlign = token.dwAlign;
|
|
break;
|
|
|
|
case TEXT_TOKEN::VALIGN:
|
|
m_dwVAlign = token.dwAlign;
|
|
break;
|
|
// End Of String
|
|
case TEXT_TOKEN::EOS:
|
|
if(nDepth == 0)
|
|
{
|
|
m_vtTextPrimitive.push_back(m_CurrentTP);
|
|
m_CurrentTP.dwOffset = 0;
|
|
m_CurrentTP.nOffsetY = 0; // 그려질 오브젝트 y 오프셋
|
|
m_dwCurrentLineWidth = 0;
|
|
m_CurrentTP.Init();
|
|
}
|
|
bLoop = FALSE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// 2010.10.07 - prodongi
|
|
/*
|
|
if (!strEmoticon.empty() && !m_vtTextPrimitive.empty())
|
|
{
|
|
std::string strFront = m_vtTextPrimitive.front().sText;
|
|
m_vtTextPrimitive.front().sText = strEmoticon + strFront;
|
|
}
|
|
*/
|
|
|
|
if( m_bEditMode && s_bUseWordWrap )
|
|
{
|
|
//라인 브레이크 별로, 스페이스 쪼개서 dwOffSet 재 설정
|
|
if( !bUseSplit )
|
|
{
|
|
int nPrimitiveCount = m_vtTextPrimitive.size();
|
|
|
|
DWORD checkWidth, checkHeight;
|
|
DWORD dwTextWidth = 0;
|
|
|
|
std::vector<DWORD> vecTextWidthList;
|
|
std::vector<int> vecTextPrList;
|
|
|
|
int nContinue = 0;
|
|
|
|
for(int i = 0; i < nPrimitiveCount; ++i)
|
|
{
|
|
const KTextParser::TEXT_PRIMITIVE &textPr = GetPrimitive(i);
|
|
|
|
BOOL bBold = textPr.dwFontFlag & KTextRender::KTFLAG_BOLD; //BOLD 검사
|
|
BOOL bCheckWidth = false;
|
|
|
|
//땜방, sFontName 값이 없다.
|
|
if( textPr.sFontName.length() )
|
|
{
|
|
KTextRender::GetStringSize(textPr.sFontName.c_str(), textPr.nFontSize, bBold,
|
|
textPr.sText.c_str(), textPr.sText.length(), &checkWidth, &checkHeight);
|
|
}
|
|
else
|
|
{
|
|
KTextRender::GetStringSize("default", textPr.nFontSize, bBold,
|
|
textPr.sText.c_str(), textPr.sText.length(), &checkWidth, &checkHeight);
|
|
}
|
|
|
|
dwTextWidth += checkWidth;
|
|
|
|
// 2010.06.08 - prodongi
|
|
if (!scroll)
|
|
{
|
|
int nCheckWidth = dwMaxWidth - dwTextWidth;
|
|
if( nCheckWidth < 0 )
|
|
{
|
|
//강제 변환
|
|
dwTextWidth -= checkWidth;
|
|
bCheckWidth = true;
|
|
}
|
|
else
|
|
{
|
|
vecTextPrList.push_back( i );
|
|
vecTextWidthList.push_back( checkWidth );
|
|
|
|
if( textPr.bContinue )
|
|
nContinue++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vecTextPrList.push_back( i );
|
|
vecTextWidthList.push_back( checkWidth );
|
|
|
|
if( textPr.bContinue )
|
|
nContinue++;
|
|
}
|
|
|
|
if( bCheckWidth || textPr.nBreak != 0 || textPr.nPageBreak != 0 || textPr.bIsLineBreak || i == nPrimitiveCount -1)
|
|
|
|
|
|
{
|
|
//dwOffSet 계산
|
|
int nTotalBlankWidth = dwMaxWidth - dwTextWidth;
|
|
if( nTotalBlankWidth < 0 )
|
|
{
|
|
assert( 0 );
|
|
}
|
|
|
|
std::string strFull;
|
|
for( unsigned int k(0); vecTextPrList.size()>k; k++ )
|
|
{
|
|
KTextParser::TEXT_PRIMITIVE &w_textPr = GetPrimitive( vecTextPrList[k] );
|
|
|
|
strFull += w_textPr.sText.c_str();
|
|
|
|
if( !w_textPr.bContinue )
|
|
strFull += " ";
|
|
|
|
if( bCheckWidth && k == (vecTextPrList.size()-1) )
|
|
w_textPr.bIsLineBreak = true;
|
|
}
|
|
|
|
// _performance_print( "%s\n", strFull.c_str() );
|
|
|
|
//Space 몇개 있는가?
|
|
std::vector<std::string> vecText;
|
|
nsl::split( strFull.c_str(), vecText, " ", false );
|
|
|
|
if( vecText.size() <=1 ) return;
|
|
|
|
int nBlankWidth = nTotalBlankWidth/(vecText.size()-1);
|
|
|
|
int nAccWidth = 0;
|
|
for( unsigned int k(0); vecTextPrList.size()>k; k++ )
|
|
{
|
|
KTextParser::TEXT_PRIMITIVE &w_textPr = GetPrimitive( vecTextPrList[k] );
|
|
|
|
w_textPr.dwOffset = nAccWidth;
|
|
|
|
nAccWidth += vecTextWidthList[k];
|
|
|
|
if( !w_textPr.bContinue )
|
|
{
|
|
if( textPr.bIsWordWrap )
|
|
nAccWidth += nBlankWidth;
|
|
}
|
|
}
|
|
|
|
nContinue = 0;
|
|
dwTextWidth = 0;
|
|
vecTextWidthList.erase( vecTextWidthList.begin(), vecTextWidthList.end() );
|
|
vecTextPrList.erase( vecTextPrList.begin(), vecTextPrList.end() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
static inline char getCharToken( const char *string, int &count )
|
|
{
|
|
char a;
|
|
while( 1 )
|
|
{
|
|
a = string[count++];
|
|
if ( a == '\n' || a == '\r' || a == '\t' )
|
|
continue;
|
|
break;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
static inline int hextoint( const char *str )
|
|
{
|
|
int result = 0;
|
|
for ( int i=0 ; i< 2 ; i++ )
|
|
{
|
|
if ( str[i] >= '0' && str[i] <= '9' )
|
|
result += (str[i] - '0') * (i==0 ? 16 : 1);
|
|
else if ( str[i] >= 'A' && str[i] <= 'F' )
|
|
result += (str[i] - 'A' + 10 ) * (i==0 ? 16 : 1);
|
|
else if ( str[i] >= 'a' && str[i] <= 'f' )
|
|
result += (str[i] - 'a' + 10 ) * (i==0 ? 16 : 1);
|
|
else return 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void KTextParser::_GetNextToken( TEXT_TOKEN *pToken, LPCSTR lpszToken, int & nCount)
|
|
{
|
|
char a = getCharToken( lpszToken, nCount );
|
|
if ( a == '\0' )
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::EOS;
|
|
return;
|
|
}
|
|
if ( a == '<' )
|
|
{
|
|
bool success = false;
|
|
int tcount = nCount;
|
|
std::string str;
|
|
while ( 1 )
|
|
{
|
|
char c = getCharToken( lpszToken, tcount );
|
|
if ( c == ' ' )
|
|
continue;
|
|
else if ( c == '>' )
|
|
{
|
|
success = true;
|
|
break;
|
|
}
|
|
else if ( c == '<' || c == '\0' )
|
|
break;
|
|
str += c;
|
|
}
|
|
if ( success == true )
|
|
{
|
|
nCount = tcount;
|
|
_InterpretCommand(str.c_str(), pToken);
|
|
return;
|
|
}
|
|
}
|
|
|
|
#ifdef _COUNTRY_ME_
|
|
if ( a == '#' )
|
|
{
|
|
int tcount = nCount;
|
|
char c = getCharToken( lpszToken, tcount );
|
|
if ( c == '@' )
|
|
{
|
|
std::string str = "#@";
|
|
while ( 1 )
|
|
{
|
|
c = getCharToken( lpszToken, tcount );
|
|
if ( c == '@' )
|
|
{
|
|
c = getCharToken( lpszToken, tcount );
|
|
assert( c == '#' );
|
|
str += "@#";
|
|
break;
|
|
}
|
|
str += c;
|
|
}
|
|
nCount = tcount;
|
|
pToken->dwType = TEXT_TOKEN::EMOTICON;
|
|
pToken->sText = str;
|
|
return;
|
|
}
|
|
}
|
|
|
|
std::string str;
|
|
while ( 1 )
|
|
{
|
|
str += a;
|
|
a = getCharToken( lpszToken, nCount );
|
|
if ( a == '<' || a == '#' || a == '\0' )
|
|
{
|
|
nCount--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
std::string str;
|
|
while ( 1 )
|
|
{
|
|
str += a;
|
|
a = getCharToken( lpszToken, nCount );
|
|
if ( a == '<' /*|| a == '#'*/ || a == '\0' )
|
|
{
|
|
nCount--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
pToken->dwType = TEXT_TOKEN::TEXT;
|
|
pToken->sText = str;
|
|
return;
|
|
|
|
}
|
|
void KTextParser::_InterpretCommand( LPCSTR lpszToken, TEXT_TOKEN * pToken)
|
|
{
|
|
|
|
LPCSTR cmds[] = { "FONT:", "#", "BR", "P", "$L","$", "B", "/B", "U", "/U", // 10
|
|
"STRIKE", "/STRIKE", "INV", "/INV","SHD", "/SHD", "%%", "%", "SIZE:", "LEFT", // 20
|
|
"TOP", "RIGHT", "BOTTOM", "HCENTER", "VCENTER", "OUT", "/OUT", "GLOW", "/GLOW", "SHADOW", // 30
|
|
"/SHADOW", "@", "2XGLOW","/2XGLOW", "OFFSETY:", "CARET", "/CARET", "OFFSET:", // 38
|
|
"WB"
|
|
};
|
|
|
|
pToken->sTokenText = std::string("<") + lpszToken;
|
|
pToken->sTokenText += ">";
|
|
|
|
for ( int i=0 ; i < _countof( cmds ) ; i++ )
|
|
{
|
|
if ( strnicmp( cmds[i], lpszToken, strlen( cmds[i] ) ) == 0 )
|
|
{
|
|
switch(i)
|
|
{
|
|
case 0: // Font Change
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::FONT;
|
|
pToken->sText = lpszToken + strlen(cmds[0]);
|
|
}
|
|
return;
|
|
case 1: // Color Change
|
|
{ //Str에는 RGB 형식으로 넘어온다
|
|
const char *str = lpszToken + 1;
|
|
int len = (int)strlen(str);
|
|
if ( len < 6 )
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::INVALID;
|
|
return;
|
|
}
|
|
unsigned char colors[4] = { 0,0,0,255, };
|
|
len = ((len/2)>4) ? 4 : len/2;
|
|
for ( int j=0 ; j<len ; j++ )
|
|
{
|
|
colors[j] = (unsigned char)hextoint( &str[j*2] );
|
|
}
|
|
pToken->dwType = TEXT_TOKEN::COLOR;
|
|
// a,r,g,b
|
|
pToken->dwColor = (colors[3] << 24) | (colors[0] << 16) | (colors[1] << 8) | colors[2];
|
|
}
|
|
return;
|
|
case 2: // Br
|
|
case 38:
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::BREAK;
|
|
}
|
|
return;
|
|
case 3: // P
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::PAGEBREAK;
|
|
}
|
|
return;
|
|
|
|
case 4: // $L
|
|
return;
|
|
case 5: // $
|
|
{
|
|
const char *begin = lpszToken + 1;
|
|
const char *end = lpszToken + strlen(lpszToken);
|
|
const char *sep = strchr( begin, ':' );
|
|
pToken->dwType = TEXT_TOKEN::TEXT;
|
|
|
|
if( *begin == 0 || end == NULL ) return;
|
|
|
|
std::string strId;
|
|
std::string strText;
|
|
|
|
if( sep ) { strId.assign( begin, sep ); strText.assign( sep + 1, end ); }
|
|
else { strText.assign( begin, end ); }
|
|
|
|
if( !strId.empty() )
|
|
{
|
|
int nId = atoi( strId.c_str() );
|
|
// TODO : strText = nId;
|
|
const char *szText = KTextRender::GetString( nId );
|
|
if( szText ) strText = szText;
|
|
|
|
// 태그는 일단 제거한다.
|
|
while( true )
|
|
{
|
|
size_t tag_begin = strText.find( '<' );
|
|
if( tag_begin == strText.npos ) break;
|
|
|
|
size_t tag_end = strText.find( '>' );
|
|
if( tag_end == strText.npos ) break;
|
|
|
|
if( tag_end > tag_begin )
|
|
strText.erase( strText.begin() + tag_begin, strText.begin() + tag_end + 1 );
|
|
else
|
|
{
|
|
char szError[256];
|
|
|
|
sprintf_s( szError, 256, "ID %d 번 스트링 \"%s\" 에 이상이 있습니다.", nId, KTextRender::GetString( nId ) );
|
|
MessageBox( NULL, szError, "RAPPELZ Token Parser", MB_OK );
|
|
_exit(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
pToken->sText = strText;
|
|
}
|
|
return;
|
|
case 6: // B
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::BOLD;
|
|
}
|
|
return;
|
|
case 7: // /B
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::UNBOLD;
|
|
}
|
|
return;
|
|
case 8: // U
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::UNDER_LINE;
|
|
}
|
|
return;
|
|
case 9: // /U
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::UNDER_LINEOFF;
|
|
}
|
|
return;
|
|
case 10: // S
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::STRIKE_LINE;
|
|
}
|
|
return;
|
|
case 11: // /S
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::STRIKE_LINEOFF;
|
|
}
|
|
return;
|
|
|
|
case 12: // INV
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::INVERSE;
|
|
}
|
|
return;
|
|
case 13: // /INV
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::INVERSE_OFF;
|
|
}
|
|
return;
|
|
|
|
case 29:
|
|
case 14: // SHADOW
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::SHADOW;
|
|
}
|
|
return;
|
|
|
|
case 30:
|
|
case 15: // /SHADOW
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::SHADOWOFF;
|
|
}
|
|
return;
|
|
|
|
// Emoticon
|
|
case 16: // %%
|
|
pToken->dwType = TEXT_TOKEN::EMOTICON;
|
|
pToken->dwIconID = atoi( lpszToken + 1 );
|
|
return;
|
|
|
|
// NX3
|
|
case 17: // %
|
|
pToken->dwType = TEXT_TOKEN::NX3;
|
|
pToken->dwIconID = atoi( lpszToken + 1 );
|
|
|
|
return;
|
|
case 18: // SIZE:
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::SIZE;
|
|
pToken->dwFontSize = atoi(lpszToken + strlen(cmds[18]));
|
|
}
|
|
return;
|
|
case 19: // LEFT
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::HALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_LEFT;
|
|
}
|
|
return;
|
|
case 20: // TOP
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::VALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_TOP;
|
|
}
|
|
return;
|
|
case 21: // RIGHT
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::HALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_RIGHT;
|
|
}
|
|
return;
|
|
case 22: // BOTTOM
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::VALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_BOTTOM;
|
|
}
|
|
return;
|
|
case 23: // HCENTER
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::HALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_HCENTER;
|
|
}
|
|
return;
|
|
case 24: // VCENTER
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::VALIGN;
|
|
pToken->dwAlign = KTextRender::KTALIGN_VCENTER;
|
|
}
|
|
return;
|
|
case 25: // OUTLINE
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::OUTLINE;
|
|
}
|
|
return;
|
|
|
|
case 26: // /OUTLINE OFF
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::OUTLINEOFF;
|
|
}
|
|
return;
|
|
case 27: // GLOW
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::GLOW;
|
|
}
|
|
return;
|
|
|
|
case 28: // /GLOW OFF
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::GLOWOFF;
|
|
}
|
|
return;
|
|
|
|
case 31: // /Color_FX "@"
|
|
{ //Str에는 RGB 형식으로 넘어온다
|
|
const char *str = lpszToken + 1;
|
|
int len = (int)strlen(str);
|
|
if ( len < 6 )
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::INVALID;
|
|
return;
|
|
}
|
|
unsigned char colors[4] = { 0,0,0,255, };
|
|
len = ((len/2)>4) ? 4 : len/2;
|
|
for ( int j=0 ; j<len ; j++ )
|
|
{
|
|
colors[j] = (unsigned char)hextoint( &str[j*2] );
|
|
}
|
|
pToken->dwType = TEXT_TOKEN::COLOR_FX;
|
|
// a,r,g,b
|
|
pToken->dwColor = (colors[3] << 24) | (colors[0] << 16) | (colors[1] << 8) | colors[2];
|
|
}
|
|
return;
|
|
|
|
case 32: //"2XGLOW"
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::GLOW2X;
|
|
}
|
|
return;
|
|
case 33: //"/2XGLOW"
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::GLOW2XOFF;
|
|
}
|
|
return;
|
|
// 그려질 오브젝트 y 오프셋 추가 적용
|
|
case 34: // OFFSETY:
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::OFFSETY;
|
|
pToken->nOffsetY = atoi(lpszToken + strlen(cmds[34]));
|
|
}
|
|
return;
|
|
case 35: // CARET
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::CARET;
|
|
}
|
|
return;
|
|
case 36: // CARET_OFF
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::CARET_OFF;
|
|
}
|
|
return;
|
|
// 그려질 오브젝트 y 오프셋 추가 적용
|
|
case 37: // OFFSET:
|
|
{
|
|
pToken->dwType = TEXT_TOKEN::OFFSET;
|
|
pToken->dwOffset = atoi(lpszToken + strlen(cmds[37]));
|
|
}
|
|
return;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
pToken->dwType = TEXT_TOKEN::UNKNOWN;
|
|
}
|
|
|
|
|
|
#ifdef _COUNTRY_ME_
|
|
|
|
void KTextParser::AddEmoticonFilter( const std::string& strText, const std::string& strAni )
|
|
{
|
|
s_mapEmoticonFilter.insert( mapEmoticon::value_type( strText, strAni ) );
|
|
}
|
|
|
|
// 2010.06.08 - prodongi
|
|
void KTextParser::_AddString( LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit, bool scroll )
|
|
//void KTextParser::_AddString( LPCSTR lpszString, int nDepth, DWORD dwMaxWidth, bool bTagEnable, bool bUseSplit )
|
|
{
|
|
Clear();
|
|
|
|
int nCount = 0;
|
|
bool bLoop = true;
|
|
|
|
KParagraphAttr attrCurrent;
|
|
|
|
bool bStrike = false;
|
|
bool bUnder = false;
|
|
bool bInverse = false;
|
|
|
|
KTextParagraph* pTextPara = new KTextParagraph( attrCurrent );
|
|
|
|
if ( bTagEnable )
|
|
{
|
|
|
|
while ( bLoop )
|
|
{
|
|
TEXT_TOKEN token;
|
|
_GetNextToken(&token, lpszString, nCount);
|
|
switch ( token.dwType )
|
|
{
|
|
case TEXT_TOKEN::EOS :
|
|
bLoop = false;
|
|
break;
|
|
|
|
case TEXT_TOKEN::TEXT :
|
|
pTextPara->AddString( token.sText );
|
|
break;
|
|
case TEXT_TOKEN::EMOTICON :
|
|
{
|
|
imapEmoticon itor = s_mapEmoticonFilter.find( token.sText );
|
|
if ( itor != s_mapEmoticonFilter.end() )
|
|
{
|
|
if ( pTextPara->GetLength() )
|
|
{
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
pTextPara->m_bEmoticon = true;
|
|
pTextPara->m_strText = itor->second.c_str();
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::SHADOW:
|
|
if ( pTextPara->m_attr.bShadow == false )
|
|
{
|
|
if ( pTextPara->GetLength() )
|
|
{
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
pTextPara->m_attr.bShadow = true;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::SHADOWOFF:
|
|
if ( pTextPara->m_attr.bShadow == true )
|
|
{
|
|
if ( pTextPara->GetLength() )
|
|
{
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
pTextPara->m_attr.bShadow = false;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::BREAK:
|
|
case TEXT_TOKEN::PAGEBREAK:
|
|
pTextPara->SetLineBreak( true );
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
break;
|
|
|
|
case TEXT_TOKEN::OFFSET:
|
|
if ( pTextPara->GetLength() )
|
|
{
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
pTextPara->SetOffsetX( token.dwOffset );
|
|
break;
|
|
|
|
case TEXT_TOKEN::OFFSETY:
|
|
if ( pTextPara->GetLength() )
|
|
{
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
pTextPara = new KTextParagraph( attrCurrent );
|
|
}
|
|
pTextPara->SetOffsetY( token.nOffsetY );
|
|
break;
|
|
|
|
case TEXT_TOKEN::COLOR:
|
|
if ( attrCurrent.dwColor != token.dwColor )
|
|
{
|
|
if ( pTextPara->GetString().empty() )
|
|
pTextPara->m_attr.dwColor = token.dwColor;
|
|
else
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_FCOLOR, token.dwColor );
|
|
attrCurrent.dwColor = token.dwColor;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::FONT:
|
|
{
|
|
std::string strFontName = KFontManager::GetInstance()->GetFaceName( token.sText.c_str() );
|
|
if ( strFontName != attrCurrent.strFontName )
|
|
{
|
|
if ( pTextPara->GetString().empty() )
|
|
pTextPara->m_attr.strFontName = KFontManager::GetInstance()->GetFaceName( strFontName.c_str() );
|
|
else
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_FONT, strFontName );
|
|
attrCurrent.strFontName = strFontName;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::SIZE:
|
|
if ( attrCurrent.nFontSize != token.dwFontSize )
|
|
{
|
|
if ( pTextPara->GetString().empty() )
|
|
pTextPara->m_attr.nFontSize = token.dwFontSize;
|
|
else
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_SIZE, token.dwFontSize );
|
|
|
|
attrCurrent.nFontSize = token.dwFontSize;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::GLOW:
|
|
pTextPara->m_attr.bGlow = true;
|
|
attrCurrent.bGlow = true;
|
|
break;
|
|
|
|
case TEXT_TOKEN::BOLD:
|
|
if ( attrCurrent.bBold == false )
|
|
{
|
|
if ( pTextPara->GetLength() )
|
|
pTextPara->m_attr.bBold = true;
|
|
else
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_BOLD, true );
|
|
attrCurrent.bBold = true;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::UNBOLD:
|
|
if ( attrCurrent.bBold == true )
|
|
{
|
|
if ( pTextPara->GetLength() )
|
|
pTextPara->m_attr.bBold = false;
|
|
else
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_BOLD, false );
|
|
attrCurrent.bBold = false;
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::UNDER_LINE:
|
|
if ( !bUnder )
|
|
{
|
|
bUnder = true;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_UNDERLINE, bUnder );
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::UNDER_LINEOFF:
|
|
if ( bUnder )
|
|
{
|
|
bUnder = false;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_UNDERLINE, bUnder );
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::STRIKE_LINE:
|
|
if ( !bStrike )
|
|
{
|
|
bStrike = true;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_STRIKE, bStrike );
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::STRIKE_LINEOFF:
|
|
if ( bStrike )
|
|
{
|
|
bStrike = false;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_STRIKE, bStrike );
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::HALIGN: m_dwHAlign = token.dwAlign; break;
|
|
case TEXT_TOKEN::VALIGN: m_dwVAlign = token.dwAlign; break;
|
|
|
|
case TEXT_TOKEN::INVERSE:
|
|
if ( !bInverse )
|
|
{
|
|
bInverse = true;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_INVERSE, bInverse );
|
|
}
|
|
break;
|
|
|
|
case TEXT_TOKEN::INVERSE_OFF:
|
|
if ( bInverse )
|
|
{
|
|
bInverse = false;
|
|
pTextPara->AddAttribute( KTextParagraph::KTextAttrBase::TA_INVERSE, bInverse );
|
|
}
|
|
break;
|
|
|
|
|
|
}
|
|
}
|
|
if ( pTextPara->GetLength() )
|
|
m_vtTextParagraph.push_back( pTextPara );
|
|
else
|
|
delete pTextPara;
|
|
}
|
|
}
|
|
|
|
|
|
#endif |