mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 06:00:33 -04:00
185 lines
No EOL
5.7 KiB
C++
185 lines
No EOL
5.7 KiB
C++
// WStringProxy.cpp: implementation of the WStringProxy class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include "WStringProxy.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
/** Funkce vytvoøí transitivní uzávìr.
|
|
to znamená, že zruší všechny zøetìzené redirecty.
|
|
*/
|
|
WStringProxy *WStringProxy::TransitivniUzaver()
|
|
{
|
|
if (_operation==OpSubstr && _offset==0 && _stringSize==_baseString->GetLength())
|
|
{
|
|
WStringProxy *next=_baseString->TransitivniUzaver();
|
|
if (next==NULL) return this;
|
|
next->AddRef();
|
|
_baseString->Release();
|
|
_baseString=next;
|
|
return next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/** Main render procedure
|
|
It creates allocates buffer proxy and renders tree into it
|
|
Then turns self into redirect proxy a redirect self into newly created string
|
|
Rerurns pointer to newly created proxy
|
|
*/
|
|
WStringProxy *WStringProxy::RenderString()
|
|
{
|
|
if (_operation==OpMemBlck) return this;
|
|
|
|
WStringProxy *pp=TransitivniUzaver();
|
|
if (pp!=NULL) return pp->_baseString->RenderString();
|
|
|
|
WStringProxy *newProxy=WStringMemory::AllocString(NULL,_stringSize);
|
|
wchar_t *renderPtr=const_cast<wchar_t *>(newProxy->GetStringFromMemBlock());
|
|
|
|
RenderStringToBuffer(renderPtr);
|
|
|
|
newProxy->AddRef();
|
|
this->~WStringProxy();
|
|
_operation=OpSubstr;
|
|
_offset=0;
|
|
_baseString=newProxy;
|
|
|
|
return newProxy;
|
|
}
|
|
|
|
/** Function renders simple effect into buffer
|
|
Function needs buffer with nul terminated string
|
|
*/
|
|
void WStringProxy::RenderSimpleEffect(wchar_t *renderPtr)
|
|
{
|
|
assert(_operation==OpEffect);
|
|
switch (_effect)
|
|
{
|
|
case EfLower: wcslwr(renderPtr);break;
|
|
case EfUpper: wcsupr(renderPtr);break;
|
|
case EfReverse: wcsrev(renderPtr);break;
|
|
}
|
|
|
|
}
|
|
|
|
/** Light phase of rendering. Used to render string that is not
|
|
created from substring. This part is optimized for concat and user effects
|
|
When substring must be rendered, function call RenderStringToBufferSubstr to
|
|
render substring.
|
|
*/
|
|
void WStringProxy::RenderStringToBuffer(wchar_t *renderPtr)
|
|
{
|
|
WStringMemory::LockProxy(this);
|
|
switch (_operation)
|
|
{
|
|
case OpConcat:
|
|
_baseString->RenderStringToBuffer(renderPtr);
|
|
_secondString->RenderStringToBuffer(renderPtr+_baseString->GetLength());
|
|
break;
|
|
case OpSubstr:
|
|
{
|
|
_baseString->RenderStringToBufferSubstr(renderPtr,_offset,GetLength());
|
|
}
|
|
break;
|
|
case OpMemBlck:
|
|
{
|
|
const wchar_t *str=GetStringFromMemBlock();
|
|
wcsncpy(renderPtr,str,_stringSize);
|
|
}
|
|
break;
|
|
case OpEffect:
|
|
{
|
|
unsigned long offset=0;
|
|
renderPtr[_stringSize]=0; //we can append zero, because right side of string is not yet rendered
|
|
//if this is end of string, one extra character for zero is also allocated.
|
|
//efect functions can rely on it.
|
|
if (_blockData2>=256) offset=_userEffect->PreRenderString(renderPtr,_baseString->GetLength()); //call prerender to prepare begin of buffer
|
|
_baseString->RenderStringToBuffer(renderPtr+offset); //render string to rest of buffer
|
|
if (_blockData2>=256) _userEffect->RenderString(renderPtr,_baseString->GetLength()); //apply effect to buffer
|
|
else RenderSimpleEffect(renderPtr);
|
|
}
|
|
break;
|
|
};
|
|
WStringMemory::UnlockProxy(this);
|
|
}
|
|
|
|
/**
|
|
Deep phase of rendering. Function can render substrings, or render substring of two
|
|
concated strings. Function can also perform partial effect on string. Function cannot
|
|
handle partial user effect, so this effects are converted to things strings.
|
|
*/
|
|
void WStringProxy::RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size)
|
|
{
|
|
WStringMemory::LockProxy(this);
|
|
switch (_operation)
|
|
{
|
|
case OpConcat:
|
|
{
|
|
//process substring of concat
|
|
//count characters in buffer
|
|
size_t rendered;
|
|
//when string starts in left string
|
|
if (_baseString->GetLength()>offset)
|
|
{
|
|
//calculate total characters that may be rendered
|
|
rendered=_baseString->GetLength()-offset;
|
|
//but limit it to request size
|
|
if (rendered>size) rendered=size;
|
|
//render substring into buffer
|
|
_baseString->RenderStringToBufferSubstr(renderPtr,offset,rendered);
|
|
}
|
|
else
|
|
//no character has been rendered
|
|
rendered=0;
|
|
|
|
//there is still characters remained to render. We will take it from second string
|
|
if (size-rendered>0)
|
|
{
|
|
if (offset>_baseString->GetLength()) offset-=_baseString->GetLength();
|
|
else offset=0;
|
|
_secondString->RenderStringToBufferSubstr(renderPtr+rendered,offset,size-rendered);
|
|
}
|
|
}
|
|
break;
|
|
case OpSubstr:
|
|
{ //rendering substrings is very easy
|
|
offset+=_offset; //add offset of substring
|
|
assert(offset+size<=GetLength()); //check length
|
|
//render substring
|
|
this->RenderStringToBufferSubstr(renderPtr,offset,size);
|
|
}
|
|
break;
|
|
case OpMemBlck:
|
|
{
|
|
//rendering from memory, final stop in recursion
|
|
//Get pointer string
|
|
const wchar_t *str=GetStringFromMemBlock();
|
|
//copy substring from string into render buffer
|
|
wcsncpy(renderPtr,str+offset,size);
|
|
}
|
|
break;
|
|
case OpEffect:
|
|
if (_blockData2>=256) //interface cannot handle partial rendering
|
|
{
|
|
RenderString(); //convert proxy to simple redirect and render it
|
|
RenderStringToBufferSubstr(renderPtr,offset,size); //now we are able to cut out part
|
|
}
|
|
else
|
|
{
|
|
//all standard effects maps string 1:1
|
|
//first get content of substring into buffer
|
|
_baseString->RenderStringToBufferSubstr(renderPtr,offset,size);
|
|
//we can append zero, because right side of string is not yet rendered
|
|
renderPtr[size]=0;
|
|
//process effect on target
|
|
RenderSimpleEffect(renderPtr);
|
|
}
|
|
break;
|
|
};
|
|
WStringMemory::UnlockProxy(this);
|
|
} |