/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "rtl/ustring.hxx"

#include "osl/module.h"
#include "osl/file.h"

#include "tools/svwin.h"

#include "vcl/svapp.hxx"

#include "win/salgdi.h"
#include "win/saldata.hxx"

// for GetMirroredChar
#include "sft.hxx"
#include "sallayout.hxx"

#include <cstdio>
#include <malloc.h>
#ifndef __MINGW32__
#define alloca _alloca
#endif

#ifdef GCP_KERN_HACK
    #include <algorithm>
#endif // GCP_KERN_HACK


#define USE_UNISCRIBE
#ifdef USE_UNISCRIBE
#include <Usp10.h>
#include <ShLwApi.h>
#include <winver.h>
#endif // USE_UNISCRIBE

#include <hash_map>
#include <set>

typedef std::hash_map<int,int> IntMap;
typedef std::set<int> IntSet;

// Graphite headers
#ifdef ENABLE_GRAPHITE
#include <i18npool/mslangid.hxx>
#include <graphite/GrClient.h>
#include <graphite/WinFont.h>
#include <graphite/Segment.h>
#include <graphite_layout.hxx>
#include <graphite_cache.hxx>
#include <graphite_features.hxx>
#endif

#define DROPPED_OUTGLYPH 0xFFFF

using namespace rtl;

// =======================================================================

// win32 specific physical font instance
class ImplWinFontEntry : public ImplFontEntry
{
public:
    explicit                ImplWinFontEntry( ImplFontSelectData& );
    virtual                 ~ImplWinFontEntry();

private:
    // TODO: also add HFONT??? Watch out for issues with too many active fonts...

#ifdef GCP_KERN_HACK
public:
    bool                    HasKernData() const;
    void                    SetKernData( int, const KERNINGPAIR* );
    int                     GetKerning( sal_Unicode, sal_Unicode ) const;
private:
    KERNINGPAIR*            mpKerningPairs;
    int                     mnKerningPairs;
#endif // GCP_KERN_HACK

#ifdef USE_UNISCRIBE
public:
    SCRIPT_CACHE&           GetScriptCache() const
                            { return maScriptCache; }
private:
    mutable SCRIPT_CACHE    maScriptCache;
#endif // USE_UNISCRIBE

public:
    int                     GetCachedGlyphWidth( int nCharCode ) const;
    void                    CacheGlyphWidth( int nCharCode, int nCharWidth );

	bool					InitKashidaHandling( HDC ); 
	int						GetMinKashidaWidth() const { return mnMinKashidaWidth; }
	int						GetMinKashidaGlyph() const { return mnMinKashidaGlyph; }

private:
    IntMap                  maWidthMap;
	mutable int				mnMinKashidaWidth;
	mutable int				mnMinKashidaGlyph;
};

// -----------------------------------------------------------------------

inline void ImplWinFontEntry::CacheGlyphWidth( int nCharCode, int nCharWidth )
{
    maWidthMap[ nCharCode ] = nCharWidth;
}

inline int ImplWinFontEntry::GetCachedGlyphWidth( int nCharCode ) const
{
    IntMap::const_iterator it = maWidthMap.find( nCharCode );
    if( it == maWidthMap.end() )
        return -1;
    return it->second;
}

// =======================================================================

class WinLayout : public SalLayout
{
public:
                        WinLayout( HDC, const ImplWinFontData&, ImplWinFontEntry& );
    virtual void        InitFont() const;
    void                SetFontScale( float f ) { mfFontScale = f; }
    float               GetFontScale() const    { return mfFontScale; }
    HFONT               DisableFontScaling( void) const;

#ifdef USE_UNISCRIBE
    SCRIPT_CACHE&       GetScriptCache() const
                            { return mrWinFontEntry.GetScriptCache(); }
#endif // USE_UNISCRIBE

protected:
    HDC                 mhDC;               // WIN32 device handle
    HFONT               mhFont;             // WIN32 font handle
    int                 mnBaseAdv;          // x-offset relative to Layout origin
    float               mfFontScale;        // allows metrics emulation of huge font sizes

    const ImplWinFontData& mrWinFontData;
    ImplWinFontEntry&   mrWinFontEntry;
};

// =======================================================================

class SimpleWinLayout : public WinLayout
{
public:
                    SimpleWinLayout( HDC, BYTE nCharSet, const ImplWinFontData&, ImplWinFontEntry& );
    virtual         ~SimpleWinLayout();

    virtual bool    LayoutText( ImplLayoutArgs& );
    virtual void    AdjustLayout( ImplLayoutArgs& );
    virtual void    DrawText( SalGraphics& ) const;

    virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
                        sal_Int32* pGlyphAdvances, int* pCharIndexes ) const;

    virtual long    FillDXArray( long* pDXArray ) const;
    virtual int     GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const;
    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const;

    // for glyph+font+script fallback
    virtual void    MoveGlyph( int nStart, long nNewXPos );
    virtual void    DropGlyph( int nStart );
    virtual void    Simplify( bool bIsBase );

protected:
    void            Justify( long nNewWidth );
    void            ApplyDXArray( const ImplLayoutArgs& );

private:
    int             mnGlyphCount;
    int             mnCharCount;
    WCHAR*          mpOutGlyphs;
    int*            mpGlyphAdvances;    // if possible this is shared with mpGlyphAdvances[]
    int*            mpGlyphOrigAdvs;
    int*            mpCharWidths;       // map rel char pos to char width
    int*            mpChars2Glyphs;     // map rel char pos to abs glyph pos
    int*            mpGlyphs2Chars;     // map abs glyph pos to abs char pos
    bool*           mpGlyphRTLFlags;    // BiDi status for glyphs: true=>RTL
    mutable long    mnWidth;
    bool            mbDisableGlyphs;

    int             mnNotdefWidth;
    BYTE            mnCharSet;
};

// =======================================================================

WinLayout::WinLayout( HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE )
:   mhDC( hDC ),
    mhFont( (HFONT)::GetCurrentObject(hDC,OBJ_FONT) ),
    mnBaseAdv( 0 ),
    mfFontScale( 1.0 ),
    mrWinFontData( rWFD ),
    mrWinFontEntry( rWFE )
{}

// -----------------------------------------------------------------------

void WinLayout::InitFont() const
{
    ::SelectObject( mhDC, mhFont );
}

// -----------------------------------------------------------------------

// Using reasonably sized fonts to emulate huge fonts works around
// a lot of problems in printer and display drivers. Huge fonts are
// mostly used by high resolution reference devices which are never
// painted to anyway. In the rare case that a huge font needs to be
// displayed somewhere then the workaround doesn't help anymore.
// If the drivers fail silently for huge fonts, so be it...
HFONT WinLayout::DisableFontScaling() const
{
    if( mfFontScale == 1.0 )
        return 0;

    LOGFONTW aLogFont;
    ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont);
    aLogFont.lfHeight = (LONG)(mfFontScale * aLogFont.lfHeight);
    aLogFont.lfWidth  = (LONG)(mfFontScale * aLogFont.lfWidth);
    HFONT hHugeFont = ::CreateFontIndirectW( &aLogFont);
    if( !hHugeFont )
        return 0;

    return SelectFont( mhDC, hHugeFont );
}

// =======================================================================

SimpleWinLayout::SimpleWinLayout( HDC hDC, BYTE nCharSet,
    const ImplWinFontData& rWinFontData, ImplWinFontEntry& rWinFontEntry )
:   WinLayout( hDC, rWinFontData, rWinFontEntry ),
    mnGlyphCount( 0 ),
    mnCharCount( 0 ),
    mpOutGlyphs( NULL ),
    mpGlyphAdvances( NULL ),
    mpGlyphOrigAdvs( NULL ),
    mpCharWidths( NULL ),
    mpChars2Glyphs( NULL ),
    mpGlyphs2Chars( NULL ),
    mpGlyphRTLFlags( NULL ),
    mnWidth( 0 ),
    mnNotdefWidth( -1 ),
    mnCharSet( nCharSet ),
    mbDisableGlyphs( false )
{
    mbDisableGlyphs = true;
}

// -----------------------------------------------------------------------

SimpleWinLayout::~SimpleWinLayout()
{
    delete[] mpGlyphRTLFlags;
    delete[] mpGlyphs2Chars;
    delete[] mpChars2Glyphs;
    if( mpCharWidths != mpGlyphAdvances )
        delete[] mpCharWidths;
    delete[] mpGlyphOrigAdvs;
    delete[] mpGlyphAdvances;
    delete[] mpOutGlyphs;
}

// -----------------------------------------------------------------------

