}
/***********************************************************************
ScriptFragment
***********************************************************************/
struct GlyphData
{
Array
Array<SCRIPT_VISATTR> glyphVisattrs;
Array
Array
Array
ABC runAbc;
GlyphData()
{
memset(&runAbc, 0, sizeof(runAbc));
}
void ClearUniscribeData(int glyphCount, int length)
{
glyphs.Resize(glyphCount);
glyphVisattrs.Resize(glyphCount);
glyphAdvances.Resize(glyphCount);
glyphOffsets.Resize(glyphCount);
charCluster.Resize(length);
memset(&runAbc, 0, sizeof(runAbc));
}
bool BuildUniscribeData(WinDC* dc, DocumentFragment* documentFragment, SCRIPT_ITEM* scriptItem, SCRIPT_CACHE& scriptCache, const wchar_t* runText, int length)
{
int glyphCount=glyphs.Count();
bool resizeGlyphData=false;
if(glyphCount==0)
{
glyphCount=(int)(1.5*length+16);
resizeGlyphData=true;
}
{
// generate shape information
WinDC* dcParameter=0;
if(resizeGlyphData)
{
glyphs.Resize(glyphCount);
glyphVisattrs.Resize(glyphCount);
charCluster.Resize(length);
}
while(true)
{
int availableGlyphCount=0;
HRESULT hr=ScriptShape(
(dcParameter dcParameter->GetHandle():NULL),
&scriptCache,
runText,
length,
glyphCount,
&scriptItem->a,
&glyphs[0],
&charCluster[0],
&glyphVisattrs[0],
&availableGlyphCount
);
if(hr==0)
{
glyphCount=availableGlyphCount;
break;
}
else if(hr==E_PENDING)
{
dcParameter=dc;
}
else if(hr==E_OUTOFMEMORY)
{
if(resizeGlyphData)
{
glyphCount+=length;
}
else
{
goto BUILD_UNISCRIBE_DATA_FAILED;
}
}
else
{
goto BUILD_UNISCRIBE_DATA_FAILED;
}
}
if(resizeGlyphData)
{
glyphs.Resize(glyphCount);
glyphVisattrs.Resize(glyphCount);
}