// ShapeArabic
//
void Typesetter::ShapeArabic(eastl_size_t iCharBegin, eastl_size_t iCharEnd)
{
    EA_ASSERT(iCharEnd <= mLineLayout.mCharArray.size());

    const OTF* const pOTF = mLineLayout.mAnalysisInfoArray[0].mpFont->GetOTF();

    // We more or less need to have OpenType font information in order to correctly display Arabic.
    if(pOTF && pOTF->IsScriptSupported("arab"))
    {
        const eastl_size_t iGlyphBegin = mLineLayout.GetGlyphIndexFromCharIndex(iCharBegin);

        for(eastl_size_t i = iCharBegin, charCount = 0; i < iCharEnd; i += charCount)
        {
            const AnalysisInfo* const pAnalysisInfo = &mLineLayout.mAnalysisInfoArray[i];

            Char         pCharCluster[kMaxArabicCharClusterSize];
            eastl_size_t charClusterSize = 0;

            charCount = GetGeneralCharCluster(i, iCharEnd, pCharCluster, charClusterSize);

            for(eastl_size_t c = 0, charsEaten = 0, glyphCount = 0, glyphCountPrev = 0; c < charClusterSize; c += charsEaten)
            {
                GlyphId pGlyphIdArray[kMaxArabicGlyphClusterSize];

                charsEaten = GetGlyphsForChar(pCharCluster + c, charClusterSize - c, pAnalysisInfo, pGlyphIdArray + glyphCount, glyphCount);

                AppendArabicGlyphCluster(iCharBegin, charCount, pCharCluster + c, charsEaten, 
                                        pGlyphIdArray + glyphCountPrev, glyphCount - glyphCountPrev, 
                                        pAnalysisInfo->mnBidiLevel, pOTF);

                glyphCountPrev = glyphCount;
            }
        }

        // Do OpenType substitutions.
        FeatureLookupArray featureLookupArray;

        SetupArabicGsubLookup(featureLookupArray, pOTF);
        AssignArabicCharProperties(&mLineLayout.mCharArray[iCharBegin], iCharEnd - iCharBegin, &mLineLayout.mGlyphInfoArray[iGlyphBegin]);
        DoGlyphSubstitution(mLineLayout, iGlyphBegin, featureLookupArray, pOTF);
        CompleteLineLayoutArrays(iCharBegin, iCharEnd, iGlyphBegin);
        PlaceGeneralGlyphCluster(iCharBegin, iCharEnd - iCharBegin);
    }
    else
    {
        // Generic fallback. Arabic text will look wrong, but at least something will be displayed.
        ShapeGeneral(iCharBegin, iCharEnd);
    }
}
void Typesetter::ShapeIndic(eastl_size_t iBegin, eastl_size_t iCharEnd)
{
    // To do: Complete this shaper.
    ShapeGeneral(iBegin, iCharEnd);
}