// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 **********************************************************************
 *   Copyright (C) 2002-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */

/*
 * paragraphLayout doesn't make much sense without
 * BreakIterator...
 */
#include "layout/LETypes.h"
#include "layout/LEScripts.h"
#include "layout/LELanguages.h"
#include "layout/LayoutEngine.h"
#include "layout/LEFontInstance.h"

#include "unicode/ubidi.h"
#include "unicode/uchriter.h"
#include "unicode/brkiter.h"

#if ! UCONFIG_NO_BREAK_ITERATION
#include "LXUtilities.h"
#include "usc_impl.h" /* this is currently private! */
#include "cstring.h"  /* this too! */

#include "layout/ParagraphLayout.h"

U_NAMESPACE_BEGIN

#define ARRAY_SIZE(array) (sizeof array  / sizeof array[0])

/* Leave this copyright notice here! It needs to go somewhere in this library. */
static const char copyright[] = U_COPYRIGHT_STRING;

class StyleRuns
{
public:
    StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount);

    ~StyleRuns();

    le_int32 getRuns(le_int32 runLimits[], le_int32 styleIndices[]);

private:
    le_int32 fStyleCount;
    le_int32 fRunCount;

    le_int32 *fRunLimits;
    le_int32 *fStyleIndices;
};

StyleRuns::StyleRuns(const RunArray *styleRunArrays[], le_int32 styleCount)
    : fStyleCount(styleCount), fRunCount(0), fRunLimits(nullptr), fStyleIndices(nullptr)
{
    le_int32 maxRunCount = 0;
    le_int32 style, run, runStyle;
    le_int32 *currentRun = LE_NEW_ARRAY(le_int32, styleCount);

    for (int i = 0; i < styleCount; i += 1) {
        maxRunCount += styleRunArrays[i]->getCount();
    }

    maxRunCount -= styleCount - 1;

    fRunLimits    = LE_NEW_ARRAY(le_int32, maxRunCount);
    fStyleIndices = LE_NEW_ARRAY(le_int32, maxRunCount * styleCount);

    for (style = 0; style < styleCount; style += 1) {
        currentRun[style] = 0;
    }

    run = 0;
    runStyle = 0;

    /*
     * Since the last run limit for each style run must be
     * the same, all the styles will hit the last limit at
     * the same time, so we know when we're done when the first
     * style hits the last limit.
     */
    while (currentRun[0] < styleRunArrays[0]->getCount()) {
        fRunLimits[run] = 0x7FFFFFFF;

        // find the minimum run limit for all the styles
        for (style = 0; style < styleCount; style += 1) {
            if (styleRunArrays[style]->getLimit(currentRun[style]) < fRunLimits[run]) {
                fRunLimits[run] = styleRunArrays[style]->getLimit(currentRun[style]);
            }
        }

        // advance all styles whose current run is at this limit to the next run
        for (style = 0; style < styleCount; style += 1) {
            fStyleIndices[runStyle++] = currentRun[style];

            if (styleRunArrays[style]->getLimit(currentRun[style]) == fRunLimits[run]) {
                currentRun[style] += 1;
            }
        }

        run += 1;
    }

    fRunCount = run;
    LE_DELETE_ARRAY(currentRun);
}

StyleRuns::~StyleRuns()
{
    fRunCount = 0;

    LE_DELETE_ARRAY(fStyleIndices);
    fStyleIndices = nullptr;

    LE_DELETE_ARRAY(fRunLimits);
    fRunLimits = nullptr;
}

le_int32 StyleRuns::getRuns(le_int32 runLimits[], le_int32 styleIndices[])
{
    if (runLimits != nullptr) {
        LE_ARRAY_COPY(runLimits, fRunLimits, fRunCount);
    }

    if (styleIndices != nullptr) {
        LE_ARRAY_COPY(styleIndices, fStyleIndices, fRunCount * fStyleCount);
    }

    return fRunCount;
}

/*
 * NOTE: This table only has "true" values for
 * those scripts which the LayoutEngine can currently
 * process, rather for all scripts which require
 * complex processing for correct rendering.
 */
