void CGraphicTextInstance::Render(RECT * pClipRect)
{
if (!m_isUpdate)
return;
#if defined(WJ_MULTI_TEXTLINE)
for (const auto& v : multi_text)
v->Render();
#endif
CGraphicText* pkText=m_roText.GetPointer();
if (!pkText)
return;
CGraphicFontTexture* pFontTexture = pkText->GetFontTexturePointer();
if (!pFontTexture)
return;
float fStanX = m_v3Position.x;
float fStanY = m_v3Position.y + 1.0f;
UINT defCodePage = GetDefaultCodePage();
if (defCodePage == CP_ARABIC)
{
switch (m_hAlign)
{
case HORIZONTAL_ALIGN_LEFT:
fStanX -= m_textWidth;
break;
case HORIZONTAL_ALIGN_CENTER:
fStanX -= float(m_textWidth / 2);
break;
}
}
else
{
switch (m_hAlign)
{
case HORIZONTAL_ALIGN_RIGHT:
fStanX -= m_textWidth;
break;
case HORIZONTAL_ALIGN_CENTER:
fStanX -= float(m_textWidth / 2);
break;
}
}
switch (m_vAlign)
{
case VERTICAL_ALIGN_BOTTOM:
fStanY -= m_textHeight;
break;
case VERTICAL_ALIGN_CENTER:
fStanY -= float(m_textHeight) / 2.0f;
break;
}
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
DWORD dwLighting = STATEMANAGER.GetRenderState(D3DRS_LIGHTING);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
#ifdef ENABLE_FIX_MOBS_LAG
std::map<CGraphicImageTexture*, std::vector<SPDTVertexRaw>> verticesMap;
#endif
{
const float fFontHalfWeight=1.0f;
float fCurX;
float fCurY;
float fFontSx;
float fFontSy;
float fFontEx;
float fFontEy;
float fFontWidth;
float fFontHeight;
float fFontMaxHeight;
float fFontAdvance;
#ifdef ENABLE_FIX_MOBS_LAG
SPDTVertexRaw akVertex[4];
akVertex[0].pz = m_v3Position.z;
akVertex[1].pz = m_v3Position.z;
akVertex[2].pz = m_v3Position.z;
akVertex[3].pz = m_v3Position.z;
#else
SVertex akVertex[4];
akVertex[0].z = m_v3Position.z;
akVertex[1].z = m_v3Position.z;
akVertex[2].z = m_v3Position.z;
akVertex[3].z = m_v3Position.z;
#endif
CGraphicFontTexture::TCharacterInfomation* pCurCharInfo;
if (m_isOutline)
{
fCurX=fStanX;
fCurY=fStanY;
fFontMaxHeight=0.0f;
CGraphicFontTexture::TPCharacterInfomationVector::iterator i;
for (i=m_pCharInfoVector.begin(); i!=m_pCharInfoVector.end(); ++i)
{
pCurCharInfo = *i;
fFontWidth=float(pCurCharInfo->width);
fFontHeight=float(pCurCharInfo->height);
fFontAdvance=float(pCurCharInfo->advance);
if ((fCurX+fFontWidth)-m_v3Position.x > m_fLimitWidth)
{
if (m_isMultiLine)
{
fCurX=fStanX;
fCurY+=fFontMaxHeight;
}
else
{
break;
}
}
if (pClipRect)
{
if (fCurY <= pClipRect->top)
{
fCurX += fFontAdvance;
continue;
}
}
fFontSx = fCurX - 0.5f;
fFontSy = fCurY - 0.5f;
fFontEx = fFontSx + fFontWidth;
fFontEy = fFontSy + fFontHeight;
#ifdef ENABLE_FIX_MOBS_LAG
const auto tex = pFontTexture->GetTexture(pCurCharInfo->index);
auto& batchVertices = verticesMap[tex];
akVertex[0].u = pCurCharInfo->left;
akVertex[0].v = pCurCharInfo->top;
akVertex[1].u = pCurCharInfo->left;
akVertex[1].v = pCurCharInfo->bottom;
akVertex[2].u = pCurCharInfo->right;
akVertex[2].v = pCurCharInfo->top;
akVertex[3].u = pCurCharInfo->right;
akVertex[3].v = pCurCharInfo->bottom;
akVertex[3].diffuse = akVertex[2].diffuse = akVertex[1].diffuse = akVertex[0].diffuse = m_dwOutLineColor;
float feather = 0.0f; // m_fFontFeather
akVertex[0].py = fFontSy - feather;
akVertex[1].py = fFontEy + feather;
akVertex[2].py = fFontSy - feather;
akVertex[3].py = fFontEy + feather;
akVertex[0].px = fFontSx - fFontHalfWeight - feather;
akVertex[1].px = fFontSx - fFontHalfWeight - feather;
akVertex[2].px = fFontEx - fFontHalfWeight + feather;
akVertex[3].px = fFontEx - fFontHalfWeight + feather;
batchVertices.insert(batchVertices.end(),
std::begin(akVertex), std::end(akVertex));
akVertex[0].px = fFontSx + fFontHalfWeight - feather;
akVertex[1].px = fFontSx + fFontHalfWeight - feather;
akVertex[2].px = fFontEx + fFontHalfWeight + feather;
akVertex[3].px = fFontEx + fFontHalfWeight + feather;
batchVertices.insert(batchVertices.end(),
std::begin(akVertex), std::end(akVertex));
akVertex[0].px = fFontSx - feather;
akVertex[1].px = fFontSx - feather;
akVertex[2].px = fFontEx + feather;
akVertex[3].px = fFontEx + feather;
akVertex[0].py = fFontSy - fFontHalfWeight - feather;
akVertex[1].py = fFontEy - fFontHalfWeight + feather;
akVertex[2].py = fFontSy - fFontHalfWeight - feather;
akVertex[3].py = fFontEy - fFontHalfWeight + feather;
batchVertices.insert(batchVertices.end(),
std::begin(akVertex), std::end(akVertex));
akVertex[0].py = fFontSy + fFontHalfWeight - feather;
akVertex[1].py = fFontEy + fFontHalfWeight + feather;
akVertex[2].py = fFontSy + fFontHalfWeight - feather;
akVertex[3].py = fFontEy + fFontHalfWeight + feather;
batchVertices.insert(batchVertices.end(),
std::begin(akVertex), std::end(akVertex));
#else
pFontTexture->SelectTexture(pCurCharInfo->index);
STATEMANAGER.SetTexture(0, pFontTexture->GetD3DTexture());
akVertex[0].u=pCurCharInfo->left;
akVertex[0].v=pCurCharInfo->top;
akVertex[1].u=pCurCharInfo->left;
akVertex[1].v=pCurCharInfo->bottom;
akVertex[2].u=pCurCharInfo->right;
akVertex[2].v=pCurCharInfo->top;
akVertex[3].u=pCurCharInfo->right;
akVertex[3].v=pCurCharInfo->bottom;
akVertex[3].color = akVertex[2].color = akVertex[1].color = akVertex[0].color = m_dwOutLineColor;
float feather = 0.0f; // m_fFontFeather
akVertex[0].y=fFontSy-feather;
akVertex[1].y=fFontEy+feather;
akVertex[2].y=fFontSy-feather;
akVertex[3].y=fFontEy+feather;
// ¿Ş
akVertex[0].x=fFontSx-fFontHalfWeight-feather;
akVertex[1].x=fFontSx-fFontHalfWeight-feather;
akVertex[2].x=fFontEx-fFontHalfWeight+feather;
akVertex[3].x=fFontEx-fFontHalfWeight+feather;
if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// ¿À¸¥
akVertex[0].x=fFontSx+fFontHalfWeight-feather;
akVertex[1].x=fFontSx+fFontHalfWeight-feather;
akVertex[2].x=fFontEx+fFontHalfWeight+feather;
akVertex[3].x=fFontEx+fFontHalfWeight+feather;
if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
akVertex[0].x=fFontSx-feather;
akVertex[1].x=fFontSx-feather;
akVertex[2].x=fFontEx+feather;
akVertex[3].x=fFontEx+feather;
// ˤ
akVertex[0].y=fFontSy-fFontHalfWeight-feather;
akVertex[1].y=fFontEy-fFontHalfWeight+feather;
akVertex[2].y=fFontSy-fFontHalfWeight-feather;
akVertex[3].y=fFontEy-fFontHalfWeight+feather;
// 20041216.myevan.DrawPrimitiveUP
if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// ¾Æ·¡
akVertex[0].y=fFontSy+fFontHalfWeight-feather;
akVertex[1].y=fFontEy+fFontHalfWeight+feather;
akVertex[2].y=fFontSy+fFontHalfWeight-feather;
akVertex[3].y=fFontEy+fFontHalfWeight+feather;
// 20041216.myevan.DrawPrimitiveUP
if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
#endif
fCurX += fFontAdvance;
}
}
fCurX=fStanX;
fCurY=fStanY;
fFontMaxHeight=0.0f;
for (int i = 0; i < m_pCharInfoVector.size(); ++i)
{
pCurCharInfo = m_pCharInfoVector[i];
fFontWidth=float(pCurCharInfo->width);
fFontHeight=float(pCurCharInfo->height);
fFontMaxHeight=std::max<float>(fFontHeight, pCurCharInfo->height);
fFontAdvance=float(pCurCharInfo->advance);
if ((fCurX+fFontWidth)-m_v3Position.x > m_fLimitWidth)
{
if (m_isMultiLine)
{
fCurX=fStanX;
fCurY+=fFontMaxHeight;
}
else
{
break;
}
}
if (pClipRect)
{
if (fCurY <= pClipRect->top)
{
fCurX += fFontAdvance;
continue;
}
}
fFontSx = fCurX-0.5f;
fFontSy = fCurY-0.5f;
fFontEx = fFontSx + fFontWidth;
fFontEy = fFontSy + fFontHeight;
#ifdef ENABLE_FIX_MOBS_LAG
const auto tex = pFontTexture->GetTexture(pCurCharInfo->index);
auto& batchVertices = verticesMap[tex];
akVertex[0].px = fFontSx;
akVertex[0].py = fFontSy;
akVertex[0].u = pCurCharInfo->left;
akVertex[0].v = pCurCharInfo->top;
akVertex[1].px = fFontSx;
akVertex[1].py = fFontEy;
akVertex[1].u = pCurCharInfo->left;
akVertex[1].v = pCurCharInfo->bottom;
akVertex[2].px = fFontEx;
akVertex[2].py = fFontSy;
akVertex[2].u = pCurCharInfo->right;
akVertex[2].v = pCurCharInfo->top;
akVertex[3].px = fFontEx;
akVertex[3].py = fFontEy;
akVertex[3].u = pCurCharInfo->right;
akVertex[3].v = pCurCharInfo->bottom;
akVertex[0].diffuse = akVertex[1].diffuse = akVertex[2].diffuse = akVertex[3].diffuse = m_dwColorInfoVector[i];
batchVertices.insert(batchVertices.end(),
std::begin(akVertex), std::end(akVertex));
fCurX += fFontAdvance;
#else
pFontTexture->SelectTexture(pCurCharInfo->index);
STATEMANAGER.SetTexture(0, pFontTexture->GetD3DTexture());
akVertex[0].x=fFontSx;
akVertex[0].y=fFontSy;
akVertex[0].u=pCurCharInfo->left;
akVertex[0].v=pCurCharInfo->top;
akVertex[1].x=fFontSx;
akVertex[1].y=fFontEy;
akVertex[1].u=pCurCharInfo->left;
akVertex[1].v=pCurCharInfo->bottom;
akVertex[2].x=fFontEx;
akVertex[2].y=fFontSy;
akVertex[2].u=pCurCharInfo->right;
akVertex[2].v=pCurCharInfo->top;
akVertex[3].x=fFontEx;
akVertex[3].y=fFontEy;
akVertex[3].u=pCurCharInfo->right;
akVertex[3].v=pCurCharInfo->bottom;
//m_dwColorInfoVector[i];
//m_dwTextColor;
akVertex[0].color = akVertex[1].color = akVertex[2].color = akVertex[3].color = m_dwColorInfoVector[i];
// 20041216.myevan.DrawPrimitiveUP
if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, akVertex, sizeof(SVertex));
fCurX += fFontAdvance;
#endif
}
}
#ifdef ENABLE_FIX_MOBS_LAG
for (auto& p : verticesMap)
{
STATEMANAGER.SetTexture(0, p.first->GetD3DTexture());
for (auto f = p.second.begin(), l = p.second.end(); f != l; )
{
const auto batchCount = std::min<std::size_t>(LARGE_PDT_VERTEX_BUFFER_SIZE,
l - f);
if (CGraphicBase::SetPDTStream(&*f, batchCount))
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0,
batchCount - 2);
f += batchCount;
}
}
#endif
if (m_isCursor && !(CTimer::instance().GetCurrentSecond() >= m_isBlinking && (ELTimer_GetMSec() / 400) % 2))
{
// Draw Cursor
float sx, sy, ex, ey;
TDiffuse diffuse;
int curpos = CIME::GetCurPos();
int compend = curpos + CIME::GetCompLen();
__GetTextPos(curpos, &sx, &sy);
// If Composition
if(curpos<compend)
{
diffuse = 0x7fffffff;
__GetTextPos(compend, &ex, &sy);
}
else
{
diffuse = 0xffffffff;
ex = sx + 2;
}
// FOR_ARABIC_ALIGN
if (defCodePage == CP_ARABIC)
{
sx += m_v3Position.x - m_textWidth;
ex += m_v3Position.x - m_textWidth;
sy += m_v3Position.y;
ey = sy + m_textHeight;
}
else
{
sx += m_v3Position.x;
sy += m_v3Position.y;
ex += m_v3Position.x;
ey = sy + m_textHeight;
}
switch (m_vAlign)
{
case VERTICAL_ALIGN_BOTTOM:
sy -= m_textHeight;
break;
case VERTICAL_ALIGN_CENTER:
sy -= float(m_textHeight) / 2.0f;
break;
}
TPDTVertex vertices[4];
vertices[0].diffuse = diffuse;
vertices[1].diffuse = diffuse;
vertices[2].diffuse = diffuse;
vertices[3].diffuse = diffuse;
vertices[0].position = TPosition(sx, sy, 0.0f);
vertices[1].position = TPosition(ex, sy, 0.0f);
vertices[2].position = TPosition(sx, ey, 0.0f);
vertices[3].position = TPosition(ex, ey, 0.0f);
STATEMANAGER.SetTexture(0, NULL);
CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT);
if (CGraphicBase::SetPDTStream(vertices, 4))
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2);
int ulbegin = CIME::GetULBegin();
int ulend = CIME::GetULEnd();
if(ulbegin < ulend)
{
__GetTextPos(curpos+ulbegin, &sx, &sy);
__GetTextPos(curpos+ulend, &ex, &sy);
sx += m_v3Position.x;
sy += m_v3Position.y + m_textHeight;
ex += m_v3Position.x;
ey = sy + 2;
vertices[0].diffuse = 0xFFFF0000;
vertices[1].diffuse = 0xFFFF0000;
vertices[2].diffuse = 0xFFFF0000;
vertices[3].diffuse = 0xFFFF0000;
vertices[0].position = TPosition(sx, sy, 0.0f);
vertices[1].position = TPosition(ex, sy, 0.0f);
vertices[2].position = TPosition(sx, ey, 0.0f);
vertices[3].position = TPosition(ex, ey, 0.0f);
STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex));
}
}
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLighting);
if (!m_hyperlinkVector.empty())
{
int lx = gs_mx - m_v3Position.x;
int ly = gs_my - m_v3Position.y;
if (GetDefaultCodePage() == CP_ARABIC)
{
lx = -lx;
ly = -ly + m_textHeight;
}
if (lx >= 0 && ly >= 0 && lx < m_textWidth && ly < m_textHeight)
{
auto it = m_hyperlinkVector.begin();
while (it != m_hyperlinkVector.end())
{
SHyperlink & link = *it++;
if (lx >= link.sx && lx < link.ex)
{
gs_hyperlinkText = link.text;
/*
OutputDebugStringW(link.text.c_str());
OutputDebugStringW(L"\n");
*/
break;
}
}
}
}
#ifdef ENABLE_EMOJI_SYSTEM
if (m_emojiVector.empty() == false)
{
for(auto& rEmo : m_emojiVector)
{
if (rEmo.pInstance)
{
rEmo.pInstance->SetPosition(fStanX + rEmo.x, (fStanY + 7.0) - (rEmo.pInstance->GetHeight() / 4));
rEmo.pInstance->Render();
}
}
}
#endif
}