bool SimpleWinLayout::LayoutText( ImplLayoutArgs& rArgs )
{
    // prepare layout
    // TODO: fix case when recyclying old SimpleWinLayout object
    mbDisableGlyphs |= ((rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) != 0);
    mnCharCount = rArgs.mnEndCharPos - rArgs.mnMinCharPos;

    if( !mbDisableGlyphs )
    {
        // Win32 glyph APIs have serious problems with vertical layout
        // => workaround is to use the unicode methods then
        if( rArgs.mnFlags & SAL_LAYOUT_VERTICAL )
            mbDisableGlyphs = true;
        else
            // use cached value from font face
            mbDisableGlyphs = mrWinFontData.IsGlyphApiDisabled();
    }

    // TODO: use a cached value for bDisableAsianKern from upper layers
    if( rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN )
    {
        TEXTMETRICA aTextMetricA;
        if( ::GetTextMetricsA( mhDC, &aTextMetricA )
        && !(aTextMetricA.tmPitchAndFamily & TMPF_FIXED_PITCH) && !(aTextMetricA.tmCharSet == 0x86) )
            rArgs.mnFlags &= ~SAL_LAYOUT_KERNING_ASIAN;
    }

    // layout text
    int i, j;

    mnGlyphCount = 0;
    bool bVertical = (rArgs.mnFlags & SAL_LAYOUT_VERTICAL) != 0;

    // count the number of chars to process if no RTL run
    rArgs.ResetPos();
    bool bHasRTL = false;
    while( rArgs.GetNextRun( &i, &j, &bHasRTL ) && !bHasRTL )
        mnGlyphCount += j - i;

    // if there are RTL runs we need room to remember individual BiDi flags
    if( bHasRTL )
    {
        mpGlyphRTLFlags = new bool[ mnCharCount ];
        for( i = 0; i < mnCharCount; ++i )
            mpGlyphRTLFlags[i] = false;
    }

    // rewrite the logical string if needed to prepare for the API calls
    const sal_Unicode* pBidiStr = rArgs.mpStr + rArgs.mnMinCharPos;
    if( (mnGlyphCount != mnCharCount) || bVertical )
    {
        // we need to rewrite the pBidiStr when any of
        // - BiDirectional layout
        // - vertical layout
        // - partial runs (e.g. with control chars or for glyph fallback)
        // are involved
        sal_Unicode* pRewrittenStr = (sal_Unicode*)alloca( mnCharCount * sizeof(sal_Unicode) );
        pBidiStr = pRewrittenStr;

        // note: glyph to char mapping is relative to first character
        mpChars2Glyphs = new int[ mnCharCount ];
        mpGlyphs2Chars = new int[ mnCharCount ];
        for( i = 0; i < mnCharCount; ++i )
            mpChars2Glyphs[i] = mpGlyphs2Chars[i] = -1;

        mnGlyphCount = 0;
        rArgs.ResetPos();
        bool bIsRTL = false;
        while( rArgs.GetNextRun( &i, &j, &bIsRTL ) )
        {
            do
            {
                // get the next leftmost character in this run
                int nCharPos = bIsRTL ? --j : i++;
                sal_UCS4 cChar = rArgs.mpStr[ nCharPos ];

                // in the RTL case mirror the character and remember its RTL status
                if( bIsRTL )
                {
                    cChar = ::GetMirroredChar( cChar );
                    mpGlyphRTLFlags[ mnGlyphCount ] = true;
                }

                // for vertical writing use vertical alternatives
                if( bVertical )
                {
                    sal_UCS4 cVert = ::GetVerticalChar( cChar );
                    if( cVert )
                        cChar = cVert;
                }

                // rewrite the original string
                // update the mappings between original and rewritten string
	       	// TODO: support surrogates in rewritten strings
                pRewrittenStr[ mnGlyphCount ] = static_cast<sal_Unicode>(cChar);
                mpGlyphs2Chars[ mnGlyphCount ] = nCharPos;
                mpChars2Glyphs[ nCharPos - rArgs.mnMinCharPos ] = mnGlyphCount;
                ++mnGlyphCount;
            } while( i < j );
        }
    }

    mpOutGlyphs     = new WCHAR[ mnGlyphCount ];
    mpGlyphAdvances = new int[ mnGlyphCount ];

    if( rArgs.mnFlags & (SAL_LAYOUT_KERNING_PAIRS | SAL_LAYOUT_KERNING_ASIAN) )
        mpGlyphOrigAdvs = new int[ mnGlyphCount ];

#ifndef GCP_KERN_HACK
    DWORD nGcpOption = 0;
    // enable kerning if requested
    if( rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS )
        nGcpOption |= GCP_USEKERNING;
#endif // GCP_KERN_HACK

    for( i = 0; i < mnGlyphCount; ++i )
        mpOutGlyphs[i] = pBidiStr[ i ];
    mnWidth = 0;
    for( i = 0; i < mnGlyphCount; ++i )
    {
        // get the current UCS-4 code point, check for surrogate pairs
        const WCHAR* pCodes = reinterpret_cast<LPCWSTR>(&pBidiStr[i]);
        unsigned nCharCode = pCodes[0];
        bool bSurrogate = ((nCharCode >= 0xD800) && (nCharCode <= 0xDFFF));
        if( bSurrogate )
        {
            if( nCharCode >= 0xDC00 ) // this part of a surrogate pair was already processed
                continue;
            nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + (pCodes[1] - 0xDC00);
	}

        // get the advance width for the current UCS-4 code point
        int nGlyphWidth = mrWinFontEntry.GetCachedGlyphWidth( nCharCode );
        if( nGlyphWidth == -1 )
        {
            ABC aABC;
            SIZE aExtent;
            if( ::GetTextExtentPoint32W( mhDC, &pCodes[0], bSurrogate ? 2 : 1, &aExtent) )
                nGlyphWidth = aExtent.cx;
            else if( ::GetCharABCWidthsW( mhDC, nCharCode, nCharCode, &aABC ) )
                nGlyphWidth = aABC.abcA + aABC.abcB + aABC.abcC;
            else if( !::GetCharWidth32W( mhDC, nCharCode, nCharCode, &nGlyphWidth )
                 &&  !::GetCharWidthW( mhDC, nCharCode, nCharCode, &nGlyphWidth ) )
                    nGlyphWidth = 0;
            mrWinFontEntry.CacheGlyphWidth( nCharCode, nGlyphWidth );
        }
        mpGlyphAdvances[ i ] = nGlyphWidth;
        mnWidth += nGlyphWidth;

        // remaining codes of surrogate pair get a zero width
        if( bSurrogate && ((i+1) < mnGlyphCount) )
            mpGlyphAdvances[ i+1 ] = 0;

        // check with the font face if glyph fallback is needed
        if( mrWinFontData.HasChar( nCharCode ) )
            continue;

        // request glyph fallback at this position in the string
        bool bRTL = mpGlyphRTLFlags ? mpGlyphRTLFlags[i] : false;
        int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[i]: i + rArgs.mnMinCharPos;
        rArgs.NeedFallback( nCharPos, bRTL );
        if( bSurrogate && ((nCharPos+1) < rArgs.mnLength) )
            rArgs.NeedFallback( nCharPos+1, bRTL );

        // replace the current glyph shape with the NotDef glyph shape
        if( rArgs.mnFlags & SAL_LAYOUT_FOR_FALLBACK )
        {
            // when we already are layouting for glyph fallback
            // then a new unresolved glyph is not interesting
            mnNotdefWidth = 0;
            mpOutGlyphs[i] = DROPPED_OUTGLYPH;
        }
        else
        {
            if( mnNotdefWidth < 0 )
            {
                // get the width of the NotDef glyph
                SIZE aExtent;
                WCHAR cNotDef = rArgs.mpStr[ nCharPos ];
                mnNotdefWidth = 0;
                if( ::GetTextExtentPoint32W( mhDC, &cNotDef, 1, &aExtent) )
                    mnNotdefWidth = aExtent.cx;
            }
            // use a better NotDef glyph
            if( !mbDisableGlyphs && !bSurrogate )
                mpOutGlyphs[i] = 0;
        }
        if( bSurrogate && ((i+1) < mnGlyphCount) )
            mpOutGlyphs[i+1] = DROPPED_OUTGLYPH;

        // adjust the current glyph width to the NotDef glyph width
        mnWidth += mnNotdefWidth - mpGlyphAdvances[i];
        mpGlyphAdvances[i] = mnNotdefWidth;
        if( mpGlyphOrigAdvs )
            mpGlyphOrigAdvs[i] = mnNotdefWidth;
    }

#ifdef GCP_KERN_HACK
    // apply kerning if the layout engine has not yet done it
    if( rArgs.mnFlags & (SAL_LAYOUT_KERNING_ASIAN|SAL_LAYOUT_KERNING_PAIRS) )
    {
#else // GCP_KERN_HACK
    // apply just asian kerning
    if( rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN )
    {
        if( !(rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) )
#endif // GCP_KERN_HACK
            for( i = 0; i < mnGlyphCount; ++i )
                mpGlyphOrigAdvs[i] = mpGlyphAdvances[i];

        // #99658# also apply asian kerning on the substring border
        int nLen = mnGlyphCount;
        if( rArgs.mnMinCharPos + nLen < rArgs.mnLength )
            ++nLen;
        for( i = 1; i < nLen; ++i )
        {
#ifdef GCP_KERN_HACK
            if( rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS )
            {
                int nKernAmount = mrWinFontEntry.GetKerning( pBidiStr[i-1], pBidiStr[i] );
                mpGlyphAdvances[ i-1 ] += nKernAmount;
                mnWidth += nKernAmount;
            }
            else if( rArgs.mnFlags & SAL_LAYOUT_KERNING_ASIAN )
#endif // GCP_KERN_HACK

            if( ( (0x3000 == (0xFF00 & pBidiStr[i-1])) || (0x2010 == (0xFFF0 & pBidiStr[i-1])) || (0xFF00 == (0xFF00 & pBidiStr[i-1])))
            &&  ( (0x3000 == (0xFF00 & pBidiStr[i])) || (0x2010 == (0xFFF0 & pBidiStr[i])) || (0xFF00 == (0xFF00 & pBidiStr[i])) ) )
            {
                long nKernFirst = +CalcAsianKerning( pBidiStr[i-1], true, bVertical );
                long nKernNext  = -CalcAsianKerning( pBidiStr[i], false, bVertical );

                long nDelta = (nKernFirst < nKernNext) ? nKernFirst : nKernNext;
                if( nDelta<0 && nKernFirst!=0 && nKernNext!=0 )
                {
                    nDelta = (nDelta * mpGlyphAdvances[i-1] + 2) / 4;
                    mpGlyphAdvances[i-1] += nDelta;
                    mnWidth += nDelta;
                }
            }
        }
    }

    // calculate virtual char widths
    if( !mpGlyphs2Chars )
        mpCharWidths = mpGlyphAdvances;
    else
    {
        mpCharWidths = new int[ mnCharCount ];
        for( i = 0; i < mnCharCount; ++i )
            mpCharWidths[ i ] = 0;
        for( i = 0; i < mnGlyphCount; ++i )
        {
            int j = mpGlyphs2Chars[ i ] - rArgs.mnMinCharPos;
            if( j >= 0 )
                mpCharWidths[ j ] += mpGlyphAdvances[ i ];
        }
    }

    // scale layout metrics if needed
	// TODO: does it make the code more simple if the metric scaling
	// is moved to the methods that need metric scaling (e.g. FillDXArray())?
    if( mfFontScale != 1.0 )
    {
        mnWidth   = (long)(mnWidth * mfFontScale);
        mnBaseAdv = (int)(mnBaseAdv * mfFontScale);
        for( i = 0; i < mnCharCount; ++i )
            mpCharWidths[i] = (int)(mpCharWidths[i] * mfFontScale);
        if( mpGlyphAdvances != mpCharWidths )
            for( i = 0; i < mnGlyphCount; ++i )
                mpGlyphAdvances[i] = (int)(mpGlyphAdvances[i] * mfFontScale);
        if( mpGlyphOrigAdvs && (mpGlyphOrigAdvs != mpGlyphAdvances) )
            for( i = 0; i < mnGlyphCount; ++i )
                mpGlyphOrigAdvs[i] = (int)(mpGlyphOrigAdvs[i] * mfFontScale);
    }

    return true;
}

// -----------------------------------------------------------------------

int SimpleWinLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int& nStart,
    long* pGlyphAdvances, int* pCharIndexes ) const
{
    // return zero if no more glyph found
    if( nStart >= mnGlyphCount )
        return 0;

    // calculate glyph position relative to layout base
    // TODO: avoid for nStart!=0 case by reusing rPos
    long nXOffset = mnBaseAdv;
    for( int i = 0; i < nStart; ++i )
        nXOffset += mpGlyphAdvances[ i ];

    // calculate absolute position in pixel units
    Point aRelativePos( nXOffset, 0 );
    rPos = GetDrawPosition( aRelativePos );

    int nCount = 0;
    while( nCount < nLen )
    {
        // update return values {nGlyphIndex,nCharPos,nGlyphAdvance}
        sal_GlyphId nGlyphIndex = mpOutGlyphs[ nStart ];
        if( mbDisableGlyphs )
        {
            if( mnLayoutFlags & SAL_LAYOUT_VERTICAL )
            {
                const sal_UCS4 cChar = static_cast<sal_UCS4>(nGlyphIndex & GF_IDXMASK);
                if( mrWinFontData.HasGSUBstitutions( mhDC )
                &&  mrWinFontData.IsGSUBstituted( cChar ) )
                    nGlyphIndex |= GF_GSUB | GF_ROTL;
                else
                {
                    nGlyphIndex |= GetVerticalFlags( cChar );
                    if( (nGlyphIndex & GF_ROTMASK) == 0 )
                        nGlyphIndex |= GF_VERT;
                }
            }
            nGlyphIndex |= GF_ISCHAR;
        }
        ++nCount;
        *(pGlyphs++) = nGlyphIndex;
        if( pGlyphAdvances )
            *(pGlyphAdvances++) = mpGlyphAdvances[ nStart ];
        if( pCharIndexes )
        {
            int nCharPos;
            if( !mpGlyphs2Chars )
                nCharPos = nStart + mnMinCharPos;
            else
                nCharPos = mpGlyphs2Chars[nStart];
            *(pCharIndexes++) = nCharPos;
        }

        // stop at last glyph
        if( ++nStart >= mnGlyphCount )
            break;

        // stop when next x-position is unexpected
        if( !pGlyphAdvances && mpGlyphOrigAdvs )
            if( mpGlyphAdvances[nStart-1] != mpGlyphOrigAdvs[nStart-1] )
                break;
    }

    return nCount;
}

// -----------------------------------------------------------------------

void SimpleWinLayout::DrawText( SalGraphics& rGraphics ) const
{
    if( mnGlyphCount <= 0 )
        return;

    WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics);
    HDC aHDC = rWinGraphics.getHDC();

    HFONT hOrigFont = DisableFontScaling();

    UINT mnDrawOptions = ETO_GLYPH_INDEX;
    if( mbDisableGlyphs )
        mnDrawOptions = 0;

    Point aPos = GetDrawPosition( Point( mnBaseAdv, 0 ) );

    // #108267#, break up into glyph portions of a limited size required by Win32 API
    const unsigned int maxGlyphCount = 8192;
    UINT numGlyphPortions = mnGlyphCount / maxGlyphCount;
    UINT remainingGlyphs = mnGlyphCount % maxGlyphCount;

    if( numGlyphPortions )
    {
        // #108267#,#109387# break up string into smaller chunks
        // the output positions will be updated by windows (SetTextAlign)
        POINT oldPos;
        UINT oldTa = ::GetTextAlign( aHDC );
        ::SetTextAlign( aHDC, (oldTa & ~TA_NOUPDATECP) | TA_UPDATECP );
        ::MoveToEx( aHDC, aPos.X(), aPos.Y(), &oldPos );
        unsigned int i = 0;
        for( unsigned int n = 0; n < numGlyphPortions; ++n, i+=maxGlyphCount )
            ::ExtTextOutW( aHDC, 0, 0, mnDrawOptions, NULL,
                mpOutGlyphs+i, maxGlyphCount, mpGlyphAdvances+i );
        ::ExtTextOutW( aHDC, 0, 0, mnDrawOptions, NULL,
            mpOutGlyphs+i, remainingGlyphs, mpGlyphAdvances+i );
        ::MoveToEx( aHDC, oldPos.x, oldPos.y, (LPPOINT) NULL);
        ::SetTextAlign( aHDC, oldTa );
    }
    else
        ::ExtTextOutW( aHDC, aPos.X(), aPos.Y(), mnDrawOptions, NULL,
            mpOutGlyphs, mnGlyphCount, mpGlyphAdvances );

    if( hOrigFont )
        DeleteFont( SelectFont( aHDC, hOrigFont ) );
}

// -----------------------------------------------------------------------

long SimpleWinLayout::FillDXArray( long* pDXArray ) const
{
    if( !mnWidth )
    {
        long mnWidth = mnBaseAdv;
        for( int i = 0; i < mnGlyphCount; ++i )
            mnWidth += mpGlyphAdvances[ i ];
    }

    if( pDXArray != NULL )
    {
        for( int i = 0; i < mnCharCount; ++i )
             pDXArray[ i ] = mpCharWidths[ i ];
    }

    return mnWidth;
}

// -----------------------------------------------------------------------

int SimpleWinLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const
// NOTE: the nFactor is used to prevent rounding errors for small nCharExtra values
{
    if( mnWidth )
        if( (mnWidth * nFactor + mnCharCount * nCharExtra) <= nMaxWidth )
            return STRING_LEN;

    long nExtraWidth = mnBaseAdv * nFactor;
    for( int n = 0; n < mnCharCount; ++n )
    {
        // skip unused characters
        if( mpChars2Glyphs && (mpChars2Glyphs[n] < 0) )
            continue;
        // add char widths until max
        nExtraWidth += mpCharWidths[ n ] * nFactor;
        if( nExtraWidth >= nMaxWidth )
            return (mnMinCharPos + n);
        nExtraWidth += nCharExtra;
    }

    return STRING_LEN;
}

// -----------------------------------------------------------------------

void SimpleWinLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const
{
    long nXPos = mnBaseAdv;

    if( !mpGlyphs2Chars )
    {
        for( int i = 0; i < nMaxIdx; i += 2 )
        {
            pCaretXArray[ i ] = nXPos;
            nXPos += mpGlyphAdvances[ i>>1 ];
            pCaretXArray[ i+1 ] = nXPos;
        }
    }
    else
    {
        int  i;
        for( i = 0; i < nMaxIdx; ++i )
            pCaretXArray[ i ] = -1;

        // assign glyph positions to character positions
        for( i = 0; i < mnGlyphCount; ++i )
        {
            int nCurrIdx = mpGlyphs2Chars[ i ] - mnMinCharPos;
            long nXRight = nXPos + mpCharWidths[ nCurrIdx ];
            nCurrIdx *= 2;
            if( !(mpGlyphRTLFlags && mpGlyphRTLFlags[i]) )
            {
                // normal positions for LTR case
                pCaretXArray[ nCurrIdx ]   = nXPos;
                pCaretXArray[ nCurrIdx+1 ] = nXRight;
            }
            else
            {
                // reverse positions for RTL case
                pCaretXArray[ nCurrIdx ]   = nXRight;
                pCaretXArray[ nCurrIdx+1 ] = nXPos;
            }
            nXPos += mpGlyphAdvances[ i ];
        }
    }
}

// -----------------------------------------------------------------------

void SimpleWinLayout::Justify( long nNewWidth )
{
    long nOldWidth = mnWidth;
    mnWidth = nNewWidth;

    if( mnGlyphCount <= 0 )
        return;

    if( nNewWidth == nOldWidth )
        return;

    // the rightmost glyph cannot be stretched
    const int nRight = mnGlyphCount - 1;
    nOldWidth -= mpGlyphAdvances[ nRight ];
    nNewWidth -= mpGlyphAdvances[ nRight ];

    // count stretchable glyphs
    int nStretchable = 0, i;
    for( i = 0; i < nRight; ++i )
        if( mpGlyphAdvances[i] >= 0 )
            ++nStretchable;

    // stretch these glyphs
    int nDiffWidth = nNewWidth - nOldWidth;
    for( i = 0; (i < nRight) && (nStretchable > 0); ++i )
    {
        if( mpGlyphAdvances[i] <= 0 )
            continue;
        int nDeltaWidth = nDiffWidth / nStretchable;
        mpGlyphAdvances[i] += nDeltaWidth;
        --nStretchable;
        nDiffWidth -= nDeltaWidth;
    }
}

// -----------------------------------------------------------------------

void SimpleWinLayout::AdjustLayout( ImplLayoutArgs& rArgs )
{
    SalLayout::AdjustLayout( rArgs );

    // adjust positions if requested
    if( rArgs.mpDXArray )
        ApplyDXArray( rArgs );
    else if( rArgs.mnLayoutWidth )
        Justify( rArgs.mnLayoutWidth );
    else
        return;

    // recalculate virtual char widths if they were changed
    if( mpCharWidths != mpGlyphAdvances )
    {
        int i;
        if( !mpGlyphs2Chars )
        {
            // standard LTR case
            for( i = 0; i < mnGlyphCount; ++i )
                 mpCharWidths[ i ] = mpGlyphAdvances[ i ];
        }
        else
        {
            // BiDi or complex case
            for( i = 0; i < mnCharCount; ++i )
                mpCharWidths[ i ] = 0;
            for( i = 0; i < mnGlyphCount; ++i )
            {
                int j = mpGlyphs2Chars[ i ] - rArgs.mnMinCharPos;
                if( j >= 0 )
                    mpCharWidths[ j ] += mpGlyphAdvances[ i ];
            }
        }
    }
}

// -----------------------------------------------------------------------