static const le_bool complexTable[] = {
    false , /* Zyyy */
    false,  /* Qaai */
    true,   /* Arab */
    false,  /* Armn */
    true,   /* Beng */
    false,  /* Bopo */
    false,  /* Cher */
    false,  /* Copt=Qaac */
    false,  /* Cyrl */
    false,  /* Dsrt */
    true,   /* Deva */
    false,  /* Ethi */
    false,  /* Geor */
    false,  /* Goth */
    false,  /* Grek */
    true,   /* Gujr */
    true,   /* Guru */
    false,  /* Hani */
    false,  /* Hang */
    true,   /* Hebr */
    false,  /* Hira */
    true,   /* Knda */
    false,  /* Kana */
    false,  /* Khmr */
    false,  /* Laoo */
    false,  /* Latn */
    true,   /* Mlym */
    false,  /* Mong */
    false,  /* Mymr */
    false,  /* Ogam */
    false,  /* Ital */
    true,   /* Orya */
    false,  /* Runr */
    false,  /* Sinh */
    false,  /* Syrc */
    true,   /* Taml */
    true,   /* Telu */
    false,  /* Thaa */
    true,   /* Thai */
    false,  /* Tibt */
    false,  /* Cans */
    false,  /* Yiii */
    false,  /* Tglg */
    false,  /* Hano */
    false,  /* Buhd */
    false,  /* Tagb */
    false,  /* Brai */
    false,  /* Cprt */
    false,  /* Limb */
    false,  /* Linb */
    false,  /* Osma */
    false,  /* Shaw */
    false,  /* Tale */
    false,  /* Ugar */
    false,  /* Hrkt */
    false,  /* Bugi */
    false,  /* Glag */
    false,  /* Khar */
    false,  /* Sylo */
    false,  /* Talu */
    false,  /* Tfng */
    false,  /* Xpeo */
    false,  /* Bali */
    false,  /* Batk */
    false,  /* Blis */
    false,  /* Brah */
    false,  /* Cham */
    false,  /* Cirt */
    false,  /* Cyrs */
    false,  /* Egyd */
    false,  /* Egyh */
    false,  /* Egyp */
    false,  /* Geok */
    false,  /* Hans */
    false,  /* Hant */
    false,  /* Hmng */
    false,  /* Hung */
    false,  /* Inds */
    false,  /* Java */
    false,  /* Kali */
    false,  /* Latf */
    false,  /* Latg */
    false,  /* Lepc */
    false,  /* Lina */
    false,  /* Mand */
    false,  /* Maya */
    false,  /* Mero */
    false,  /* Nkoo */
    false,  /* Orkh */
    false,  /* Perm */
    false,  /* Phag */
    false,  /* Phnx */
    false,  /* Plrd */
    false,  /* Roro */
    false,  /* Sara */
    false,  /* Syre */
    false,  /* Syrj */
    false,  /* Syrn */
    false,  /* Teng */
    false,  /* Taii */
    false,  /* Visp */
    false,  /* Xsux */
    false,  /* Zxxx */
    false,  /* Zzzz */
    false,  /* Cari */
    false,  /* Jpan */
    false,  /* Lana */
    false,  /* Lyci */
    false,  /* Lydi */
    false,  /* Olck */
    false,  /* Rjng */
    false,  /* Saur */
    false,  /* Sgnw */
    false,  /* Sund */
    false,  /* Moon */
    false,  /* Mtei */
    false,  /* Armi */
    false,  /* Avst */
    false,  /* Cakm */
    false,  /* Kore */
    false,  /* Kthi */
    false,  /* Mani */
    false,  /* Phli */
    false,  /* Phlp */
    false,  /* Phlv */
    false,  /* Prti */
    false,  /* Samr */
    false,  /* Tavt */
    false,  /* Zmth */
    false,  /* Zsym */
    false,  /* Bamu */
    false,  /* Lisu */
    false,  /* Nkgb */
    false   /* Sarb */
};


const char ParagraphLayout::fgClassID = 0;

static void fillMissingCharToGlyphMapValues(le_int32 *charToGlyphMap,
                                            le_int32 charCount) {
    le_int32 lastValidGlyph = -1;
    le_int32 ch;
    for (ch = 0; ch <= charCount; ch += 1) {
        if (charToGlyphMap[ch] == -1) {
            charToGlyphMap[ch] = lastValidGlyph;
        } else {
            lastValidGlyph = charToGlyphMap[ch];
        }
    }
}

