Files
2026-06-01 12:46:52 +02:00

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