void SimpleWinLayout::ApplyDXArray( const ImplLayoutArgs& rArgs )
{
    // try to avoid disturbance of text flow for LSB rounding case;
    const long* pDXArray = rArgs.mpDXArray;

    int i = 0;
    long nOldWidth = mnBaseAdv;
    for(; i < mnCharCount; ++i )
    {
        int j = !mpChars2Glyphs ? i : mpChars2Glyphs[i];
        if( j >= 0 )
        {
            nOldWidth += mpGlyphAdvances[ j ];
            int nDiff = nOldWidth - pDXArray[ i ];

            // disabled because of #104768#
            // works great for static text, but problems when typing
            // if( nDiff>+1 || nDiff<-1 )
            // only bother with changing anything when something moved
            if( nDiff != 0 )
                break;
        }
    }
    if( i >= mnCharCount )
        return;

    if( !mpGlyphOrigAdvs )
    {
        mpGlyphOrigAdvs = new int[ mnGlyphCount ];
        for( i = 0; i < mnGlyphCount; ++i )
            mpGlyphOrigAdvs[ i ] = mpGlyphAdvances[ i ];
    }

    mnWidth = mnBaseAdv;
    for( i = 0; i < mnCharCount; ++i )
    {
        int j = !mpChars2Glyphs ? i : mpChars2Glyphs[i];
        if( j >= 0 )
            mpGlyphAdvances[j] = pDXArray[i] - mnWidth;
        mnWidth = pDXArray[i];
    }
}

// -----------------------------------------------------------------------

void SimpleWinLayout::MoveGlyph( int nStart, long nNewXPos )
{
   if( nStart > mnGlyphCount )
        return;

    // calculate the current x-position of the requested glyph
    // TODO: cache absolute positions
    int nXPos = mnBaseAdv;
    for( int i = 0; i < nStart; ++i )
        nXPos += mpGlyphAdvances[i];

    // calculate the difference to the current glyph position
    int nDelta = nNewXPos - nXPos;

    // adjust the width of the layout if it was already cached
    if( mnWidth )
        mnWidth += nDelta;

    // depending on whether the requested glyph is leftmost in the layout
    // adjust either the layout's or the requested glyph's relative position
    if( nStart > 0 )
        mpGlyphAdvances[ nStart-1 ] += nDelta;
    else
        mnBaseAdv += nDelta;
}

// -----------------------------------------------------------------------

void SimpleWinLayout::DropGlyph( int nStart )
{
    mpOutGlyphs[ nStart ] = DROPPED_OUTGLYPH;
}

// -----------------------------------------------------------------------

void SimpleWinLayout::Simplify( bool /*bIsBase*/ )
{
    // return early if no glyph has been dropped
    int i = mnGlyphCount;
    while( (--i >= 0) && (mpOutGlyphs[ i ] != DROPPED_OUTGLYPH) );
    if( i < 0 )
        return;

    // convert the layout to a sparse layout if it is not already
    if( !mpGlyphs2Chars )
    {
        mpGlyphs2Chars = new int[ mnGlyphCount ];
        mpCharWidths = new int[ mnCharCount ];
        // assertion: mnGlyphCount == mnCharCount
        for( int k = 0; k < mnGlyphCount; ++k )
        {
            mpGlyphs2Chars[ k ] = mnMinCharPos + k;
            mpCharWidths[ k ] = mpGlyphAdvances[ k ];
        }
    }

    // remove dropped glyphs that are rightmost in the layout
    for( i = mnGlyphCount; --i >= 0; )
    {
        if( mpOutGlyphs[ i ] != DROPPED_OUTGLYPH )
            break;
        if( mnWidth )
            mnWidth -= mpGlyphAdvances[ i ];
        int nRelCharPos = mpGlyphs2Chars[ i ] - mnMinCharPos;
        if( nRelCharPos >= 0 )
            mpCharWidths[ nRelCharPos ] = 0;
    }
    mnGlyphCount = i + 1;

    // keep original glyph widths around
    if( !mpGlyphOrigAdvs )
    {
        mpGlyphOrigAdvs = new int[ mnGlyphCount ];
        for( int k = 0; k < mnGlyphCount; ++k )
            mpGlyphOrigAdvs[ k ] = mpGlyphAdvances[ k ];
    }

    // remove dropped glyphs inside the layout
    int nNewGC = 0;
    for( i = 0; i < mnGlyphCount; ++i )
    {
        if( mpOutGlyphs[ i ] == DROPPED_OUTGLYPH )
        {
            // adjust relative position to last valid glyph
            int nDroppedWidth = mpGlyphAdvances[ i ];
            mpGlyphAdvances[ i ] = 0;
            if( nNewGC > 0 )
                mpGlyphAdvances[ nNewGC-1 ] += nDroppedWidth;
            else
                mnBaseAdv += nDroppedWidth;

            // zero the virtual char width for the char that has a fallback
            int nRelCharPos = mpGlyphs2Chars[ i ] - mnMinCharPos;
            if( nRelCharPos >= 0 )
                mpCharWidths[ nRelCharPos ] = 0;
        }
        else
        {
            if( nNewGC != i )
            {
                // rearrange the glyph array to get rid of the dropped glyph
                mpOutGlyphs[ nNewGC ]     = mpOutGlyphs[ i ];
                mpGlyphAdvances[ nNewGC ] = mpGlyphAdvances[ i ];
                mpGlyphOrigAdvs[ nNewGC ] = mpGlyphOrigAdvs[ i ];
                mpGlyphs2Chars[ nNewGC ]  = mpGlyphs2Chars[ i ];
            }
            ++nNewGC;
        }
    }

    mnGlyphCount = nNewGC;
    if( mnGlyphCount <= 0 )
        mnWidth = mnBaseAdv = 0;
}

// =======================================================================

#ifdef USE_UNISCRIBE

struct VisualItem
{
public:
    SCRIPT_ITEM*    mpScriptItem;
    int             mnMinGlyphPos;
    int             mnEndGlyphPos;
    int             mnMinCharPos;
    int             mnEndCharPos;
    //long          mnPixelWidth;
    int             mnXOffset;
    ABC             maABCWidths;
    bool            mbHasKashidas;

public:
    bool            IsEmpty() const { return (mnEndGlyphPos <= 0); }
    bool            IsRTL() const { return mpScriptItem->a.fRTL; }
    bool            HasKashidas() const { return mbHasKashidas; }
};

// -----------------------------------------------------------------------

class UniscribeLayout : public WinLayout
{
public:
                    UniscribeLayout( HDC, const ImplWinFontData&, ImplWinFontEntry& );

    virtual bool    LayoutText( ImplLayoutArgs& );
    virtual void    AdjustLayout( ImplLayoutArgs& );
    virtual void    DrawText( SalGraphics& ) const;
    virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
                        sal_Int32* pGlyphAdvances, int* pCharPosAry ) const;

    virtual long    FillDXArray( long* pDXArray ) const;
    virtual int     GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const;
    virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const;
    virtual bool    IsKashidaPosValid ( int nCharPos ) const;

    // for glyph+font+script fallback
    virtual void    MoveGlyph( int nStart, long nNewXPos );
    virtual void    DropGlyph( int nStart );
    virtual void    Simplify( bool bIsBase );
    virtual void    DisableGlyphInjection( bool bDisable ) { mbDisableGlyphInjection = bDisable; }

protected:
    virtual         ~UniscribeLayout();

    void            Justify( long nNewWidth );
    void            ApplyDXArray( const ImplLayoutArgs& );

    bool            GetItemSubrange( const VisualItem&,
                        int& rMinIndex, int& rEndIndex ) const;

private:
    // item specific info
    SCRIPT_ITEM*    mpScriptItems;      // in logical order
    VisualItem*     mpVisualItems;      // in visual order
    int             mnItemCount;        // number of visual items

    // string specific info
    // everything is in logical order
    int             mnCharCapacity;
    WORD*           mpLogClusters;      // map from absolute_char_pos to relative_glyph_pos
    int*            mpCharWidths;       // map from absolute_char_pos to char_width
    int             mnSubStringMin;     // char_pos of first char in context

    // glyph specific info
    // everything is in visual order
    int             mnGlyphCount;
    int             mnGlyphCapacity;
    int*            mpGlyphAdvances;    // glyph advance width before justification
    int*            mpJustifications;   // glyph advance width after justification
    WORD*           mpOutGlyphs;        // glyphids in visual order
    GOFFSET*        mpGlyphOffsets;     // glyph offsets to the "naive" layout
    SCRIPT_VISATTR* mpVisualAttrs;      // glyph visual attributes
    mutable int*    mpGlyphs2Chars;     // map from absolute_glyph_pos to absolute_char_pos

    // kashida stuff
    void InitKashidaHandling();
    void KashidaItemFix( int nMinGlyphPos, int nEndGlyphPos );
    bool KashidaWordFix( int nMinGlyphPos, int nEndGlyphPos, int* pnCurrentPos );

    int            mnMinKashidaWidth;
    int            mnMinKashidaGlyph;
    bool           mbDisableGlyphInjection;
};

// -----------------------------------------------------------------------
// dynamic loading of usp library

static oslModule aUspModule = NULL;
static bool bUspEnabled = true;

static HRESULT ((WINAPI *pScriptIsComplex)( const WCHAR*, int, DWORD ));
static HRESULT ((WINAPI *pScriptItemize)( const WCHAR*, int, int,
    const SCRIPT_CONTROL*, const SCRIPT_STATE*, SCRIPT_ITEM*, int* ));
static HRESULT ((WINAPI *pScriptShape)( HDC, SCRIPT_CACHE*, const WCHAR*,
    int, int, SCRIPT_ANALYSIS*, WORD*, WORD*, SCRIPT_VISATTR*, int* ));
static HRESULT ((WINAPI *pScriptPlace)( HDC, SCRIPT_CACHE*, const WORD*, int,
    const SCRIPT_VISATTR*, SCRIPT_ANALYSIS*, int*, GOFFSET*, ABC* ));
static HRESULT ((WINAPI *pScriptGetLogicalWidths)( const SCRIPT_ANALYSIS*,
    int, int, const int*, const WORD*, const SCRIPT_VISATTR*, int* ));
static HRESULT ((WINAPI *pScriptApplyLogicalWidth)( const int*, int, int, const WORD*,
    const SCRIPT_VISATTR*, const int*, const SCRIPT_ANALYSIS*, ABC*, int* ));
static HRESULT ((WINAPI *pScriptJustify)( const SCRIPT_VISATTR*,
    const int*, int, int, int, int* ));
static HRESULT ((WINAPI *pScriptTextOut)( const HDC, SCRIPT_CACHE*,
    int, int, UINT, const RECT*, const SCRIPT_ANALYSIS*, const WCHAR*,
    int, const WORD*, int, const int*, const int*, const GOFFSET* ));
static HRESULT ((WINAPI *pScriptGetFontProperties)( HDC, SCRIPT_CACHE*, SCRIPT_FONTPROPERTIES* ));
static HRESULT ((WINAPI *pScriptFreeCache)( SCRIPT_CACHE* ));

static bool bManualCellAlign = true;

// -----------------------------------------------------------------------