/*
 * How to deal with composite fonts:
 *
 * Don't store the client's FontRuns; we'll need to compute sub-font FontRuns using Doug's
 * LEFontInstance method. Do that by intersecting the client's FontRuns with fScriptRuns. Use
 * that to compute fFontRuns, and then intersect fFontRuns, fScriptRuns and fLevelRuns. Doing
 * it in this order means we do a two-way intersection and a three-way intersection.
 *
 * An optimization would be to only do this if there's at least one composite font...
 *
 * Other notes:
 *
 * * Return the sub-fonts as the run fonts... could keep the mapping back to the client's FontRuns
 *   but that probably makes it more complicated of everyone...
 *
 * * Take the LineInfo and LineRun types from Paragraph and use them here, incorporate them into the API.
 *
 * * Might want to change the name of the StyleRun type, and make a new one that holds fonts, scripts and levels?
 *
 */
ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count,
                                 const FontRuns   *fontRuns,
                                 const ValueRuns  *levelRuns,
                                 const ValueRuns  *scriptRuns,
                                 const LocaleRuns *localeRuns,
                                 UBiDiLevel paragraphLevel, le_bool vertical,
                                 LEErrorCode &status)
                                 : fChars(chars), fCharCount(count),
                                   fFontRuns(nullptr), fLevelRuns(levelRuns), fScriptRuns(scriptRuns), fLocaleRuns(localeRuns),
                                   fVertical(vertical), fClientLevels(true), fClientScripts(true), fClientLocales(true), fEmbeddingLevels(nullptr),
                                   fAscent(0), fDescent(0), fLeading(0),
                                   fGlyphToCharMap(nullptr), fCharToMinGlyphMap(nullptr), fCharToMaxGlyphMap(nullptr), fGlyphWidths(nullptr), fGlyphCount(0),
                                   fParaBidi(nullptr), fLineBidi(nullptr),
                                   fStyleRunLimits(nullptr), fStyleIndices(nullptr), fStyleRunCount(0),
                                   fBreakIterator(nullptr), fLineStart(-1), fLineEnd(0),
                                 /*fVisualRuns(nullptr), fStyleRunInfo(nullptr), fVisualRunCount(-1),
                                   fFirstVisualRun(-1), fLastVisualRun(-1),*/ fVisualRunLastX(0), fVisualRunLastY(0)
{

    if (LE_FAILURE(status)) {
        fCharCount = -1;
        return;
    }

    (void)copyright;  // Suppress unused variable warning.
    (void)fVertical;  // Suppress warning for unused field fVertical.

    // FIXME: should check the limit arrays for consistency...

    computeLevels(paragraphLevel);

    if (scriptRuns == nullptr) {
        computeScripts();
    }

    if (localeRuns == nullptr) {
        computeLocales();
    }

    computeSubFonts(fontRuns, status);

    if (LE_FAILURE(status)) {
        //other stuff?
        fCharCount = -1;
        return;
    }

    // now intersect the font, direction and script runs...
    const RunArray *styleRunArrays[] = {fFontRuns, fLevelRuns, fScriptRuns, fLocaleRuns};
    le_int32  styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0];
    StyleRuns styleRuns(styleRunArrays, styleCount);
    LEErrorCode layoutStatus = LE_NO_ERROR;

    fStyleRunCount = styleRuns.getRuns(nullptr, nullptr);

    fStyleRunLimits = LE_NEW_ARRAY(le_int32, fStyleRunCount);
    fStyleIndices   = LE_NEW_ARRAY(le_int32, fStyleRunCount * styleCount);
    if ((fStyleRunLimits == nullptr) || (fStyleIndices == nullptr)) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }

    styleRuns.getRuns(fStyleRunLimits, fStyleIndices);

    // now build a LayoutEngine for each style run...
    le_int32 *styleIndices = fStyleIndices;
    le_int32 run, runStart;

    fStyleRunInfo = LE_NEW_ARRAY(StyleRunInfo, fStyleRunCount);
    if (fStyleRunInfo == nullptr) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }
    else {
        // initialize
        for (run = 0; run < fStyleRunCount; run += 1) {
            fStyleRunInfo[run].font = nullptr;
            fStyleRunInfo[run].runBase = 0;
            fStyleRunInfo[run].runLimit = 0;
            fStyleRunInfo[run].script = static_cast<UScriptCode>(0);
            fStyleRunInfo[run].locale = nullptr;
            fStyleRunInfo[run].level = 0;
            fStyleRunInfo[run].glyphBase = 0;
            fStyleRunInfo[run].engine = nullptr;
            fStyleRunInfo[run].glyphCount = 0;
            fStyleRunInfo[run].glyphs = nullptr;
            fStyleRunInfo[run].positions = nullptr;
        }
    }

    fGlyphCount = 0;
    for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
        fStyleRunInfo[run].font      = fFontRuns->getFont(styleIndices[0]);
        fStyleRunInfo[run].runBase   = runStart;
        fStyleRunInfo[run].runLimit  = fStyleRunLimits[run];
        fStyleRunInfo[run].script = static_cast<UScriptCode>(fScriptRuns->getValue(styleIndices[2]));
        fStyleRunInfo[run].locale    = fLocaleRuns->getLocale(styleIndices[3]);
        fStyleRunInfo[run].level = static_cast<UBiDiLevel>(fLevelRuns->getValue(styleIndices[1]));
        fStyleRunInfo[run].glyphBase = fGlyphCount;

        fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font,
            fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount,
            fStyleRunInfo[run].level & 1, 0, 0, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        runStart = fStyleRunLimits[run];
        styleIndices += styleCount;
        fGlyphCount += fStyleRunInfo[run].glyphCount;
    }

    // Make big arrays for the glyph widths, glyph-to-char and char-to-glyph maps,
    // in logical order. (Both maps need an extra entry for the end of the text.)
    //
    // For each layout get the positions and convert them into glyph widths, in
    // logical order. Get the glyph-to-char mapping, offset by starting index in the
    // character array. Swap the glyph width and glyph-to-char arrays into logical order.
    // Finally, fill in the char-to-glyph mappings.
    fGlyphWidths       = LE_NEW_ARRAY(float, fGlyphCount);
    fGlyphToCharMap    = LE_NEW_ARRAY(le_int32, fGlyphCount + 1);
    fCharToMinGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
    fCharToMaxGlyphMap = LE_NEW_ARRAY(le_int32, fCharCount + 1);
    if ((fGlyphWidths == nullptr) || (fGlyphToCharMap == nullptr) ||
        (fCharToMinGlyphMap == nullptr) || (fCharToMaxGlyphMap == nullptr)) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }

    le_int32 glyph;

    for (runStart = 0, run = 0; run < fStyleRunCount; run += 1) {
        LayoutEngine *engine = fStyleRunInfo[run].engine;
        le_int32 glyphCount  = fStyleRunInfo[run].glyphCount;
        le_int32 glyphBase   = fStyleRunInfo[run].glyphBase;

        fStyleRunInfo[run].glyphs = LE_NEW_ARRAY(LEGlyphID, glyphCount);
        fStyleRunInfo[run].positions = LE_NEW_ARRAY(float, glyphCount * 2 + 2);
        if ((fStyleRunInfo[run].glyphs == nullptr) ||
            (fStyleRunInfo[run].positions == nullptr)) {
            status = LE_MEMORY_ALLOCATION_ERROR;
            return;
        }

        engine->getGlyphs(fStyleRunInfo[run].glyphs, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        engine->getGlyphPositions(fStyleRunInfo[run].positions, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        engine->getCharIndices(&fGlyphToCharMap[glyphBase], runStart, layoutStatus);
        if (LE_FAILURE(layoutStatus)) {
            status = layoutStatus;
            return;
        }

        for (glyph = 0; glyph < glyphCount; glyph += 1) {
            fGlyphWidths[glyphBase + glyph] = fStyleRunInfo[run].positions[glyph * 2 + 2] - fStyleRunInfo[run].positions[glyph * 2];
        }

        if ((fStyleRunInfo[run].level & 1) != 0) {
            LXUtilities::reverse(&fGlyphWidths[glyphBase], glyphCount);
            LXUtilities::reverse(&fGlyphToCharMap[glyphBase], glyphCount);
        }

        runStart = fStyleRunLimits[run];

        delete engine;
        fStyleRunInfo[run].engine = nullptr;
    }

    fGlyphToCharMap[fGlyphCount] = fCharCount;

    // Initialize the char-to-glyph maps to -1 so that we can later figure out
    // whether any of the entries in the map aren't filled in below.
    le_int32 chIndex;
    for (chIndex = 0; chIndex <= fCharCount; chIndex += 1) {
        fCharToMinGlyphMap[chIndex] = -1;
        fCharToMaxGlyphMap[chIndex] = -1;
    }

    for (glyph = fGlyphCount - 1; glyph >= 0; glyph -= 1) {
        le_int32 ch = fGlyphToCharMap[glyph];

        fCharToMinGlyphMap[ch] = glyph;
    }

    fCharToMinGlyphMap[fCharCount] = fGlyphCount;

    for (glyph = 0; glyph < fGlyphCount; glyph += 1) {
        le_int32 ch = fGlyphToCharMap[glyph];

        fCharToMaxGlyphMap[ch] = glyph;
    }

    fCharToMaxGlyphMap[fCharCount] = fGlyphCount;

    // Now fill in the missing values in the char-to-glyph maps.
    fillMissingCharToGlyphMapValues(fCharToMinGlyphMap, fCharCount);
    fillMissingCharToGlyphMapValues(fCharToMaxGlyphMap, fCharCount);
}

ParagraphLayout::~ParagraphLayout()
{
    delete const_cast<FontRuns*>(fFontRuns);

    if (! fClientLevels) {
        delete const_cast<ValueRuns*>(fLevelRuns);
        fLevelRuns = nullptr;

        fClientLevels = true;
    }

    if (! fClientScripts) {
        delete const_cast<ValueRuns*>(fScriptRuns);
        fScriptRuns = nullptr;

        fClientScripts = true;
    }

    if (! fClientLocales) {
        delete const_cast<LocaleRuns*>(fLocaleRuns);
        fLocaleRuns = nullptr;

        fClientLocales = true;
    }

    if (fEmbeddingLevels != nullptr) {
        LE_DELETE_ARRAY(fEmbeddingLevels);
        fEmbeddingLevels = nullptr;
    }

    if (fGlyphToCharMap != nullptr) {
        LE_DELETE_ARRAY(fGlyphToCharMap);
        fGlyphToCharMap = nullptr;
    }

    if (fCharToMinGlyphMap != nullptr) {
        LE_DELETE_ARRAY(fCharToMinGlyphMap);
        fCharToMinGlyphMap = nullptr;
    }

    if (fCharToMaxGlyphMap != nullptr) {
        LE_DELETE_ARRAY(fCharToMaxGlyphMap);
        fCharToMaxGlyphMap = nullptr;
    }

    if (fGlyphWidths != nullptr) {
        LE_DELETE_ARRAY(fGlyphWidths);
        fGlyphWidths = nullptr;
    }

    if (fParaBidi != nullptr) {
        ubidi_close(fParaBidi);
        fParaBidi = nullptr;
    }

    if (fLineBidi != nullptr) {
        ubidi_close(fLineBidi);
        fLineBidi = nullptr;
    }

    if (fStyleRunCount > 0) {
        le_int32 run;

        LE_DELETE_ARRAY(fStyleRunLimits);
        LE_DELETE_ARRAY(fStyleIndices);

        for (run = 0; run < fStyleRunCount; run += 1) {
            LE_DELETE_ARRAY(fStyleRunInfo[run].glyphs);
            LE_DELETE_ARRAY(fStyleRunInfo[run].positions);

            fStyleRunInfo[run].glyphs    = nullptr;
            fStyleRunInfo[run].positions = nullptr;
        }

        LE_DELETE_ARRAY(fStyleRunInfo);

        fStyleRunLimits = nullptr;
        fStyleIndices   = nullptr;
        fStyleRunInfo        = nullptr;
        fStyleRunCount  = 0;
    }

    if (fBreakIterator != nullptr) {
        delete fBreakIterator;
        fBreakIterator = nullptr;
    }
}


le_bool ParagraphLayout::isComplex(const LEUnicode chars[], le_int32 count)
{
    UErrorCode scriptStatus = U_ZERO_ERROR;
    UScriptCode scriptCode  = USCRIPT_INVALID_CODE;
    UScriptRun *sr = uscript_openRun(chars, count, &scriptStatus);
    le_bool result = false;

    while (uscript_nextRun(sr, nullptr, nullptr, &scriptCode)) {
        if (isComplex(scriptCode)) {
            result = true;
            break;
        }
    }

    uscript_closeRun(sr);
    return result;
}

le_int32 ParagraphLayout::getAscent() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        const_cast<ParagraphLayout*>(this)->computeMetrics();
    }

    return fAscent;
}