static bool InitUSP()
{
    aUspModule = osl_loadAsciiModule( "usp10", SAL_LOADMODULE_DEFAULT );
    if( !aUspModule )
        return (bUspEnabled = false);

    pScriptIsComplex = (HRESULT (WINAPI*)(const WCHAR*,int,DWORD))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptIsComplex" );
    bUspEnabled &= (NULL != pScriptIsComplex);

    pScriptItemize = (HRESULT (WINAPI*)(const WCHAR*,int,int,
        const SCRIPT_CONTROL*,const SCRIPT_STATE*,SCRIPT_ITEM*,int*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptItemize" );
    bUspEnabled &= (NULL != pScriptItemize);

    pScriptShape = (HRESULT (WINAPI*)(HDC,SCRIPT_CACHE*,const WCHAR*,
        int,int,SCRIPT_ANALYSIS*,WORD*,WORD*,SCRIPT_VISATTR*,int*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptShape" );
    bUspEnabled &= (NULL != pScriptShape);

    pScriptPlace = (HRESULT (WINAPI*)(HDC, SCRIPT_CACHE*, const WORD*, int,
        const SCRIPT_VISATTR*,SCRIPT_ANALYSIS*,int*,GOFFSET*,ABC*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptPlace" );
    bUspEnabled &= (NULL != pScriptPlace);

    pScriptGetLogicalWidths = (HRESULT (WINAPI*)(const SCRIPT_ANALYSIS*,
        int,int,const int*,const WORD*,const SCRIPT_VISATTR*,int*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptGetLogicalWidths" );
    bUspEnabled &= (NULL != pScriptGetLogicalWidths);

    pScriptApplyLogicalWidth = (HRESULT (WINAPI*)(const int*,int,int,const WORD*,
        const SCRIPT_VISATTR*,const int*,const SCRIPT_ANALYSIS*,ABC*,int*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptApplyLogicalWidth" );
    bUspEnabled &= (NULL != pScriptApplyLogicalWidth);

    pScriptJustify = (HRESULT (WINAPI*)(const SCRIPT_VISATTR*,const int*,
        int,int,int,int*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptJustify" );
    bUspEnabled &= (NULL != pScriptJustify);

    pScriptGetFontProperties = (HRESULT (WINAPI*)( HDC,SCRIPT_CACHE*,SCRIPT_FONTPROPERTIES*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptGetFontProperties" );
    bUspEnabled &= (NULL != pScriptGetFontProperties);

    pScriptTextOut = (HRESULT (WINAPI*)(const HDC,SCRIPT_CACHE*,
        int,int,UINT,const RECT*,const SCRIPT_ANALYSIS*,const WCHAR*,
        int,const WORD*,int,const int*,const int*,const GOFFSET*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptTextOut" );
    bUspEnabled &= (NULL != pScriptTextOut);

    pScriptFreeCache = (HRESULT (WINAPI*)(SCRIPT_CACHE*))
        osl_getAsciiFunctionSymbol( aUspModule, "ScriptFreeCache" );
    bUspEnabled &= (NULL != pScriptFreeCache);

    if( !bUspEnabled )
    {
        osl_unloadModule( aUspModule );
        aUspModule = NULL;
    }

	// get the DLL version info
	int nUspVersion = 0;
	// TODO: there must be a simpler way to get the friggin version info from OSL?
	rtl_uString* pModuleURL = NULL;
	osl_getModuleURLFromAddress( (void*)pScriptIsComplex, &pModuleURL );
	rtl_uString* pModuleFileName = NULL;
	if( pModuleURL )
		osl_getSystemPathFromFileURL( pModuleURL, &pModuleFileName );
	const sal_Unicode* pModuleFileCStr = NULL;
	if( pModuleFileName )
		pModuleFileCStr = rtl_uString_getStr( pModuleFileName );
	if( pModuleFileCStr )
	{
		DWORD nHandle;
		DWORD nBufSize = ::GetFileVersionInfoSizeW( const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(pModuleFileCStr)), &nHandle );
		char* pBuffer = (char*)alloca( nBufSize );
		BOOL bRC = ::GetFileVersionInfoW( const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(pModuleFileCStr)), nHandle, nBufSize, pBuffer );
		VS_FIXEDFILEINFO* pFixedFileInfo = NULL;
		UINT nFixedFileSize = 0;
		if( bRC )
			::VerQueryValueW( pBuffer, const_cast<LPWSTR>(L"\\"), (void**)&pFixedFileInfo, &nFixedFileSize );
		if( pFixedFileInfo && pFixedFileInfo->dwSignature == 0xFEEF04BD )
			nUspVersion = HIWORD(pFixedFileInfo->dwProductVersionMS) * 10000
						+ LOWORD(pFixedFileInfo->dwProductVersionMS);
	}

	// #i77976# USP>=1.0600 changed the need to manually align glyphs in their cells
	if( nUspVersion >= 10600 )
		bManualCellAlign = false;

    return bUspEnabled;
}

// -----------------------------------------------------------------------

UniscribeLayout::UniscribeLayout( HDC hDC,
    const ImplWinFontData& rWinFontData, ImplWinFontEntry& rWinFontEntry )
:   WinLayout( hDC, rWinFontData, rWinFontEntry ),
    mnItemCount( 0 ),
    mpScriptItems( NULL ),
    mpVisualItems( NULL ),
    mpLogClusters( NULL ),
    mpCharWidths( NULL ),
    mnCharCapacity( 0 ),
    mnSubStringMin( 0 ),
    mnGlyphCapacity( 0 ),
    mnGlyphCount( 0 ),
    mpOutGlyphs( NULL ),
    mpGlyphAdvances( NULL ),
    mpJustifications( NULL ),
    mpGlyphOffsets( NULL ),
    mpVisualAttrs( NULL ),
    mpGlyphs2Chars( NULL ),
    mnMinKashidaGlyph( 0 ),
    mbDisableGlyphInjection( false )
{}

// -----------------------------------------------------------------------

UniscribeLayout::~UniscribeLayout()
{
    delete[] mpScriptItems;
    delete[] mpVisualItems;
    delete[] mpLogClusters;
    delete[] mpCharWidths;
    delete[] mpOutGlyphs;
    delete[] mpGlyphAdvances;
    delete[] mpJustifications;
    delete[] mpGlyphOffsets;
    delete[] mpVisualAttrs;
    delete[] mpGlyphs2Chars;
}

// -----------------------------------------------------------------------

bool UniscribeLayout::LayoutText( ImplLayoutArgs& rArgs )
{
    // for a base layout only the context glyphs have to be dropped
    // => when the whole string is involved there is no extra context
    typedef std::vector<int> TIntVector;
    TIntVector aDropChars;
    if( rArgs.mnFlags & SAL_LAYOUT_FOR_FALLBACK )
    {
        // calculate superfluous context char positions
        aDropChars.push_back( 0 );
        aDropChars.push_back( rArgs.mnLength );
        int nMin, nEnd;
        bool bRTL;
        for( rArgs.ResetPos(); rArgs.GetNextRun( &nMin, &nEnd, &bRTL ); )
        {
            aDropChars.push_back( nMin );
            aDropChars.push_back( nEnd );
        }
        // prepare aDropChars for binary search which will allow to
        // not bother with visual items that will be dropped anyway
        std::sort( aDropChars.begin(), aDropChars.end() );
    }

    // prepare layout
    // TODO: fix case when recyclying old UniscribeLayout object
    mnMinCharPos = rArgs.mnMinCharPos;
    mnEndCharPos = rArgs.mnEndCharPos;

    // determine script items from string

    // prepare itemization
    // TODO: try to avoid itemization since it costs a lot of performance
    SCRIPT_STATE aScriptState = {0,false,false,false,false,false,false,false,false,0,0};
    aScriptState.uBidiLevel         = (0 != (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL));
    aScriptState.fOverrideDirection = (0 != (rArgs.mnFlags & SAL_LAYOUT_BIDI_STRONG));
    aScriptState.fDigitSubstitute   = (0 != (rArgs.mnFlags & SAL_LAYOUT_SUBSTITUTE_DIGITS));
    aScriptState.fArabicNumContext  = aScriptState.fDigitSubstitute & aScriptState.uBidiLevel;
    DWORD nLangId = 0;  // TODO: get language from font
    SCRIPT_CONTROL aScriptControl = {nLangId,false,false,false,false,false,false,false,false,0};
    aScriptControl.fNeutralOverride = aScriptState.fOverrideDirection;
    aScriptControl.fContextDigits   = (0 != (rArgs.mnFlags & SAL_LAYOUT_SUBSTITUTE_DIGITS));
    aScriptControl.fMergeNeutralItems = true;
    // determine relevant substring and work only on it
    // when Bidi status is unknown we need to look at the whole string though
    mnSubStringMin = 0;
    int nSubStringEnd = rArgs.mnLength;
    if( aScriptState.fOverrideDirection )
    {
        // TODO: limit substring to portion limits
        mnSubStringMin = rArgs.mnMinCharPos - 8;
        if( mnSubStringMin < 0 )
            mnSubStringMin = 0;
        nSubStringEnd = rArgs.mnEndCharPos + 8;
        if( nSubStringEnd > rArgs.mnLength )
            nSubStringEnd = rArgs.mnLength;

    }

    // now itemize the substring with its context
    for( int nItemCapacity = 16;; nItemCapacity *= 8 )
    {
        mpScriptItems = new SCRIPT_ITEM[ nItemCapacity ];
        HRESULT nRC = (*pScriptItemize)(
            reinterpret_cast<LPCWSTR>(rArgs.mpStr + mnSubStringMin), nSubStringEnd - mnSubStringMin,
            nItemCapacity - 1, &aScriptControl, &aScriptState,
            mpScriptItems, &mnItemCount );
        if( !nRC )  // break loop when everything is correctly itemized
            break;

        // prepare bigger buffers for another itemization round
        delete[] mpScriptItems;
        mpScriptItems = NULL;
        if( nRC != E_OUTOFMEMORY )
            return false;
        if( nItemCapacity > (nSubStringEnd - mnSubStringMin) + 16 )
            return false;
    }

    // calculate the order of visual items
    int nItem, i;

    // adjust char positions by substring offset
    for( nItem = 0; nItem <= mnItemCount; ++nItem )
        mpScriptItems[ nItem ].iCharPos += mnSubStringMin;
    // default visual item ordering
    mpVisualItems = new VisualItem[ mnItemCount ];
    for( nItem = 0; nItem < mnItemCount; ++nItem )
    {
        // initialize char specific item info
        VisualItem& rVisualItem = mpVisualItems[ nItem ];
        SCRIPT_ITEM* pScriptItem = &mpScriptItems[ nItem ];
        rVisualItem.mpScriptItem = pScriptItem;
        rVisualItem.mnMinCharPos = pScriptItem[0].iCharPos;
        rVisualItem.mnEndCharPos = pScriptItem[1].iCharPos;
    }

    // reorder visual item order if needed
    if( rArgs.mnFlags & SAL_LAYOUT_BIDI_STRONG )
    {
        // force RTL item ordering if requested
        if( rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL )
        {
            VisualItem* pVI0 = &mpVisualItems[ 0 ];
            VisualItem* pVI1 = &mpVisualItems[ mnItemCount ];
            while( pVI0 < --pVI1 )
            {
                VisualItem aVtmp = *pVI0;
                *(pVI0++) = *pVI1;
                *pVI1 = aVtmp;
            }
        }
    }
    else if( mnItemCount > 1 )
    {
        // apply bidi algorithm's rule L2 on item level
        // TODO: use faster L2 algorithm
        int nMaxBidiLevel = 0;
        VisualItem* pVI = &mpVisualItems[0];
        VisualItem* const pVIend = pVI + mnItemCount;
        for(; pVI < pVIend; ++pVI )
            if( nMaxBidiLevel < pVI->mpScriptItem->a.s.uBidiLevel )
                nMaxBidiLevel = pVI->mpScriptItem->a.s.uBidiLevel;

        while( --nMaxBidiLevel >= 0 )
        {
            for( pVI = &mpVisualItems[0]; pVI < pVIend; )
            {
                // find item range that needs reordering
                for(; pVI < pVIend; ++pVI )
                    if( nMaxBidiLevel < pVI->mpScriptItem->a.s.uBidiLevel )
                        break;
                VisualItem* pVImin = pVI++;
                for(; pVI < pVIend; ++pVI )
                    if( nMaxBidiLevel >= pVI->mpScriptItem->a.s.uBidiLevel )
                        break;
                VisualItem* pVImax = pVI++;

                // reverse order of items in this range
                while( pVImin < --pVImax )
                {
                    VisualItem aVtmp = *pVImin;
                    *(pVImin++) = *pVImax;
                    *pVImax = aVtmp;
                }
            }
        }
    }

    // allocate arrays
    // TODO: when reusing object reuse old allocations or delete them
    // TODO: use only [nSubStringMin..nSubStringEnd) instead of [0..nSubStringEnd)
    mnCharCapacity  = nSubStringEnd;
    mpLogClusters   = new WORD[ mnCharCapacity ];
    mpCharWidths    = new int[ mnCharCapacity ];

    mnGlyphCount    = 0;
    mnGlyphCapacity = 16 + 4 * (nSubStringEnd - mnSubStringMin); // worst case assumption
    mpGlyphAdvances = new int[ mnGlyphCapacity ];
    mpOutGlyphs     = new WORD[ mnGlyphCapacity ];
    mpGlyphOffsets  = new GOFFSET[ mnGlyphCapacity ];
    mpVisualAttrs   = new SCRIPT_VISATTR[ mnGlyphCapacity ];

    long nXOffset = 0;
    for( int j = mnSubStringMin; j < nSubStringEnd; ++j )
        mpCharWidths[j] = 0;

    // layout script items
    SCRIPT_CACHE& rScriptCache = GetScriptCache();
    for( nItem = 0; nItem < mnItemCount; ++nItem )
    {
        VisualItem& rVisualItem = mpVisualItems[ nItem ];

        // initialize glyph specific item info
        rVisualItem.mnMinGlyphPos = mnGlyphCount;
        rVisualItem.mnEndGlyphPos = 0;
        rVisualItem.mnXOffset     = nXOffset;
        //rVisualItem.mnPixelWidth  = 0;

        // shortcut ignorable items
        if( (rArgs.mnEndCharPos <= rVisualItem.mnMinCharPos)
         || (rArgs.mnMinCharPos >= rVisualItem.mnEndCharPos) )
        {
            for( int i = rVisualItem.mnMinCharPos; i < rVisualItem.mnEndCharPos; ++i )
                mpLogClusters[i] = sal::static_int_cast<WORD>(~0U);
            continue;
        }

        // override bidi analysis if requested
        if( rArgs.mnFlags & SAL_LAYOUT_BIDI_STRONG )
        {
            // FIXME: is this intended ?
            rVisualItem.mpScriptItem->a.fRTL                 = (aScriptState.uBidiLevel & 1);
            rVisualItem.mpScriptItem->a.s.uBidiLevel         = aScriptState.uBidiLevel;
            rVisualItem.mpScriptItem->a.s.fOverrideDirection = aScriptState.fOverrideDirection;
        }

        // convert the unicodes to glyphs
        int nGlyphCount = 0;
        int nCharCount = rVisualItem.mnEndCharPos - rVisualItem.mnMinCharPos;
        HRESULT nRC = (*pScriptShape)( mhDC, &rScriptCache,
            reinterpret_cast<LPCWSTR>(rArgs.mpStr + rVisualItem.mnMinCharPos),
            nCharCount,
            mnGlyphCapacity - rVisualItem.mnMinGlyphPos, // problem when >0xFFFF
            &rVisualItem.mpScriptItem->a,
            mpOutGlyphs + rVisualItem.mnMinGlyphPos,
            mpLogClusters + rVisualItem.mnMinCharPos,
            mpVisualAttrs + rVisualItem.mnMinGlyphPos,
            &nGlyphCount );

        // find and handle problems in the unicode to glyph conversion
        if( nRC == USP_E_SCRIPT_NOT_IN_FONT )
        {
            // the whole visual item needs a fallback, but make sure that the next
            // fallback request is limited to the characters in the original request
            // => this is handled in ImplLayoutArgs::PrepareFallback()
            rArgs.NeedFallback( rVisualItem.mnMinCharPos, rVisualItem.mnEndCharPos,
                rVisualItem.IsRTL() );

            // don't bother to do a default layout in a fallback level
            if( 0 != (rArgs.mnFlags & SAL_LAYOUT_FOR_FALLBACK) )
                continue;

            // the primitive layout engine is good enough for the default layout
            rVisualItem.mpScriptItem->a.eScript = SCRIPT_UNDEFINED;
            nRC = (*pScriptShape)( mhDC, &rScriptCache,
                reinterpret_cast<LPCWSTR>(rArgs.mpStr + rVisualItem.mnMinCharPos),
                nCharCount,
                mnGlyphCapacity - rVisualItem.mnMinGlyphPos,
                &rVisualItem.mpScriptItem->a,
                mpOutGlyphs + rVisualItem.mnMinGlyphPos,
                mpLogClusters + rVisualItem.mnMinCharPos,
                mpVisualAttrs + rVisualItem.mnMinGlyphPos,
                &nGlyphCount );

            if( nRC != 0 )
                continue;

#if 0       // keep the glyphs for now because they are better than nothing
            // mark as NotDef glyphs
            for( i = 0; i < nGlyphCount; ++i )
                mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] = 0;
#endif
        }
        else if( nRC != 0 )
            // something undefined happened => give up for this visual item
            continue;
        else // if( nRC == 0 )
        {
            // check if there are any NotDef glyphs
            for( i = 0; i < nGlyphCount; ++i )
                if( 0 == mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] )
                    break;
            if( i < nGlyphCount )
            {
                // clip charpos limits to the layout string without context
                int nMinCharPos = rVisualItem.mnMinCharPos;
                if( nMinCharPos < rArgs.mnMinCharPos )
                    nMinCharPos = rArgs.mnMinCharPos;
                int nEndCharPos = rVisualItem.mnEndCharPos;
                if( nEndCharPos > rArgs.mnEndCharPos )
                    nEndCharPos = rArgs.mnEndCharPos;
                // request fallback for individual NotDef glyphs
                do
                {
                    // ignore non-NotDef glyphs
                    if( 0 != mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] )
                        continue;
                    mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] = DROPPED_OUTGLYPH;
                    // request fallback for the whole cell that resulted in a NotDef glyph
                    // TODO: optimize algorithm
                    const bool bRTL = rVisualItem.IsRTL();
                    if( !bRTL )
                    {
                        // request fallback for the left-to-right cell
                        for( int c = nMinCharPos; c < nEndCharPos; ++c )
                        {
                            if( mpLogClusters[ c ] == i )
                            {
                                // #i55716# skip WORDJOINER
                                if( rArgs.mpStr[ c ] == 0x2060 )
                                    mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] = 1;
                                else
                                    rArgs.NeedFallback( c, false );
                           }
                        }
                    }
                    else
                    {
                        // request fallback for the right to left cell
                        for( int c = nEndCharPos; --c >= nMinCharPos; )
                        {
                            if( mpLogClusters[ c ] == i )
                            {
                                // #i55716# skip WORDJOINER
                                if( rArgs.mpStr[ c ] == 0x2060 )
                                    mpOutGlyphs[ i + rVisualItem.mnMinGlyphPos ] = 1;
                                else
                                    rArgs.NeedFallback( c, true );
                            }
                        }
                    }
                } while( ++i < nGlyphCount );
            }
        }

        // now place the glyphs
        nRC = (*pScriptPlace)( mhDC, &rScriptCache,
            mpOutGlyphs + rVisualItem.mnMinGlyphPos,
            nGlyphCount,
            mpVisualAttrs + rVisualItem.mnMinGlyphPos,
            &rVisualItem.mpScriptItem->a,
            mpGlyphAdvances + rVisualItem.mnMinGlyphPos,
            mpGlyphOffsets + rVisualItem.mnMinGlyphPos,
            &rVisualItem.maABCWidths );

        if( nRC != 0 )
            continue;

        // calculate the logical char widths from the glyph layout
        nRC = (*pScriptGetLogicalWidths)(
            &rVisualItem.mpScriptItem->a,
            nCharCount, nGlyphCount,
            mpGlyphAdvances + rVisualItem.mnMinGlyphPos,
            mpLogClusters + rVisualItem.mnMinCharPos,
            mpVisualAttrs + rVisualItem.mnMinGlyphPos,
            mpCharWidths + rVisualItem.mnMinCharPos );

        // update the glyph counters
        mnGlyphCount += nGlyphCount;
        rVisualItem.mnEndGlyphPos = mnGlyphCount;

        // update nXOffset
        int nEndGlyphPos;
        if( GetItemSubrange( rVisualItem, i, nEndGlyphPos ) )
            for(; i < nEndGlyphPos; ++i )
                nXOffset += mpGlyphAdvances[ i ];

        // TODO: shrink glyphpos limits to match charpos/fallback limits
        //pVI->mnMinGlyphPos = nMinGlyphPos;
        //pVI->mnEndGlyphPos = nEndGlyphPos;

        // drop the superfluous context glyphs
        TIntVector::const_iterator it = aDropChars.begin();
        while( it != aDropChars.end() )
        {
            // find matching "drop range"
            int nMinDropPos = *(it++); // begin of drop range
            if( nMinDropPos >= rVisualItem.mnEndCharPos )
                break;
            int nEndDropPos = *(it++); // end of drop range
            if( nEndDropPos <= rVisualItem.mnMinCharPos )
                continue;
            // clip "drop range" to visual item's char range
            if( nMinDropPos <= rVisualItem.mnMinCharPos )
            {
                nMinDropPos = rVisualItem.mnMinCharPos;
                // drop the whole visual item if possible
                if( nEndDropPos >= rVisualItem.mnEndCharPos )
                {
                    rVisualItem.mnEndGlyphPos = 0;
                    break;
                }
            }
            if( nEndDropPos > rVisualItem.mnEndCharPos )
                nEndDropPos = rVisualItem.mnEndCharPos;

            // drop the glyphs which correspond to the charpos range
            // drop the corresponding glyphs in the cluster
            for( int c = nMinDropPos; c < nEndDropPos; ++c )
            {
                int nGlyphPos = mpLogClusters[c] + rVisualItem.mnMinGlyphPos;
                // no need to bother when the cluster was already dropped
                if( mpOutGlyphs[ nGlyphPos ] != DROPPED_OUTGLYPH )
                {
                    for(;;)
                    {
                        mpOutGlyphs[ nGlyphPos ] = DROPPED_OUTGLYPH;
                        // until the end of visual item
                        if( ++nGlyphPos >= rVisualItem.mnEndGlyphPos )
                            break;
                        // until the next cluster start
                        if( mpVisualAttrs[ nGlyphPos ].fClusterStart )
                            break;
                    }
                }
            }
        }
    }

    // scale layout metrics if needed
	// TODO: does it make the code more simple if the metric scaling
	// is moved to the methods that need metric scaling (e.g. FillDXArray())?
    if( mfFontScale != 1.0 )
    {
        mnBaseAdv = (int)((double)mnBaseAdv*mfFontScale);

        for( i = 0; i < mnItemCount; ++i )
            mpVisualItems[i].mnXOffset = (int)((double)mpVisualItems[i].mnXOffset*mfFontScale);

        mnBaseAdv = (int)((double)mnBaseAdv*mfFontScale);
        for( i = 0; i < mnGlyphCount; ++i )
        {
            mpGlyphAdvances[i]   = (int)(mpGlyphAdvances[i] * mfFontScale);
            mpGlyphOffsets[i].du = (LONG)(mpGlyphOffsets[i].du * mfFontScale);
            mpGlyphOffsets[i].dv = (LONG)(mpGlyphOffsets[i].dv * mfFontScale);
            // mpJustifications are still NULL
        }

        for( i = mnSubStringMin; i < nSubStringEnd; ++i )
            mpCharWidths[i] = (int)(mpCharWidths[i] * mfFontScale);
    }

    return true;
}

// -----------------------------------------------------------------------

// calculate the range of relevant glyphs for this visual item
bool UniscribeLayout::GetItemSubrange( const VisualItem& rVisualItem,
    int& rMinGlyphPos, int& rEndGlyphPos ) const
{
    // return early when nothing of interest in this item
    if( rVisualItem.IsEmpty()
     || (rVisualItem.mnEndCharPos <= mnMinCharPos)
     || (mnEndCharPos <= rVisualItem.mnMinCharPos) )
        return false;

    // default: subrange is complete range
    rMinGlyphPos = rVisualItem.mnMinGlyphPos;
    rEndGlyphPos = rVisualItem.mnEndGlyphPos;

    // return early when the whole item is of interest
    if( (mnMinCharPos <= rVisualItem.mnMinCharPos)
     && (rVisualItem.mnEndCharPos <= mnEndCharPos ) )
        return true;

    // get glyph range from char range by looking at cluster boundries
    // TODO: optimize for case that LTR/RTL correspond to monotonous glyph indexes
    rMinGlyphPos = rVisualItem.mnEndGlyphPos;
    int nMaxGlyphPos = 0;

    int i = mnMinCharPos;
    if( i < rVisualItem.mnMinCharPos )
        i = rVisualItem.mnMinCharPos;
    int nCharPosLimit = rVisualItem.mnEndCharPos;
    if( nCharPosLimit > mnEndCharPos )
        nCharPosLimit = mnEndCharPos;
    for(; i < nCharPosLimit; ++i )
    {
        int n = mpLogClusters[ i ] + rVisualItem.mnMinGlyphPos;
        if( rMinGlyphPos > n )
            rMinGlyphPos = n;
        if( nMaxGlyphPos < n )
            nMaxGlyphPos = n;
    }
	if (nMaxGlyphPos > rVisualItem.mnEndGlyphPos)
		nMaxGlyphPos = rVisualItem.mnEndGlyphPos - 1;

    // extend the glyph range to account for all glyphs in referenced clusters
    if( !rVisualItem.IsRTL() ) // LTR-item
    {
        // extend to rightmost glyph of rightmost referenced cluster
        for( i = nMaxGlyphPos; ++i < rVisualItem.mnEndGlyphPos; nMaxGlyphPos = i )
            if( mpVisualAttrs[i].fClusterStart )
                break;
    }
    else // RTL-item
    {
        // extend to leftmost glyph of leftmost referenced cluster
        for( i = rMinGlyphPos; --i >= rVisualItem.mnMinGlyphPos; rMinGlyphPos = i )
            if( mpVisualAttrs[i].fClusterStart )
                break;
    }
    rEndGlyphPos = nMaxGlyphPos + 1;

    return true;
}

// -----------------------------------------------------------------------

int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
    int& nStartx8, sal_Int32* pGlyphAdvances, int* pCharPosAry ) const
{
    // HACK to allow fake-glyph insertion (e.g. for kashidas)
    // TODO: use iterator idiom instead of GetNextGlyphs(...)
    // TODO: else make sure that the limit for glyph injection is sufficient (currently 256)
    int nSubIter = nStartx8 & 0xff;
    int nStart = nStartx8 >> 8;

    // check the glyph iterator
    if( nStart > mnGlyphCount )       // nStart>MAX means no more glyphs
        return 0;

    // find the visual item for the nStart glyph position
    int nItem = 0;
    const VisualItem* pVI = mpVisualItems;
    if( nStart <= 0 )                 // nStart<=0 requests the first visible glyph
    {
        // find first visible item
        for(; nItem < mnItemCount; ++nItem, ++pVI )
            if( !pVI->IsEmpty() )
                break;
        // it is possible that there are glyphs but no valid visual item
        // TODO: get rid of these visual items more early
        if( nItem < mnItemCount )
            nStart = pVI->mnMinGlyphPos;
    }
    else //if( nStart > 0 )           // nStart>0 means absolute glyph pos +1
    {
        --nStart;

        // find matching item
        for(; nItem < mnItemCount; ++nItem, ++pVI )
            if( (nStart >= pVI->mnMinGlyphPos)
            &&  (nStart < pVI->mnEndGlyphPos) )
                break;
    }

    // after the last visual item there are no more glyphs
    if( (nItem >= mnItemCount) || (nStart < 0) )
    {
        nStartx8 = (mnGlyphCount + 1) << 8;
        return 0;
    }

    // calculate the first glyph in the next visual item
    int nNextItemStart = mnGlyphCount;
    while( ++nItem < mnItemCount )
    {
        if( mpVisualItems[nItem].IsEmpty() )
            continue;
        nNextItemStart = mpVisualItems[nItem].mnMinGlyphPos;
        break;
    }

    // get the range of relevant glyphs in this visual item
    int nMinGlyphPos, nEndGlyphPos;
    bool bRC = GetItemSubrange( *pVI, nMinGlyphPos, nEndGlyphPos );
    DBG_ASSERT( bRC, "USPLayout::GNG GISR() returned false" );
    if( !bRC )
    {
        nStartx8 = (mnGlyphCount + 1) << 8;
        return 0;
    }

    // make sure nStart is inside the range of relevant glyphs
    if( nStart < nMinGlyphPos )
        nStart = nMinGlyphPos;

    // calculate the start glyph xoffset relative to layout's base position,
    // advance to next visual glyph position by using adjusted glyph widths
    // TODO: speed up the calculation for nStart!=0 case by using rPos as a cache
    long nXOffset = pVI->mnXOffset;
    const int* pGlyphWidths = mpJustifications ? mpJustifications : mpGlyphAdvances;
    for( int i = nMinGlyphPos; i < nStart; ++i )
        nXOffset += pGlyphWidths[ i ];

    // adjust the nXOffset relative to glyph cluster start
    int c = mnMinCharPos;
    if( !pVI->IsRTL() ) // LTR-case
    {
        // LTR case: subtract the remainder of the cell from xoffset
        int nTmpIndex = mpLogClusters[c];
        while( (--c >= pVI->mnMinCharPos)
            && (nTmpIndex == mpLogClusters[c]) )
            nXOffset -= mpCharWidths[c];
    }
    else // RTL-case
    {
        // RTL case: add the remainder of the cell from xoffset
        int nTmpIndex = mpLogClusters[ pVI->mnEndCharPos - 1 ];
        while( (--c >= pVI->mnMinCharPos)
            && (nTmpIndex == mpLogClusters[c]) )
            nXOffset += mpCharWidths[c];

        // adjust the xoffset if justified glyphs are not positioned at their justified positions yet
		if( mpJustifications && !bManualCellAlign )
           nXOffset += mpJustifications[ nStart ] - mpGlyphAdvances[ nStart ];
    }

    // create mpGlyphs2Chars[] if it is needed later
    if( pCharPosAry && !mpGlyphs2Chars )
    {
        // create and reset the new array
        mpGlyphs2Chars = new int[ mnGlyphCapacity ];
        for( int i = 0; i < mnGlyphCount; ++i )
            mpGlyphs2Chars[i] = -1;
        // calculate the char->glyph mapping
        for( nItem = 0; nItem < mnItemCount; ++nItem )
        {
            // ignore invisible visual items
            const VisualItem& rVI = mpVisualItems[ nItem ];
            if( rVI.IsEmpty() )
                continue;
            // calculate the mapping by using mpLogClusters[]
            // mpGlyphs2Chars[] should obey the logical order
            // => reversing the loop does this by overwriting higher logicals
            for( c = rVI.mnEndCharPos; --c >= rVI.mnMinCharPos; )
            {
                int i = mpLogClusters[c] + rVI.mnMinGlyphPos;
                mpGlyphs2Chars[i] = c;
            }
        }
    }

    // calculate the absolute position of the first result glyph in pixel units
    const GOFFSET aGOffset = mpGlyphOffsets[ nStart ];
    Point aRelativePos( nXOffset + aGOffset.du, -aGOffset.dv );
    rPos = GetDrawPosition( aRelativePos );

	// fill the result arrays
    int nCount = 0;
    while( nCount < nLen )
    {
        // prepare return values
        sal_GlyphId aGlyphId = mpOutGlyphs[ nStart ];
        int nGlyphWidth = pGlyphWidths[ nStart ];
        int nCharPos = -1;    // no need to determine charpos
        if( mpGlyphs2Chars )  // unless explicitly requested+provided
            nCharPos = mpGlyphs2Chars[ nStart ];

        // inject kashida glyphs if needed
        if( !mbDisableGlyphInjection
        && mpJustifications
        && mnMinKashidaWidth
        && mpVisualAttrs[nStart].uJustification >= SCRIPT_JUSTIFY_ARABIC_NORMAL )
        {
			// prepare draw position adjustment
			int nExtraOfs = (nSubIter++) * mnMinKashidaWidth;
        	// calculate space available for the injected glyphs
   	        nGlyphWidth = mpGlyphAdvances[ nStart ];
	        const int nExtraWidth = mpJustifications[ nStart ] - nGlyphWidth;
			const int nToFillWidth = nExtraWidth - nExtraOfs;
	        if( (4*nToFillWidth >= mnMinKashidaWidth)    // prevent glyph-injection if there is no room
	        ||  ((nSubIter > 1) && (nToFillWidth > 0)) ) // unless they can overlap with others
	        {
	        	// handle if there is not sufficient room for a full glyph
	        	if( nToFillWidth < mnMinKashidaWidth )
	        	{
	        		// overlap it with the previously injected glyph if possible
	        		int nOverlap = mnMinKashidaWidth - nToFillWidth;
	        		// else overlap it with both neighboring glyphs
					if( nSubIter <= 1 )
						nOverlap /= 2;
					nExtraOfs -= nOverlap;
	        	}
	        	nGlyphWidth = mnMinKashidaWidth;
	        	aGlyphId = mnMinKashidaGlyph;
				nCharPos = -1;
	        }
	        else
	        {
	        	nExtraOfs += nToFillWidth;	// at right of cell
	        	nSubIter = 0;				// done with glyph injection
	        }
            if( !bManualCellAlign )
                nExtraOfs -= nExtraWidth;	// adjust for right-aligned cells

			// adjust the draw position for the injected-glyphs case
			if( nExtraOfs )
			{
				aRelativePos.X() += nExtraOfs;
				rPos = GetDrawPosition( aRelativePos );
			}
        }

        // update return values
        *(pGlyphs++) = aGlyphId;
        if( pGlyphAdvances )
            *(pGlyphAdvances++) = nGlyphWidth;
        if( pCharPosAry )
            *(pCharPosAry++) = nCharPos;

        // increment counter of returned glyphs
        ++nCount;

        // reduce code complexity by returning early in glyph-injection case
       	if( nSubIter != 0 )
       		break;

        // stop after the last visible glyph in this visual item
        if( ++nStart >= nEndGlyphPos )
        {
            nStart = nNextItemStart;
            break;
        }

        // RTL-justified glyph positioning is not easy
        // simplify the code by just returning only one glyph at a time
        if( mpJustifications && pVI->IsRTL() )
            break;

        // stop when the x-position of the next glyph is unexpected
        if( !pGlyphAdvances  )
            if( (mpGlyphOffsets && (mpGlyphOffsets[nStart].du != aGOffset.du) )
             || (mpJustifications && (mpJustifications[nStart] != mpGlyphAdvances[nStart]) ) )
                break;

        // stop when the y-position of the next glyph is unexpected
        if( mpGlyphOffsets && (mpGlyphOffsets[nStart].dv != aGOffset.dv) )
            break;
    }

    ++nStart;
    nStartx8 = (nStart << 8) + nSubIter;
    return nCount;
}

// -----------------------------------------------------------------------

void UniscribeLayout::MoveGlyph( int nStartx8, long nNewXPos )
{
    DBG_ASSERT( !(nStartx8 & 0xff), "USP::MoveGlyph(): glyph injection not disabled!" );
    int nStart = nStartx8 >> 8;
    if( nStart > mnGlyphCount )
        return;

    VisualItem* pVI = mpVisualItems;
    int nMinGlyphPos = 0, nEndGlyphPos;
    if( nStart == 0 )               // nStart==0 for first visible glyph
    {
        for( int i = mnItemCount; --i >= 0; ++pVI )
            if( GetItemSubrange( *pVI, nMinGlyphPos, nEndGlyphPos ) )
                break;
        nStart = nMinGlyphPos;
        DBG_ASSERT( nStart <= mnGlyphCount, "USPLayout::MoveG overflow" );
    }
    else //if( nStart > 0 )         // nStart>0 means absolute_glyphpos+1
    {
        --nStart;
        for( int i = mnItemCount; --i >= 0; ++pVI )
            if( (nStart >= pVI->mnMinGlyphPos) && (nStart < pVI->mnEndGlyphPos) )
                break;
        bool bRC = GetItemSubrange( *pVI, nMinGlyphPos, nEndGlyphPos );
	(void)bRC; // avoid var-not-used warning
        DBG_ASSERT( bRC, "USPLayout::MoveG GISR() returned false" );
    }

    long nDelta = nNewXPos - pVI->mnXOffset;
    if( nStart > nMinGlyphPos )
    {
        // move the glyph by expanding its left glyph but ignore dropped glyphs
        int i, nLastUndropped = nMinGlyphPos - 1;
        for( i = nMinGlyphPos; i < nStart; ++i )
		{
			if (mpOutGlyphs[i] != DROPPED_OUTGLYPH)
			{
	            nDelta -= (mpJustifications)? mpJustifications[ i ] : mpGlyphAdvances[ i ];
				nLastUndropped = i;
			}
		}
		if (nLastUndropped >= nMinGlyphPos)
		{
			mpGlyphAdvances[ nLastUndropped ] += nDelta;
			if (mpJustifications) mpJustifications[ nLastUndropped ] += nDelta;
		}
		else
		{
			pVI->mnXOffset += nDelta;
		}
    }
    else
    {
        // move the visual item by having an offset
        pVI->mnXOffset += nDelta;
    }
    // move subsequent items - this often isn't necessary because subsequent
    // moves will correct subsequent items. However, if there is a contiguous
    // range not involving fallback which spans items, this will be needed
    while (++pVI - mpVisualItems < mnItemCount)
    {
        pVI->mnXOffset += nDelta;
    }
}

// -----------------------------------------------------------------------

void UniscribeLayout::DropGlyph( int nStartx8 )
{
    DBG_ASSERT( !(nStartx8 & 0xff), "USP::DropGlyph(): glyph injection not disabled!" );
    int nStart = nStartx8 >> 8;
    DBG_ASSERT( nStart<=mnGlyphCount, "USPLayout::MoveG nStart overflow" );

    if( nStart > 0 )        // nStart>0 means absolute glyph pos + 1
        --nStart;
    else                    // nStart<=0 for first visible glyph
    {
        VisualItem* pVI = mpVisualItems;
        for( int i = mnItemCount, nDummy; --i >= 0; ++pVI )
            if( GetItemSubrange( *pVI, nStart, nDummy ) )
                break;
        DBG_ASSERT( nStart <= mnGlyphCount, "USPLayout::DropG overflow" );
		int nOffset = 0;
		int j = pVI->mnMinGlyphPos;
		while (mpOutGlyphs[j] == DROPPED_OUTGLYPH) j++;
		if (j == nStart)
		{
			pVI->mnXOffset += ((mpJustifications)? mpJustifications[nStart] : mpGlyphAdvances[nStart]);
		}
    }

    mpOutGlyphs[ nStart ] = DROPPED_OUTGLYPH;
}

// -----------------------------------------------------------------------

void UniscribeLayout::Simplify( bool /*bIsBase*/ )
{
    static const WCHAR cDroppedGlyph = DROPPED_OUTGLYPH;
    int i;
    // if there are no dropped glyphs don't bother
    for( i = 0; i < mnGlyphCount; ++i )
        if( mpOutGlyphs[ i ] == cDroppedGlyph )
            break;
    if( i >= mnGlyphCount )
        return;

    // prepare for sparse layout
    // => make sure mpGlyphs2Chars[] exists
    if( !mpGlyphs2Chars )
    {
        mpGlyphs2Chars = new int[ mnGlyphCapacity ];
        for( i = 0; i < mnGlyphCount; ++i )
            mpGlyphs2Chars[ i ] = -1;
        for( int nItem = 0; nItem < mnItemCount; ++nItem )
        {
            // skip invisible items
            VisualItem& rVI = mpVisualItems[ nItem ];
            if( rVI.IsEmpty() )
                continue;
            for( i = rVI.mnEndCharPos; --i >= rVI.mnMinCharPos; )
            {
                int j = mpLogClusters[ i ] + rVI.mnMinGlyphPos;
                mpGlyphs2Chars[ j ] = i;
            }
        }
    }

    // remove the dropped glyphs
    const int* pGlyphWidths = mpJustifications ? mpJustifications : mpGlyphAdvances;
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        VisualItem& rVI = mpVisualItems[ nItem ];
        if( rVI.IsEmpty() )
            continue;

        // mark replaced character widths
        for( i = rVI.mnMinCharPos; i < rVI.mnEndCharPos; ++i )
        {
            int j = mpLogClusters[ i ] + rVI.mnMinGlyphPos;
            if( mpOutGlyphs[ j ] == cDroppedGlyph )
                mpCharWidths[ i ] = 0;
        }

        // handle dropped glyphs at start of visual item
        int nMinGlyphPos, nEndGlyphPos, nOrigMinGlyphPos = rVI.mnMinGlyphPos;
        GetItemSubrange( rVI, nMinGlyphPos, nEndGlyphPos );
        i = nMinGlyphPos;
        while( (mpOutGlyphs[i] == cDroppedGlyph) && (i < nEndGlyphPos) )
        {
            //rVI.mnXOffset += pGlyphWidths[ i ];
            rVI.mnMinGlyphPos = ++i;
        }

        // when all glyphs in item got dropped mark it as empty
        if( i >= nEndGlyphPos )
        {
            rVI.mnEndGlyphPos = 0;
            continue;
        }
		// If there are still glyphs in the cluster and mnMinGlyphPos
		// has changed then we need to remove the dropped glyphs at start
		// to correct logClusters, which is unsigned and relative to the 
		// item start.
		if (rVI.mnMinGlyphPos != nOrigMinGlyphPos)
		{
			// drop any glyphs in the visual item outside the range
			for (i = nOrigMinGlyphPos; i < nMinGlyphPos; i++)
				mpOutGlyphs[ i ] = cDroppedGlyph;
			rVI.mnMinGlyphPos = i = nOrigMinGlyphPos;
		}

        // handle dropped glyphs in the middle of visual item
        for(; i < nEndGlyphPos; ++i )
            if( mpOutGlyphs[ i ] == cDroppedGlyph )
                break;
        int j = i;
        while( ++i < nEndGlyphPos )
        {
            if( mpOutGlyphs[ i ] == cDroppedGlyph )
                continue;
            mpOutGlyphs[ j ]      = mpOutGlyphs[ i ];
            mpGlyphOffsets[ j ]   = mpGlyphOffsets[ i ];
            mpVisualAttrs[ j ]    = mpVisualAttrs[ i ];
            mpGlyphAdvances[ j ]  = mpGlyphAdvances[ i ];
            if( mpJustifications )
                mpJustifications[ j ] = mpJustifications[ i ];
            const int k = mpGlyphs2Chars[ i ];
            mpGlyphs2Chars[ j ]   = k;
            const int nRelGlyphPos = (j++) - rVI.mnMinGlyphPos;
            if( k < 0) // extra glyphs are already mapped
                continue;
            mpLogClusters[ k ] = static_cast<WORD>(nRelGlyphPos);
        }

        rVI.mnEndGlyphPos = j;
    }
}

// -----------------------------------------------------------------------

void UniscribeLayout::DrawText( SalGraphics& ) const
{
    HFONT hOrigFont = DisableFontScaling();

    int nBaseClusterOffset = 0;
    int nBaseGlyphPos = -1;
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        const VisualItem& rVisualItem = mpVisualItems[ nItem ];

        // skip if there is nothing to display
        int nMinGlyphPos, nEndGlyphPos;
        if( !GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) )
            continue;

        if( nBaseGlyphPos < 0 )
        {
            // adjust draw position relative to cluster start
            if( rVisualItem.IsRTL() )
                nBaseGlyphPos = nEndGlyphPos - 1;
            else
                nBaseGlyphPos = nMinGlyphPos;

            const int* pGlyphWidths;
            if( mpJustifications )
                pGlyphWidths = mpJustifications;
            else
                pGlyphWidths = mpGlyphAdvances;

            int i = mnMinCharPos;
            while( (--i >= rVisualItem.mnMinCharPos)
                && (nBaseGlyphPos == mpLogClusters[i]) )
                 nBaseClusterOffset += mpCharWidths[i];

            if( !rVisualItem.IsRTL() )
                nBaseClusterOffset = -nBaseClusterOffset;
        }

        // now draw the matching glyphs in this item
        Point aRelPos( rVisualItem.mnXOffset + nBaseClusterOffset, 0 );
        Point aPos = GetDrawPosition( aRelPos );
        SCRIPT_CACHE& rScriptCache = GetScriptCache();
        (*pScriptTextOut)( mhDC, &rScriptCache,
            aPos.X(), aPos.Y(), 0, NULL,
            &rVisualItem.mpScriptItem->a, NULL, 0,
            mpOutGlyphs + nMinGlyphPos,
            nEndGlyphPos - nMinGlyphPos,
            mpGlyphAdvances + nMinGlyphPos,
            mpJustifications ? mpJustifications + nMinGlyphPos : NULL,
            mpGlyphOffsets + nMinGlyphPos );
    }

    if( hOrigFont )
        DeleteFont( SelectFont( mhDC, hOrigFont ) );
}

// -----------------------------------------------------------------------

long UniscribeLayout::FillDXArray( long* pDXArray ) const
{
    // calculate width of the complete layout
    long nWidth = mnBaseAdv;
    for( int nItem = mnItemCount; --nItem >= 0; )
    {
        const VisualItem& rVI = mpVisualItems[ nItem ];

        // skip if there is nothing to display
        int nMinGlyphPos, nEndGlyphPos;
        if( !GetItemSubrange( rVI, nMinGlyphPos, nEndGlyphPos ) )
            continue;

        // width = xoffset + width of last item
        nWidth = rVI.mnXOffset;
        const int* pGlyphWidths = mpJustifications ? mpJustifications : mpGlyphAdvances;
        for( int i = nMinGlyphPos; i < nEndGlyphPos; ++i )
            nWidth += pGlyphWidths[i];
        break;
    }

    // copy the virtual char widths into pDXArray[]
    if( pDXArray )
        for( int i = mnMinCharPos; i < mnEndCharPos; ++i )
            pDXArray[ i - mnMinCharPos ] = mpCharWidths[ i ];

    return nWidth;
}

// -----------------------------------------------------------------------

int UniscribeLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const
{
    long nWidth = 0;
    for( int i = mnMinCharPos; i < mnEndCharPos; ++i )
    {
        nWidth += mpCharWidths[ i ] * nFactor;

        // check if the nMaxWidth still fits the current sub-layout
        if( nWidth >= nMaxWidth )
        {
            // go back to cluster start
            // we have to find the visual item first since the mpLogClusters[]
            // needed to find the cluster start is relative to to the visual item
            int nMinGlyphIndex = 0;
            for( int nItem = 0; nItem < mnItemCount; ++nItem )
            {
                const VisualItem& rVisualItem = mpVisualItems[ nItem ];
                nMinGlyphIndex = rVisualItem.mnMinGlyphPos;
                if( (i >= rVisualItem.mnMinCharPos)
                &&  (i < rVisualItem.mnEndCharPos) )
                    break;
            }
            // now go back to the matching cluster start
            do
            {
                int nGlyphPos = mpLogClusters[i] + nMinGlyphIndex;
                if( 0 != mpVisualAttrs[ nGlyphPos ].fClusterStart )
                    return i;
            } while( --i >= mnMinCharPos );

            // if the cluster starts before the start of the visual item
            // then set the visual breakpoint before this item
            return mnMinCharPos;
        }

        // the visual break also depends on the nCharExtra between the characters
        nWidth += nCharExtra;
    }

    // the whole layout did fit inside the nMaxWidth
    return STRING_LEN;
}

// -----------------------------------------------------------------------

void UniscribeLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const
{
    int i;
    for( i = 0; i < nMaxIdx; ++i )
        pCaretXArray[ i ] = -1;
    long* const pGlyphPos = (long*)alloca( (mnGlyphCount+1) * sizeof(long) );
    for( i = 0; i <= mnGlyphCount; ++i )
        pGlyphPos[ i ] = -1;

    long nXPos = 0;
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        const VisualItem& rVisualItem = mpVisualItems[ nItem ];
        if( rVisualItem.IsEmpty() )
            continue;

        if (mnLayoutFlags & SAL_LAYOUT_FOR_FALLBACK)
        {
            nXPos = rVisualItem.mnXOffset;
        }
        // get glyph positions
        // TODO: handle when rVisualItem's glyph range is only partially used
        for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
        {
            pGlyphPos[ i ] = nXPos;
            nXPos += mpGlyphAdvances[ i ];
        }
        // rightmost position of this visualitem
        pGlyphPos[ i ] = nXPos;

        // convert glyph positions to character positions
        i = rVisualItem.mnMinCharPos;
        if( i < mnMinCharPos )
            i = mnMinCharPos;
        for(; (i < rVisualItem.mnEndCharPos) && (i < mnEndCharPos); ++i )
        {
            int j = mpLogClusters[ i ] + rVisualItem.mnMinGlyphPos;
            int nCurrIdx = i * 2;
            if( !rVisualItem.IsRTL() )
            {
                // normal positions for LTR case
                pCaretXArray[ nCurrIdx ]   = pGlyphPos[ j ];
                pCaretXArray[ nCurrIdx+1 ] = pGlyphPos[ j+1 ];
            }
            else
            {
                // reverse positions for RTL case
                pCaretXArray[ nCurrIdx ]   = pGlyphPos[ j+1 ];
                pCaretXArray[ nCurrIdx+1 ] = pGlyphPos[ j ];
            }
        }
    }

    if (!(mnLayoutFlags & SAL_LAYOUT_FOR_FALLBACK))
    {
        nXPos = 0;
        // fixup unknown character positions to neighbor
        for( i = 0; i < nMaxIdx; ++i )
        {
            if( pCaretXArray[ i ] >= 0 )
                nXPos = pCaretXArray[ i ];
            else
                pCaretXArray[ i ] = nXPos;
        }
    }
}

// -----------------------------------------------------------------------

void UniscribeLayout::AdjustLayout( ImplLayoutArgs& rArgs )
{
    SalLayout::AdjustLayout( rArgs );

    // adjust positions if requested
    if( rArgs.mpDXArray )
        ApplyDXArray( rArgs );
    else if( rArgs.mnLayoutWidth )
        Justify( rArgs.mnLayoutWidth );
}

// -----------------------------------------------------------------------

void UniscribeLayout::ApplyDXArray( const ImplLayoutArgs& rArgs )
{
    const long* pDXArray = rArgs.mpDXArray;

    // increase char widths in string range to desired values
    bool bModified = false;
    int nOldWidth = 0;
    DBG_ASSERT( mnUnitsPerPixel==1, "UniscribeLayout.mnUnitsPerPixel != 1" );
    int i,j;
    for( i = mnMinCharPos, j = 0; i < mnEndCharPos; ++i, ++j )
    {
        int nNewCharWidth = (pDXArray[j] - nOldWidth);
        // TODO: nNewCharWidth *= mnUnitsPerPixel;
        if( mpCharWidths[i] != nNewCharWidth )
        {
            mpCharWidths[i] = nNewCharWidth;
            bModified = true;
        }
        nOldWidth = pDXArray[j];
    }

    if( !bModified )
        return;

    // initialize justifications array
    mpJustifications = new int[ mnGlyphCapacity ];
    for( i = 0; i < mnGlyphCount; ++i )
        mpJustifications[ i ] = mpGlyphAdvances[ i ];

    // apply new widths to script items
    long nXOffset = 0;
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        VisualItem& rVisualItem = mpVisualItems[ nItem ];

        // set the position of this visual item
        rVisualItem.mnXOffset = nXOffset;

        // ignore empty visual items
        if( rVisualItem.IsEmpty() )
        {
            for (i = rVisualItem.mnMinCharPos; i < rVisualItem.mnEndCharPos; i++)
              nXOffset += mpCharWidths[i];
            continue;
        }
        // ignore irrelevant visual items
        if( (rVisualItem.mnMinCharPos >= mnEndCharPos)
         || (rVisualItem.mnEndCharPos <= mnMinCharPos) )
            continue;

		// if needed prepare special handling for arabic justification
		rVisualItem.mbHasKashidas = false;
		if( rVisualItem.IsRTL() )
        {
			for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
                if ( (1U << mpVisualAttrs[i].uJustification) & 0xFF82 )  //  any Arabic justification 
                {                                                        //  excluding SCRIPT_JUSTIFY_NONE
                    // yes                                               
                    rVisualItem.mbHasKashidas = true;
                    // so prepare for kashida handling
                    InitKashidaHandling();
					break;
				}

			if( rVisualItem.HasKashidas() )
				for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i )
				{
                    // TODO: check if we still need this hack after correction of kashida placing?
                    // (i87688): apparently yes, we still need it!
                    if ( mpVisualAttrs[i].uJustification == SCRIPT_JUSTIFY_NONE )
                        // usp decided that justification can't be applied here
						// but maybe our Kashida algorithm thinks differently.
						// To avoid trouble (gaps within words, last character of
						// a word gets a Kashida appended) override this.

						// I chose SCRIPT_JUSTIFY_ARABIC_KASHIDA to replace SCRIPT_JUSTIFY_NONE
						// just because this previous hack (which I haven't understand, sorry) used
						// the same value to replace. Don't know if this is really the best
						// thing to do, but it seems to fix things
						mpVisualAttrs[i].uJustification = SCRIPT_JUSTIFY_ARABIC_KASHIDA;
				}
        }

        // convert virtual charwidths to glyph justification values
        HRESULT nRC = (*pScriptApplyLogicalWidth)(
            mpCharWidths + rVisualItem.mnMinCharPos,
            rVisualItem.mnEndCharPos - rVisualItem.mnMinCharPos,
            rVisualItem.mnEndGlyphPos - rVisualItem.mnMinGlyphPos,
            mpLogClusters + rVisualItem.mnMinCharPos,
            mpVisualAttrs + rVisualItem.mnMinGlyphPos,
            mpGlyphAdvances + rVisualItem.mnMinGlyphPos,
            &rVisualItem.mpScriptItem->a,
            &rVisualItem.maABCWidths,
            mpJustifications + rVisualItem.mnMinGlyphPos );

        if( nRC != 0 )
        {
            delete[] mpJustifications;
            mpJustifications = NULL;
            break;
        }

        // to prepare for the next visual item
        // update nXOffset to the next items position
        // before the mpJustifications[] array gets modified
        int nMinGlyphPos, nEndGlyphPos;
        if( GetItemSubrange( rVisualItem, nMinGlyphPos, nEndGlyphPos ) )
        {
            for( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
                nXOffset += mpJustifications[ i ];
           
            if( rVisualItem.mbHasKashidas )
				KashidaItemFix( nMinGlyphPos, nEndGlyphPos );
        }

		// workaround needed for older USP versions:
        // right align the justification-adjusted glyphs in their cells for RTL-items
		// unless the right alignment is done by inserting kashidas
        if( bManualCellAlign && rVisualItem.IsRTL() && !rVisualItem.HasKashidas() )
        {
            for( i = nMinGlyphPos; i < nEndGlyphPos; ++i )
            {
                const int nXOffsetAdjust = mpJustifications[i] - mpGlyphAdvances[i];
				// #i99862# skip diacritics, we mustn't add extra justification to diacritics
				int nIdxAdd = i - 1;
				while( (nIdxAdd >= nMinGlyphPos) && !mpGlyphAdvances[nIdxAdd] )
					--nIdxAdd;
                if( nIdxAdd < nMinGlyphPos )
                    rVisualItem.mnXOffset += nXOffsetAdjust;
                else
                    mpJustifications[nIdxAdd] += nXOffsetAdjust;
                mpJustifications[i] -= nXOffsetAdjust;
            }
        }
    }
}

// -----------------------------------------------------------------------

void UniscribeLayout::InitKashidaHandling()
{
	if( mnMinKashidaGlyph != 0 )	// already initialized
		return;

	mrWinFontEntry.InitKashidaHandling( mhDC );
	mnMinKashidaWidth = static_cast<int>(mfFontScale * mrWinFontEntry.GetMinKashidaWidth());
	mnMinKashidaGlyph = mrWinFontEntry.GetMinKashidaGlyph();
}

// adjust the kashida placement matching to the WriterEngine
void UniscribeLayout::KashidaItemFix( int nMinGlyphPos, int nEndGlyphPos )
{
	// workaround needed for all known USP versions:
	// ApplyLogicalWidth does not match ScriptJustify behaviour
	for( int i = nMinGlyphPos; i < nEndGlyphPos; ++i )
	{
		// check for vowels
		if( (i > nMinGlyphPos && !mpGlyphAdvances[ i-1 ])
		&&  (1U << mpVisualAttrs[i].uJustification) & 0xFF83 )	// all Arabic justifiction types
		{														// including SCRIPT_JUSTIFY_NONE
			// vowel, we do it like ScriptJustify does
			// the vowel gets the extra width
			long nSpaceAdded =  mpJustifications[ i ] - mpGlyphAdvances[ i ];
			mpJustifications [ i ] = mpGlyphAdvances [ i ];
			mpJustifications [ i - 1 ] += nSpaceAdded;
		}
	}

	// redistribute the widths for kashidas
	for( int i = nMinGlyphPos; i < nEndGlyphPos; )
		KashidaWordFix ( nMinGlyphPos, nEndGlyphPos, &i );
}

bool UniscribeLayout::KashidaWordFix ( int nMinGlyphPos, int nEndGlyphPos, int* pnCurrentPos )
{
	// doing pixel work within a word.
	// sometimes we have extra pixels and sometimes we miss some pixels to get to mnMinKashidaWidth

	// find the next kashida
	int nMinPos = *pnCurrentPos;
	int nMaxPos = *pnCurrentPos;
	for( int i = nMaxPos; i < nEndGlyphPos; ++i )
	{
		if( (mpVisualAttrs[ i ].uJustification >= SCRIPT_JUSTIFY_ARABIC_BLANK)
		&&  (mpVisualAttrs[ i ].uJustification < SCRIPT_JUSTIFY_ARABIC_NORMAL) )
			break;
		nMaxPos = i;
	}
	*pnCurrentPos = nMaxPos + 1;
	if( nMinPos == nMaxPos )
		return false;

	// calculate the available space for an extra kashida
	long nMaxAdded = 0;
	int nKashPos = -1;
	for( int i = nMaxPos; i >= nMinPos; --i )
	{
		long nSpaceAdded = mpJustifications[ i ] - mpGlyphAdvances[ i ];
		if( nSpaceAdded > nMaxAdded )
		{
			nKashPos = i;
			nMaxAdded = nSpaceAdded;
		}
	}

	// return early if there is no need for an extra kashida
	if ( nMaxAdded <= 0 )
		return false;
	// return early if there is not enough space for an extra kashida
	if( 2*nMaxAdded < mnMinKashidaWidth ) 
		return false;

	// redistribute the extra spacing to the kashida position
	for( int i = nMinPos; i <= nMaxPos; ++i )
	{
		if( i == nKashPos )
			continue;
		// everything else should not have extra spacing
		long nSpaceAdded = mpJustifications[ i ] - mpGlyphAdvances[ i ];
		if( nSpaceAdded > 0 )
		{
			mpJustifications[ i ] -= nSpaceAdded;
			mpJustifications[ nKashPos ] += nSpaceAdded;
		}
	}

	// check if we fulfill minimal kashida width
	long nSpaceAdded = mpJustifications[ nKashPos ] - mpGlyphAdvances[ nKashPos ];
	if( nSpaceAdded < mnMinKashidaWidth )
	{
		// ugly: steal some pixels
		long nSteal = 1;
		if ( nMaxPos - nMinPos > 0 && ((mnMinKashidaWidth - nSpaceAdded) > (nMaxPos - nMinPos)))
			nSteal = (mnMinKashidaWidth - nSpaceAdded) / (nMaxPos - nMinPos); 
		for( int i = nMinPos; i <= nMaxPos; ++i )
		{
			if( i == nKashPos )
				continue;
			nSteal = Min( mnMinKashidaWidth - nSpaceAdded, nSteal );
			if ( nSteal > 0 )
			{
				mpJustifications [ i ] -= nSteal;
				mpJustifications [ nKashPos ] += nSteal;
				nSpaceAdded += nSteal;
			}
			if( nSpaceAdded >= mnMinKashidaWidth )
				return true;
		}
	}

	// blank padding
	long nSpaceMissing = mnMinKashidaWidth - nSpaceAdded;
	if( nSpaceMissing > 0 )
	{
		// inner glyph: distribute extra space evenly
		if( (nMinPos > nMinGlyphPos) && (nMaxPos < nEndGlyphPos - 1) )
		{
			mpJustifications [ nKashPos ] += nSpaceMissing;
			long nHalfSpace = nSpaceMissing / 2;
			mpJustifications [ nMinPos - 1 ] -= nHalfSpace;
			mpJustifications [ nMaxPos + 1 ] -= nSpaceMissing - nHalfSpace;
		}
		// rightmost: left glyph gets extra space
		else if( nMinPos > nMinGlyphPos )
		{
			mpJustifications [ nMinPos - 1 ] -= nSpaceMissing;
			mpJustifications [ nKashPos ] += nSpaceMissing;
		}
		// leftmost: right glyph gets extra space
		else if( nMaxPos < nEndGlyphPos - 1 )
		{
			mpJustifications [ nKashPos ] += nSpaceMissing;
			mpJustifications [ nMaxPos + 1 ] -= nSpaceMissing;
		}
		else
			return false;
	}

	return true;
}

// -----------------------------------------------------------------------

void UniscribeLayout::Justify( long nNewWidth )
{
    long nOldWidth = 0;
    int i;
    for( i = mnMinCharPos; i < mnEndCharPos; ++i )
        nOldWidth += mpCharWidths[ i ];
	if( nOldWidth <= 0 )
		return;

    nNewWidth *= mnUnitsPerPixel;	// convert into font units
    if( nNewWidth == nOldWidth )
        return;
    // prepare to distribute the extra width evenly among the visual items
    const double fStretch = (double)nNewWidth / nOldWidth;

    // initialize justifications array
    mpJustifications = new int[ mnGlyphCapacity ];
    for( i = 0; i < mnGlyphCapacity; ++i )
        mpJustifications[ i ] = mpGlyphAdvances[ i ];

    // justify stretched script items
    long nXOffset = 0;
    SCRIPT_CACHE& rScriptCache = GetScriptCache();
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        VisualItem& rVisualItem = mpVisualItems[ nItem ];
        if( rVisualItem.IsEmpty() )
            continue;

        if( (rVisualItem.mnMinCharPos < mnEndCharPos)
         && (rVisualItem.mnEndCharPos > mnMinCharPos) )
        {
            long nItemWidth = 0;
            for( i = rVisualItem.mnMinCharPos; i < rVisualItem.mnEndCharPos; ++i )
                nItemWidth += mpCharWidths[ i ];
            nItemWidth = (int)((fStretch - 1.0) * nItemWidth + 0.5);

            HRESULT nRC = (*pScriptJustify) (
                mpVisualAttrs + rVisualItem.mnMinGlyphPos,
                mpGlyphAdvances + rVisualItem.mnMinGlyphPos,
                rVisualItem.mnEndGlyphPos - rVisualItem.mnMinGlyphPos,
                nItemWidth,
                mnMinKashidaWidth,
                mpJustifications + rVisualItem.mnMinGlyphPos );

            rVisualItem.mnXOffset = nXOffset;
            nXOffset += nItemWidth;
        }
    }
}

// -----------------------------------------------------------------------

bool UniscribeLayout::IsKashidaPosValid ( int nCharPos ) const
{
	// we have to find the visual item first since the mpLogClusters[]
    // needed to find the cluster start is relative to to the visual item
    int nMinGlyphIndex = -1;
    for( int nItem = 0; nItem < mnItemCount; ++nItem )
    {
        const VisualItem& rVisualItem = mpVisualItems[ nItem ];
        if( (nCharPos >= rVisualItem.mnMinCharPos)
        &&  (nCharPos < rVisualItem.mnEndCharPos) )
		{
			nMinGlyphIndex = rVisualItem.mnMinGlyphPos;
            break;
		}
    }
	// Invalid char pos or leftmost glyph in visual item
    if ( nMinGlyphIndex == -1 || !mpLogClusters[ nCharPos ] ) 
		return false;

//	This test didn't give the expected results
/*	if( mpLogClusters[ nCharPos+1 ] == mpLogClusters[ nCharPos ]) 
	// two chars, one glyph
		return false;*/

	const int nGlyphPos = mpLogClusters[ nCharPos ] + nMinGlyphIndex;
	if( nGlyphPos <= 0 )
		return true;
	// justification is only allowed if the glyph to the left has not SCRIPT_JUSTIFY_NONE
	// and not SCRIPT_JUSTIFY_ARABIC_BLANK
	// special case: glyph to the left is vowel (no advance width)
	if ( mpVisualAttrs[ nGlyphPos-1 ].uJustification == SCRIPT_JUSTIFY_ARABIC_BLANK 
		|| ( mpVisualAttrs[ nGlyphPos-1 ].uJustification == SCRIPT_JUSTIFY_NONE 
			&& mpGlyphAdvances [ nGlyphPos-1 ] ))	
		return false;
	return true;
}

#endif // USE_UNISCRIBE

#ifdef ENABLE_GRAPHITE

class GraphiteLayoutWinImpl : public GraphiteLayout
{
public:
    GraphiteLayoutWinImpl(const gr::Font & font, ImplWinFontEntry & rFont)
        throw()
    : GraphiteLayout(font), mrFont(rFont) {};
    virtual ~GraphiteLayoutWinImpl() throw() {};
    virtual sal_GlyphId getKashidaGlyph(int & rWidth);
private:
    ImplWinFontEntry & mrFont;
};

sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth)
{
    rWidth = mrFont.GetMinKashidaWidth();
    return mrFont.GetMinKashidaGlyph();
}

// This class uses the SIL Graphite engine to provide complex text layout services to the VCL
// @author tse
//
class GraphiteWinLayout : public WinLayout
{
private:
    mutable GraphiteWinFont mpFont;
    grutils::GrFeatureParser * mpFeatures;
    mutable GraphiteLayoutWinImpl maImpl;
public:
    GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE) throw();

    static bool IsGraphiteEnabledFont(HDC hDC) throw();

    // used by upper layers
    virtual bool  LayoutText( ImplLayoutArgs& );    // first step of layout
    virtual void  AdjustLayout( ImplLayoutArgs& );  // adjusting after fallback etc.
    //  virtual void  InitFont() const;
    virtual void  DrawText( SalGraphics& ) const;

    // methods using string indexing
    virtual int   GetTextBreak( long nMaxWidth, long nCharExtra=0, int nFactor=1 ) const;
    virtual long  FillDXArray( long* pDXArray ) const;

    virtual void  GetCaretPositions( int nArraySize, long* pCaretXArray ) const;

    // methods using glyph indexing
    virtual int   GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&,
                      long* pGlyphAdvAry = 0, int* pCharPosAry = 0 ) const;

    // used by glyph+font+script fallback
    virtual void    MoveGlyph( int nStart, long nNewXPos );
    virtual void    DropGlyph( int nStart );
    virtual void    Simplify( bool bIsBase );
    ~GraphiteWinLayout() { delete mpFeatures; mpFeatures = NULL; };
protected:
    virtual void    ReplaceDC(gr::Segment & segment) const;
    virtual void    RestoreDC(gr::Segment & segment) const;
};

bool GraphiteWinLayout::IsGraphiteEnabledFont(HDC hDC) throw()
{
  return gr::WinFont::FontHasGraphiteTables(hDC);
}

GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE) throw()
  : WinLayout(hDC, rWFD, rWFE), mpFont(hDC),
    maImpl(mpFont, rWFE)
{
    const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( rWFE.maFontSelData.meLanguage );
    rtl::OString name = rtl::OUStringToOString(
        rWFE.maFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
    sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1;
    if (nFeat > 0)
    {
        rtl::OString aFeat = name.copy(nFeat, name.getLength() - nFeat);
        mpFeatures = new grutils::GrFeatureParser(mpFont, aFeat.getStr(), aLang.getStr());
    }
    else
    {
        mpFeatures = new grutils::GrFeatureParser(mpFont, aLang.getStr());
    }
    maImpl.SetFeatures(mpFeatures);
}

void GraphiteWinLayout::ReplaceDC(gr::Segment & segment) const
{
    COLORREF color = GetTextColor(mhDC);
    dynamic_cast<gr::WinFont&>(segment.getFont()).replaceDC(mhDC);
    SetTextColor(mhDC, color);
}

void GraphiteWinLayout::RestoreDC(gr::Segment & segment) const
{
    dynamic_cast<gr::WinFont&>(segment.getFont()).restoreDC();
}

bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args)
{
    if (args.mnMinCharPos >= args.mnEndCharPos)
    {
        maImpl.clear();
        return true;
    }
    HFONT hUnRotatedFont;
    if (args.mnOrientation)
    {
        // Graphite gets very confused if the font is rotated
        LOGFONTW aLogFont;
        ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont);
        aLogFont.lfEscapement = 0;
        aLogFont.lfOrientation = 0;
        hUnRotatedFont = ::CreateFontIndirectW( &aLogFont);
        ::SelectFont(mhDC, hUnRotatedFont);
    }
    WinLayout::AdjustLayout(args);
    mpFont.replaceDC(mhDC);
    maImpl.SetFontScale(WinLayout::mfFontScale);
    //bool succeeded = maImpl.LayoutText(args);