le_int32 ParagraphLayout::getDescent() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        const_cast<ParagraphLayout*>(this)->computeMetrics();
    }

    return fDescent;
}

le_int32 ParagraphLayout::getLeading() const
{
    if (fAscent <= 0 && fCharCount > 0) {
        const_cast<ParagraphLayout*>(this)->computeMetrics();
    }

    return fLeading;
}

le_bool ParagraphLayout::isDone() const
{
    return fLineEnd >= fCharCount;
}

ParagraphLayout::Line *ParagraphLayout::nextLine(float width)
{
    if (isDone()) {
        return nullptr;
    }

    fLineStart = fLineEnd;

    if (width > 0) {
        le_int32 glyph    = fCharToMinGlyphMap[fLineStart];
        float widthSoFar  = 0;

        while (glyph < fGlyphCount && widthSoFar + fGlyphWidths[glyph] <= width) {
            widthSoFar += fGlyphWidths[glyph++];
        }

        // If no glyphs fit on the line, force one to fit.
        //
        // (There shouldn't be any zero width glyphs at the
        // start of a line unless the paragraph consists of
        // only zero width glyphs, because otherwise the zero
        // width glyphs will have been included on the end of
        // the previous line...)
        if (widthSoFar == 0 && glyph < fGlyphCount) {
            glyph += 1;
        }

        fLineEnd = previousBreak(fGlyphToCharMap[glyph]);

        // If this break is at or before the last one,
        // find a glyph, starting at the one which didn't
        // fit, that produces a break after the last one.
        while (fLineEnd <= fLineStart) {
            fLineEnd = fGlyphToCharMap[glyph++];
        }
    } else {
        fLineEnd = fCharCount;
    }

    return computeVisualRuns();
}