#ifdef GRCACHE
    GrSegRecord * pSegRecord = NULL;
    gr::Segment * pSegment = maImpl.CreateSegment(args, &pSegRecord);
#else
    gr::Segment * pSegment = maImpl.CreateSegment(args);
#endif
    bool bSucceeded = false;
    if (pSegment)
    {
        // replace the DC on the font within the segment
        ReplaceDC(*pSegment);
        // create glyph vectors
#ifdef GRCACHE
        bSucceeded = maImpl.LayoutGlyphs(args, pSegment, pSegRecord);
#else
        bSucceeded = maImpl.LayoutGlyphs(args, pSegment);
#endif
        // restore original DC
        RestoreDC(*pSegment);
#ifdef GRCACHE
        if (pSegRecord) pSegRecord->unlock();
        else delete pSegment;
#else
        delete pSegment;
#endif
    }
    mpFont.restoreDC();
    if (args.mnOrientation)
    {
        // restore the rotated font
        ::SelectFont(mhDC, mhFont);
        ::DeleteObject(hUnRotatedFont);
    }
    return bSucceeded;
}

void  GraphiteWinLayout::AdjustLayout(ImplLayoutArgs& rArgs)
{
    WinLayout::AdjustLayout(rArgs);
    maImpl.DrawBase() = WinLayout::maDrawBase;
    maImpl.DrawOffset() = WinLayout::maDrawOffset;
    if ( (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL) && rArgs.mpDXArray)
    {
        mrWinFontEntry.InitKashidaHandling(mhDC);
    }
    maImpl.AdjustLayout(rArgs);
}