void ParagraphLayout::computeLevels(UBiDiLevel paragraphLevel)
{
    UErrorCode bidiStatus = U_ZERO_ERROR;

    if (fLevelRuns != nullptr) {
        le_int32 ch;
        le_int32 run;

        fEmbeddingLevels = LE_NEW_ARRAY(UBiDiLevel, fCharCount);

        for (ch = 0, run = 0; run < fLevelRuns->getCount(); run += 1) {
            UBiDiLevel runLevel = static_cast<UBiDiLevel>(fLevelRuns->getValue(run)) | UBIDI_LEVEL_OVERRIDE;
            le_int32   runLimit = fLevelRuns->getLimit(run);

            while (ch < runLimit) {
                fEmbeddingLevels[ch++] = runLevel;
            }
        }
    }

    fParaBidi = ubidi_openSized(fCharCount, 0, &bidiStatus);
    ubidi_setPara(fParaBidi, fChars, fCharCount, paragraphLevel, fEmbeddingLevels, &bidiStatus);

    if (fLevelRuns == nullptr) {
        le_int32 levelRunCount = ubidi_countRuns(fParaBidi, &bidiStatus);
        ValueRuns *levelRuns = new ValueRuns(levelRunCount);

        le_int32 logicalStart = 0;
        le_int32 run;
        le_int32 limit;
        UBiDiLevel level;

        for (run = 0; run < levelRunCount; run += 1) {
            ubidi_getLogicalRun(fParaBidi, logicalStart, &limit, &level);
            levelRuns->add(level, limit);
            logicalStart = limit;
        }

        fLevelRuns    = levelRuns;
        fClientLevels = false;
    }
}

void ParagraphLayout::computeScripts()
{
    UErrorCode scriptStatus = U_ZERO_ERROR;
    UScriptRun *sr = uscript_openRun(fChars, fCharCount, &scriptStatus);
    ValueRuns  *scriptRuns = new ValueRuns(0);
    le_int32 limit;
    UScriptCode script;

    while (uscript_nextRun(sr, nullptr, &limit, &script)) {
        scriptRuns->add(script, limit);
    }

    uscript_closeRun(sr);

    fScriptRuns    = scriptRuns;
    fClientScripts = false;
}

void ParagraphLayout::computeLocales()
{
    LocaleRuns *localeRuns = new LocaleRuns(0);
    const Locale *defaultLocale = &Locale::getDefault();

    localeRuns->add(defaultLocale, fCharCount);

    fLocaleRuns    = localeRuns;
    fClientLocales = false;
}

void ParagraphLayout::computeSubFonts(const FontRuns *fontRuns, LEErrorCode &status)
{
    if (LE_FAILURE(status)) {
        return;
    }

    const RunArray *styleRunArrays[] = {fontRuns, fScriptRuns};
    le_int32 styleCount = sizeof styleRunArrays / sizeof styleRunArrays[0];
    StyleRuns styleRuns(styleRunArrays, styleCount);
    le_int32 styleRunCount = styleRuns.getRuns(nullptr, nullptr);
    le_int32 *styleRunLimits = LE_NEW_ARRAY(le_int32, styleRunCount);
    le_int32 *styleIndices = LE_NEW_ARRAY(le_int32, styleRunCount * styleCount);
    FontRuns *subFontRuns  = new FontRuns(0);
    le_int32  run, offset, *si;

    styleRuns.getRuns(styleRunLimits, styleIndices);

    si = styleIndices;
    offset = 0;

    for (run = 0; run < styleRunCount; run += 1) {
        const LEFontInstance *runFont = fontRuns->getFont(si[0]);
        le_int32 script = fScriptRuns->getValue(si[1]);

        while (offset < styleRunLimits[run]) {
            const LEFontInstance *subFont = runFont->getSubFont(fChars, &offset, styleRunLimits[run], script, status);

            if (LE_FAILURE(status)) {
                delete subFontRuns;
                goto cleanUp;
            }

            subFontRuns->add(subFont, offset);
        }

        si += styleCount;
    }

    fFontRuns = subFontRuns;

cleanUp:
    LE_DELETE_ARRAY(styleIndices);
    LE_DELETE_ARRAY(styleRunLimits);
}

void ParagraphLayout::computeMetrics()
{
    le_int32 i, count = fFontRuns->getCount();
    le_int32 maxDL = 0;

    for (i = 0; i < count; i += 1) {
        const LEFontInstance *font = fFontRuns->getFont(i);
        le_int32 ascent  = font->getAscent();
        le_int32 descent = font->getDescent();
        le_int32 leading = font->getLeading();
        le_int32 dl      = descent + leading;

        if (ascent > fAscent) {
            fAscent = ascent;
        }

        if (descent > fDescent) {
            fDescent = descent;
        }

        if (leading > fLeading) {
            fLeading = leading;
        }

        if (dl > maxDL) {
            maxDL = dl;
        }
    }

    fLeading = maxDL - fDescent;
}