void GraphiteWinLayout::DrawText(SalGraphics &sal_graphics) const
{
    HFONT hOrigFont = DisableFontScaling();
    const HDC aHDC = static_cast<WinSalGraphics&>(sal_graphics).getHDC();
    maImpl.DrawBase() = WinLayout::maDrawBase;
    maImpl.DrawOffset() = WinLayout::maDrawOffset;
    const int MAX_GLYPHS = 2;
    sal_GlyphId glyphIntStr[MAX_GLYPHS];
    WORD glyphWStr[MAX_GLYPHS];
    int glyphIndex = 0;
    Point aPos(0,0);
    int nGlyphs = 0;
    do
    {
        nGlyphs = maImpl.GetNextGlyphs(1, glyphIntStr, aPos, glyphIndex);
        if (nGlyphs < 1)
          break;
        std::copy(glyphIntStr, glyphIntStr + nGlyphs, glyphWStr);
        ::ExtTextOutW(aHDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX,
		              NULL, (LPCWSTR)&(glyphWStr), nGlyphs, NULL);
    } while (nGlyphs);
    if( hOrigFont )
          DeleteFont( SelectFont( aHDC, hOrigFont ) );
}

int GraphiteWinLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const
{
    mpFont.replaceDC(mhDC);
    int nBreak = maImpl.GetTextBreak(nMaxWidth, nCharExtra, nFactor);
    mpFont.restoreDC();
    return nBreak;
}

long  GraphiteWinLayout::FillDXArray( long* pDXArray ) const
{
    return maImpl.FillDXArray(pDXArray);
}

void GraphiteWinLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const
{
	maImpl.GetCaretPositions(nArraySize, pCaretXArray);
}

int GraphiteWinLayout::GetNextGlyphs( int length, sal_GlyphId* glyph_out,
        ::Point & pos_out, int &glyph_slot, long * glyph_adv, int *char_index) const
{
    maImpl.DrawBase() = WinLayout::maDrawBase;
    maImpl.DrawOffset() = WinLayout::maDrawOffset;
    return maImpl.GetNextGlyphs(length, glyph_out, pos_out, glyph_slot, glyph_adv, char_index);
}

void GraphiteWinLayout::MoveGlyph( int glyph_idx, long new_x_pos )
{
	maImpl.MoveGlyph(glyph_idx, new_x_pos);
}

void GraphiteWinLayout::DropGlyph( int glyph_idx )
{
	maImpl.DropGlyph(glyph_idx);
}

void GraphiteWinLayout::Simplify( bool is_base )
{
	maImpl.Simplify(is_base);
}
#endif // ENABLE_GRAPHITE
// =======================================================================

SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
{
    DBG_ASSERT( mpWinFontEntry[nFallbackLevel], "WinSalGraphics mpWinFontEntry==NULL");

	WinLayout* pWinLayout = NULL;

    const ImplWinFontData& rFontFace = *mpWinFontData[ nFallbackLevel ];
    ImplWinFontEntry& rFontInstance = *mpWinFontEntry[ nFallbackLevel ];

#if defined( USE_UNISCRIBE )
    if( !(rArgs.mnFlags & SAL_LAYOUT_COMPLEX_DISABLED)
    &&   (aUspModule || (bUspEnabled && InitUSP())) )   // CTL layout engine
    {
#ifdef ENABLE_GRAPHITE
        if (rFontFace.SupportsGraphite())
            pWinLayout = new GraphiteWinLayout( getHDC(), rFontFace, rFontInstance);
        else
#endif // ENABLE_GRAPHITE
        // script complexity is determined in upper layers
        pWinLayout = new UniscribeLayout( getHDC(), rFontFace, rFontInstance );
        // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
        // the created UniscribeLayout, otherwise the data passed into the
        // constructor might become invalid too early
    }
    else
#endif // USE_UNISCRIBE
    {
#ifdef GCP_KERN_HACK
        if( (rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) && !rFontInstance.HasKernData() )
        {
            // TODO: directly cache kerning info in the rFontInstance
            // TODO: get rid of kerning methods+data in WinSalGraphics object
            GetKernPairs( 0, NULL );
            rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
        }
#endif // GCP_KERN_HACK

        BYTE eCharSet = ANSI_CHARSET;
        if( mpLogFont )
            eCharSet = mpLogFont->lfCharSet;
#ifdef ENABLE_GRAPHITE
        if (rFontFace.SupportsGraphite())
            pWinLayout = new GraphiteWinLayout( getHDC(), rFontFace, rFontInstance);
        else
#endif // ENABLE_GRAPHITE
            pWinLayout = new SimpleWinLayout( getHDC(), eCharSet, rFontFace, rFontInstance );
    }

    if( mfFontScale != 1.0 )
        pWinLayout->SetFontScale( mfFontScale );

    return pWinLayout;
}

// -----------------------------------------------------------------------

int	WinSalGraphics::GetMinKashidaWidth()
{
	if( !mpWinFontEntry[0] )
		return 0;
	mpWinFontEntry[0]->InitKashidaHandling( getHDC() );
	int nMinKashida = static_cast<int>(mfFontScale * mpWinFontEntry[0]->GetMinKashidaWidth());
	return nMinKashida;
}

// =======================================================================

ImplWinFontEntry::ImplWinFontEntry( ImplFontSelectData& rFSD )
:   ImplFontEntry( rFSD )
,   maWidthMap( 512 )
,   mpKerningPairs( NULL )
,   mnKerningPairs( -1 )
,	mnMinKashidaWidth( -1 )
,	mnMinKashidaGlyph( -1 )
{
#ifdef USE_UNISCRIBE
    maScriptCache = NULL;
#endif // USE_UNISCRIBE
}

// -----------------------------------------------------------------------

ImplWinFontEntry::~ImplWinFontEntry()
{
#ifdef USE_UNISCRIBE
    if( maScriptCache != NULL )
        (*pScriptFreeCache)( &maScriptCache );
#endif // USE_UNISCRIBE
#ifdef GCP_KERN_HACK
    delete[] mpKerningPairs;
#endif // GCP_KERN_HACK
}

// -----------------------------------------------------------------------

bool ImplWinFontEntry::HasKernData() const
{
    return (mnKerningPairs >= 0);
}

// -----------------------------------------------------------------------

void ImplWinFontEntry::SetKernData( int nPairCount, const KERNINGPAIR* pPairData )
{
    mnKerningPairs = nPairCount;
    mpKerningPairs = new KERNINGPAIR[ mnKerningPairs ];
    ::memcpy( mpKerningPairs, (const void*)pPairData, nPairCount*sizeof(KERNINGPAIR) );
}

// -----------------------------------------------------------------------

int ImplWinFontEntry::GetKerning( sal_Unicode cLeft, sal_Unicode cRight ) const
{
    int nKernAmount = 0;
    if( mpKerningPairs )
    {
        const KERNINGPAIR aRefPair = { cLeft, cRight, 0 };
        const KERNINGPAIR* pFirstPair = mpKerningPairs;
        const KERNINGPAIR* pEndPair = mpKerningPairs + mnKerningPairs;
        const KERNINGPAIR* pPair = std::lower_bound( pFirstPair,
            pEndPair, aRefPair, ImplCmpKernData );
        if( (pPair != pEndPair)
        &&  (pPair->wFirst == aRefPair.wFirst)
        &&  (pPair->wSecond == aRefPair.wSecond) )
            nKernAmount = pPair->iKernAmount;
    }

    return nKernAmount;
}

// -----------------------------------------------------------------------

bool ImplWinFontEntry::InitKashidaHandling( HDC hDC )
{
	if( mnMinKashidaWidth >= 0 )	// already cached?
		return mnMinKashidaWidth;

	// initialize the kashida width
	mnMinKashidaWidth = 0;
	mnMinKashidaGlyph = 0;
#ifdef USE_UNISCRIBE
	if (aUspModule || (bUspEnabled && InitUSP())) 
	{
		SCRIPT_FONTPROPERTIES aFontProperties;
		aFontProperties.cBytes = sizeof (aFontProperties); 
		SCRIPT_CACHE& rScriptCache = GetScriptCache();
		HRESULT nRC = (*pScriptGetFontProperties)( hDC, &rScriptCache, &aFontProperties );
		if( nRC != 0 )
			return false;
		mnMinKashidaWidth = aFontProperties.iKashidaWidth;
		mnMinKashidaGlyph = aFontProperties.wgKashida;
    }
#endif // USE_UNISCRIBE

	return true;
}

// =======================================================================

ImplFontData* ImplWinFontData::Clone() const
{
    if( mpUnicodeMap )
        mpUnicodeMap->AddReference();
    ImplFontData* pClone = new ImplWinFontData( *this );
    return pClone;
}

// -----------------------------------------------------------------------

ImplFontEntry* ImplWinFontData::CreateFontInstance( ImplFontSelectData& rFSD ) const
{
    ImplFontEntry* pEntry = new ImplWinFontEntry( rFSD );
    return pEntry;
}

// =======================================================================