#if 1
struct LanguageMap
{
    const char *localeCode;
    le_int32 languageCode;
};

static const LanguageMap languageMap[] =
{
    {"afr", afkLanguageCode}, // Afrikaans
    {"ara", araLanguageCode}, // Arabic
    {"asm", asmLanguageCode}, // Assamese
    {"bel", belLanguageCode}, // Belarussian
    {"ben", benLanguageCode}, // Bengali
    {"bod", tibLanguageCode}, // Tibetan
    {"bul", bgrLanguageCode}, // Bulgarian
    {"cat", catLanguageCode}, // Catalan
    {"ces", csyLanguageCode}, // Czech
    {"che", cheLanguageCode}, // Chechen
    {"cop", copLanguageCode}, // Coptic
    {"cym", welLanguageCode}, // Welsh
    {"dan", danLanguageCode}, // Danish
    {"deu", deuLanguageCode}, // German
    {"dzo", dznLanguageCode}, // Dzongkha
    {"ell", ellLanguageCode}, // Greek
    {"eng", engLanguageCode}, // English
    {"est", etiLanguageCode}, // Estonian
    {"eus", euqLanguageCode}, // Basque
    {"fas", farLanguageCode}, // Farsi
    {"fin", finLanguageCode}, // Finnish
    {"fra", fraLanguageCode}, // French
    {"gle", gaeLanguageCode}, // Irish Gaelic
    {"guj", gujLanguageCode}, // Gujarati
    {"hau", hauLanguageCode}, // Hausa
    {"heb", iwrLanguageCode}, // Hebrew
    {"hin", hinLanguageCode}, // Hindi
    {"hrv", hrvLanguageCode}, // Croatian
    {"hun", hunLanguageCode}, // Hungarian
    {"hye", hyeLanguageCode}, // Armenian
    {"ind", indLanguageCode}, // Indonesian
    {"ita", itaLanguageCode}, // Italian
    {"jpn", janLanguageCode}, // Japanese
    {"kan", kanLanguageCode}, // Kannada
    {"kas", kshLanguageCode}, // Kashmiri
    {"khm", khmLanguageCode}, // Khmer
    {"kok", kokLanguageCode}, // Konkani
    {"kor", korLanguageCode}, // Korean
//  {"mal_XXX", malLanguageCode}, // Malayalam - Traditional
    {"mal", mlrLanguageCode}, // Malayalam - Reformed
    {"mar", marLanguageCode}, // Marathi
    {"mlt", mtsLanguageCode}, // Maltese
    {"mni", mniLanguageCode}, // Manipuri
    {"mon", mngLanguageCode}, // Mongolian
    {"nep", nepLanguageCode}, // Nepali
    {"ori", oriLanguageCode}, // Oriya
    {"pol", plkLanguageCode}, // Polish
    {"por", ptgLanguageCode}, // Portuguese
    {"pus", pasLanguageCode}, // Pashto
    {"ron", romLanguageCode}, // Romanian
    {"rus", rusLanguageCode}, // Russian
    {"san", sanLanguageCode}, // Sanskrit
    {"sin", snhLanguageCode}, // Sinhalese
    {"slk", skyLanguageCode}, // Slovak
    {"snd", sndLanguageCode}, // Sindhi
    {"slv", slvLanguageCode}, // Slovenian
    {"spa", espLanguageCode}, // Spanish
    {"sqi", sqiLanguageCode}, // Albanian
    {"srp", srbLanguageCode}, // Serbian
    {"swe", sveLanguageCode}, // Swedish
    {"syr", syrLanguageCode}, // Syriac
    {"tam", tamLanguageCode}, // Tamil
    {"tel", telLanguageCode}, // Telugu
    {"tha", thaLanguageCode}, // Thai
    {"tur", trkLanguageCode}, // Turkish
    {"urd", urdLanguageCode}, // Urdu
    {"yid", jiiLanguageCode}, // Yiddish
//  {"zhp", zhpLanguageCode}, // Chinese - Phonetic
    {"zho", zhsLanguageCode}, // Chinese
    {"zho_CHN", zhsLanguageCode}, // Chinese - China
    {"zho_HKG", zhsLanguageCode}, // Chinese - Hong Kong
    {"zho_MAC", zhtLanguageCode}, // Chinese - Macao
    {"zho_SGP", zhsLanguageCode}, // Chinese - Singapore
    {"zho_TWN", zhtLanguageCode}  // Chinese - Taiwan
};

static const le_int32 languageMapCount = ARRAY_SIZE(languageMap);

le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
    char code[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    const char *language = locale->getISO3Language();
    const char *country  = locale->getISO3Country();

    uprv_strcat(code, language);

    if ((uprv_strcmp(language, "zho") == 0) && country != nullptr) {
        uprv_strcat(code, "_");
        uprv_strcat(code, country);
    }

    for (le_int32 i = 0; i < languageMapCount; i += 1) {
        if (uprv_strcmp(code, languageMap[i].localeCode) == 0) {
            return languageMap[i].languageCode;
        }
    }

    return nullLanguageCode;
}
#else

// TODO - dummy implementation for right now...
le_int32 ParagraphLayout::getLanguageCode(const Locale *locale)
{
    return nullLanguageCode;
}
#endif

le_bool ParagraphLayout::isComplex(UScriptCode script)
{
    if (script < 0 || script >= ARRAY_SIZE(complexTable)) {
        return false;
    }

    return complexTable[script];
}

le_int32 ParagraphLayout::previousBreak(le_int32 charIndex)
{
    // skip over any whitespace or control characters,
    // because they can hang in the margin.
    while (charIndex < fCharCount &&
           (u_isWhitespace(fChars[charIndex]) ||
            u_iscntrl(fChars[charIndex]))) {
        charIndex += 1;
    }

    // Create the BreakIterator if we don't already have one
    if (fBreakIterator == nullptr) {
        Locale thai("th");
        UCharCharacterIterator *iter = new UCharCharacterIterator(fChars, fCharCount);
        UErrorCode status = U_ZERO_ERROR;

        fBreakIterator = BreakIterator::createLineInstance(thai, status);
        fBreakIterator->adoptText(iter);
    }

    // return the break location that's at or before
    // the character we stopped on. Note: if we're
    // on a break, the "+ 1" will cause preceding to
    // back up to it.
    return fBreakIterator->preceding(charIndex + 1);
}

ParagraphLayout::Line *ParagraphLayout::computeVisualRuns()
{
    UErrorCode bidiStatus = U_ZERO_ERROR;
    le_int32 dirRunCount, visualRun;

    fVisualRunLastX = 0;
    fVisualRunLastY = 0;
    fFirstVisualRun = getCharRun(fLineStart);
    fLastVisualRun  = getCharRun(fLineEnd - 1);

    if (fLineBidi == nullptr) {
        fLineBidi = ubidi_openSized(fCharCount, 0, &bidiStatus);
    }

    ubidi_setLine(fParaBidi, fLineStart, fLineEnd, fLineBidi, &bidiStatus);
    dirRunCount = ubidi_countRuns(fLineBidi, &bidiStatus);

    Line *line = new Line();

    for (visualRun = 0; visualRun < dirRunCount; visualRun += 1) {
        le_int32 relStart, run, runLength;
        UBiDiDirection runDirection = ubidi_getVisualRun(fLineBidi, visualRun, &relStart, &runLength);
        le_int32 runStart = fLineStart + relStart;
        le_int32 runEnd   = runStart + runLength - 1;
        le_int32 firstRun = getCharRun(runStart);
        le_int32 lastRun  = getCharRun(runEnd);
        le_int32 startRun = (runDirection == UBIDI_LTR)? firstRun : lastRun;
        le_int32 stopRun  = (runDirection == UBIDI_LTR)? lastRun + 1 : firstRun - 1;
        le_int32 dir      = (runDirection == UBIDI_LTR)?  1 : -1;

        for (run = startRun; run != stopRun; run += dir) {
            le_int32 firstChar = (run == firstRun)? runStart : fStyleRunInfo[run].runBase;
            le_int32 lastChar  = (run == lastRun)?  runEnd   : fStyleRunInfo[run].runLimit - 1;

            appendRun(line, run, firstChar, lastChar);
        }
    }

    return line;
}

void ParagraphLayout::appendRun(ParagraphLayout::Line *line, le_int32 run, le_int32 firstChar, le_int32 lastChar)
{
    le_int32 glyphBase = fStyleRunInfo[run].glyphBase;
    le_int32 inGlyph, outGlyph;

    // Get the glyph indices for all the characters between firstChar and lastChar,
    // make the minimum one be leftGlyph and the maximum one be rightGlyph.
    // (need to do this to handle local reorderings like Indic left matras)
    le_int32 leftGlyph  = fGlyphCount;
    le_int32 rightGlyph = -1;
    le_int32 ch;

    for (ch = firstChar; ch <= lastChar; ch += 1) {
        le_int32 minGlyph = fCharToMinGlyphMap[ch];
        le_int32 maxGlyph = fCharToMaxGlyphMap[ch];

        if (minGlyph < leftGlyph) {
            leftGlyph = minGlyph;
        }

        if (maxGlyph > rightGlyph) {
            rightGlyph = maxGlyph;
        }
    }

    if ((fStyleRunInfo[run].level & 1) != 0) {
        le_int32 swap = rightGlyph;
        le_int32 last = glyphBase + fStyleRunInfo[run].glyphCount - 1;

        // Here, we want to remove the glyphBase bias...
        rightGlyph = last - leftGlyph;
        leftGlyph  = last - swap;
    } else {
        rightGlyph -= glyphBase;
        leftGlyph  -= glyphBase;
    }

    // Set the position bias for the glyphs. If we're at the start of
    // a line, we want the first glyph to be at x = 0, even if it comes
    // from the middle of a layout. If we've got a right-to-left run, we
    // want the left-most glyph to start at the final x position of the
    // previous run, even though this glyph may be in the middle of the
    // run.
    fVisualRunLastX -= fStyleRunInfo[run].positions[leftGlyph * 2];

    // Make rightGlyph be the glyph just to the right of
    // the run's glyphs
    rightGlyph += 1;

    UBiDiDirection direction  = ((fStyleRunInfo[run].level & 1) == 0)? UBIDI_LTR : UBIDI_RTL;
    le_int32   glyphCount     = rightGlyph - leftGlyph;
    LEGlyphID *glyphs         = LE_NEW_ARRAY(LEGlyphID, glyphCount);
    float     *positions      = LE_NEW_ARRAY(float, glyphCount * 2 + 2);
    le_int32  *glyphToCharMap = LE_NEW_ARRAY(le_int32, glyphCount);

    LE_ARRAY_COPY(glyphs, &fStyleRunInfo[run].glyphs[leftGlyph], glyphCount);

    for (outGlyph = 0, inGlyph = leftGlyph * 2; inGlyph <= rightGlyph * 2; inGlyph += 2, outGlyph += 2) {
        positions[outGlyph]     = fStyleRunInfo[run].positions[inGlyph] + fVisualRunLastX;
        positions[outGlyph + 1] = fStyleRunInfo[run].positions[inGlyph + 1] + fVisualRunLastY;
    }

    // Save the ending position of this run
    // to use for the start of the next run
    fVisualRunLastX = positions[outGlyph - 2];
    fVisualRunLastY = positions[outGlyph - 1];

    if ((fStyleRunInfo[run].level & 1) == 0) {
        for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) {
            glyphToCharMap[outGlyph] = fGlyphToCharMap[glyphBase + inGlyph];
        }
    } else {
        // Because fGlyphToCharMap is stored in logical order to facilitate line breaking,
        // we need to map the physical glyph indices to logical indices while we copy the
        // character indices.
        le_int32 base = glyphBase + fStyleRunInfo[run].glyphCount - 1;

        for (outGlyph = 0, inGlyph = leftGlyph; inGlyph < rightGlyph; inGlyph += 1, outGlyph += 1) {
            glyphToCharMap[outGlyph] = fGlyphToCharMap[base - inGlyph];
        }
    }

    line->append(fStyleRunInfo[run].font, direction, glyphCount, glyphs, positions, glyphToCharMap);
}

le_int32 ParagraphLayout::getCharRun(le_int32 charIndex)
{
    if (charIndex < 0 || charIndex > fCharCount) {
        return -1;
    }

    le_int32 run;

    // NOTE: as long as fStyleRunLimits is well-formed
    // the above range check guarantees that we'll never
    // fall off the end of the array.
    run = 0;
    while (charIndex >= fStyleRunLimits[run]) {
        run += 1;
    }

    return run;
}


const char ParagraphLayout::Line::fgClassID = 0;

#define INITIAL_RUN_CAPACITY 4
#define RUN_CAPACITY_GROW_LIMIT 16

ParagraphLayout::Line::~Line()
{
    le_int32 i;

    for (i = 0; i < fRunCount; i += 1) {
        delete fRuns[i];
    }

    LE_DELETE_ARRAY(fRuns);
}

le_int32 ParagraphLayout::Line::getAscent() const
{
    if (fAscent <= 0) {
        const_cast<ParagraphLayout::Line*>(this)->computeMetrics();
    }

    return fAscent;
}

le_int32 ParagraphLayout::Line::getDescent() const
{
    if (fAscent <= 0) {
        const_cast<ParagraphLayout::Line*>(this)->computeMetrics();
    }

    return fDescent;
}

le_int32 ParagraphLayout::Line::getLeading() const
{
    if (fAscent <= 0) {
        const_cast<ParagraphLayout::Line*>(this)->computeMetrics();
    }

    return fLeading;
}

le_int32 ParagraphLayout::Line::getWidth() const
{
    const VisualRun *lastRun = getVisualRun(fRunCount - 1);

    if (lastRun == nullptr) {
        return 0;
    }

    le_int32 glyphCount = lastRun->getGlyphCount();
    const float *positions = lastRun->getPositions();

    return static_cast<le_int32>(positions[glyphCount * 2]);
}

const ParagraphLayout::VisualRun *ParagraphLayout::Line::getVisualRun(le_int32 runIndex) const
{
    if (runIndex < 0 || runIndex >= fRunCount) {
        return nullptr;
    }

    return fRuns[runIndex];
}

void ParagraphLayout::Line::append(const LEFontInstance *font, UBiDiDirection direction, le_int32 glyphCount,
                                   const LEGlyphID glyphs[], const float positions[], const le_int32 glyphToCharMap[])
{
    if (fRunCount >= fRunCapacity) {
        if (fRunCapacity == 0) {
            fRunCapacity = INITIAL_RUN_CAPACITY;
            fRuns = LE_NEW_ARRAY(ParagraphLayout::VisualRun *, fRunCapacity);
        } else {
            fRunCapacity += (fRunCapacity < RUN_CAPACITY_GROW_LIMIT? fRunCapacity : RUN_CAPACITY_GROW_LIMIT);
            fRuns = static_cast<ParagraphLayout::VisualRun**>(LE_GROW_ARRAY(fRuns, fRunCapacity));
        }
    }

    fRuns[fRunCount++] = new ParagraphLayout::VisualRun(font, direction, glyphCount, glyphs, positions, glyphToCharMap);
}

void ParagraphLayout::Line::computeMetrics()
{
    le_int32 maxDL = 0;

    for (le_int32 i = 0; i < fRunCount; i += 1) {
        le_int32 ascent  = fRuns[i]->getAscent();
        le_int32 descent = fRuns[i]->getDescent();
        le_int32 leading = fRuns[i]->getLeading();
        le_int32 dl      = descent + leading;

        if (ascent > fAscent) {
            fAscent = ascent;
        }

        if (descent > fDescent) {
            fDescent = descent;
        }

        if (leading > fLeading) {
            fLeading = leading;
        }

        if (dl > maxDL) {
            maxDL = dl;
        }
    }

    fLeading = maxDL - fDescent;
}

const char ParagraphLayout::VisualRun::fgClassID = 0;

ParagraphLayout::VisualRun::~VisualRun()
{
    LE_DELETE_ARRAY(fGlyphToCharMap);
    LE_DELETE_ARRAY(fPositions);
    LE_DELETE_ARRAY(fGlyphs);
}

U_NAMESPACE_END

#endif

