diff options
author | Herbert Duerr <hdu@openoffice.org> | 2002-09-04 16:33:07 +0000 |
---|---|---|
committer | Herbert Duerr <hdu@openoffice.org> | 2002-09-04 16:33:07 +0000 |
commit | 6266d9147888c65338062ddf468e921f7c1c9248 (patch) | |
tree | ac7bf93fe80258fb6e18232b728ab07b76b5b701 /vcl/source/glyphs | |
parent | b252d8266b113bff6305a1be676ce5be830a16a5 (diff) |
#100194# implement Bidi processing for ServerFonts
Diffstat (limited to 'vcl/source/glyphs')
-rwxr-xr-x | vcl/source/glyphs/gcach_layout.cxx | 338 |
1 files changed, 187 insertions, 151 deletions
diff --git a/vcl/source/glyphs/gcach_layout.cxx b/vcl/source/glyphs/gcach_layout.cxx index 6de4b060be6c..7c49ac4d8531 100755 --- a/vcl/source/glyphs/gcach_layout.cxx +++ b/vcl/source/glyphs/gcach_layout.cxx @@ -2,8 +2,8 @@ * * $RCSfile: gcach_layout.cxx,v $ * - * $Revision: 1.13 $ - * last change: $Author: hdu $ $Date: 2002-08-22 16:44:29 $ + * $Revision: 1.14 $ + * last change: $Author: hdu $ $Date: 2002-09-04 17:33:07 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -86,78 +86,41 @@ #include <cstdio> #endif -// ======================================================================= - -ServerFontLayout::ServerFontLayout( ServerFont* pServerFont, - const ImplLayoutArgs& rArgs ) -: GenericSalLayout( rArgs ), - mpServerFont( pServerFont ) -{} - -// ======================================================================= -// Layout Engine Abstract Base Class -// ======================================================================= - -class ServerFontLayoutEngine -{ -public: - virtual ServerFontLayout* operator()( ServerFont*, const ImplLayoutArgs& rArgs ); -}; - static ServerFontLayoutEngine aSimpleLayoutEngine; // ======================================================================= // layout implementation for ServerFont // ======================================================================= -bool ServerFont::InitLayoutEngine() -{ - // setup default layout engine - mpLayoutData = (void*)&aSimpleLayoutEngine; - return true; -} - -// ----------------------------------------------------------------------- - -void ServerFont::DoneLayoutEngine() -{ - ServerFontLayoutEngine* pLE = (ServerFontLayoutEngine*)mpLayoutData; - if( (pLE != NULL) && (pLE != &aSimpleLayoutEngine) ) - delete pLE; - mpLayoutData = NULL; -} - -// ----------------------------------------------------------------------- - -ServerFontLayout* ServerFont::LayoutText( const ImplLayoutArgs& rLayoutArgs ) +ServerFontLayout::ServerFontLayout( const ImplLayoutArgs& rArgs, ServerFont& rFont ) +: GenericSalLayout( rArgs ), + mrServerFont( rFont ) { ServerFontLayoutEngine* pLE = NULL; - if( !(rLayoutArgs.mnFlags & SAL_LAYOUT_COMPLEX_DISABLED) ) - { - if( !mpLayoutData ) - InitLayoutEngine(); - pLE = (ServerFontLayoutEngine*)mpLayoutData; - } + if( ~rArgs.mnFlags & (SAL_LAYOUT_COMPLEX_DISABLED|SAL_LAYOUT_BIDI_STRONG) ) + pLE = rFont.GetLayoutEngine(); if( !pLE ) pLE = &aSimpleLayoutEngine; - ServerFontLayout* pSalLayout = (*pLE)( this, rLayoutArgs ); - if( rLayoutArgs.mpDXArray ) - pSalLayout->ApplyDXArray( rLayoutArgs.mpDXArray ); - if( rLayoutArgs.mnLayoutWidth ) - pSalLayout->Justify( rLayoutArgs.mnLayoutWidth ); - return pSalLayout; + (*pLE)( *this, rArgs ); + + if( rArgs.mpDXArray ) + ApplyDXArray( rArgs.mpDXArray ); + if( rArgs.mnLayoutWidth ) + Justify( rArgs.mnLayoutWidth ); } -// ----------------------------------------------------------------------- +// ======================================================================= -ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, +bool ServerFontLayoutEngine::operator()( ServerFontLayout& rLayout, const ImplLayoutArgs& rArgs ) { + FreetypeServerFont& rFont = reinterpret_cast<FreetypeServerFont&>(rLayout.GetServerFont()); + bool bRightToLeft = (SAL_LAYOUT_BIDI_RTL & rArgs.mnFlags) != 0; - int nGlyphCount = rArgs.mnEndCharIndex - rArgs.mnFirstCharIndex; - GlyphItem* pGlyphBuffer = new GlyphItem[ nGlyphCount ]; + int nGlyphCount = rArgs.mnEndCharPos - rArgs.mnMinCharPos; + GlyphItem* pGlyphItems = new GlyphItem[ nGlyphCount ]; Point aNewPos( 0, 0 ); bool bWantFallback = false; @@ -165,15 +128,15 @@ ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, int nGlyphWidth = 0; for( int i = 0; i < nGlyphCount; ++i ) { - int nLogicalIndex = bRightToLeft ? rArgs.mnEndCharIndex-1-i : rArgs.mnFirstCharIndex+i; - int nGlyphIndex = pFont->GetGlyphIndex( rArgs.mpStr[ nLogicalIndex ] ); + int nLogicalIndex = bRightToLeft ? rArgs.mnEndCharPos-1-i : rArgs.mnMinCharPos+i; + int nGlyphIndex = rFont.GetGlyphIndex( rArgs.mpStr[ nLogicalIndex ] ); if( !nGlyphIndex ) bWantFallback = true; // apply pair kerning if requested if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags ) { - int nKern = pFont->GetGlyphKernValue( nOldGlyphId, nGlyphIndex ); + int nKern = rFont.GetGlyphKernValue( nOldGlyphId, nGlyphIndex ); nGlyphWidth += nKern; nOldGlyphId = nGlyphIndex; } @@ -181,10 +144,11 @@ ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, // update position of this glyph using all previous info aNewPos.X() += nGlyphWidth; - const GlyphMetric& rGM = pFont->GetGlyphMetric( nGlyphIndex ); + const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex ); nGlyphWidth = rGM.GetCharWidth(); - pGlyphBuffer[i] = GlyphItem( nLogicalIndex, nGlyphIndex, aNewPos, - GlyphItem::CLUSTER_START, nGlyphWidth ); + int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0; + pGlyphItems[i] = GlyphItem( nLogicalIndex, nGlyphIndex, aNewPos, + nGlyphFlags, nGlyphWidth ); } // apply asian kerning if requested @@ -193,10 +157,10 @@ ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, { bool bVertical = false; // TODO - const xub_Unicode* pStr = rArgs.mpStr + rArgs.mnFirstCharIndex; + const xub_Unicode* pStr = rArgs.mpStr + rArgs.mnMinCharPos; // #99658# also do asian kerning one beyond substring int nLen = nGlyphCount; - if( rArgs.mnFirstCharIndex + nLen < rArgs.mnLength ) + if( rArgs.mnMinCharPos + nLen < rArgs.mnLength ) ++nLen; long nOffset = 0; for( int i = 1; i < nLen; ++i ) @@ -210,24 +174,23 @@ ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, long nDelta = (nKernFirst < nKernNext) ? nKernFirst : nKernNext; if( nDelta<0 && nKernFirst!=0 && nKernNext!=0 ) { - nGlyphWidth = pGlyphBuffer[i-1].mnOrigWidth; + nGlyphWidth = pGlyphItems[i-1].mnOrigWidth; nDelta = (nDelta * nGlyphWidth + 2) / 4; if( i == nGlyphCount ) - pGlyphBuffer[i-1].mnNewWidth += nDelta; + pGlyphItems[i-1].mnNewWidth += nDelta; nOffset += nDelta; } } if( i < nGlyphCount ) - pGlyphBuffer[i].maLinearPos.X() += nOffset; + pGlyphItems[i].maLinearPos.X() += nOffset; } } // create layout object - ServerFontLayout* pSalLayout = new ServerFontLayout( pFont, rArgs ); - pSalLayout->SetGlyphItems( pGlyphBuffer, nGlyphCount ); - pSalLayout->SetWantFallback( bWantFallback ); - return pSalLayout; + rLayout.SetGlyphItems( pGlyphItems, nGlyphCount ); + rLayout.SetWantFallback( bWantFallback ); + return true; } // ======================================================================= @@ -241,6 +204,7 @@ ServerFontLayout* ServerFontLayoutEngine::operator()( ServerFont* pFont, #include <layout/LEFontInstance.h> #include <layout/LEScripts.h> #include <unicode/uscript.h> +#include <unicode/ubidi.h> using namespace U_ICU_NAMESPACE; @@ -250,11 +214,11 @@ class IcuFontFromServerFont : public LEFontInstance { private: - FreetypeServerFont* const mpServerFont; + FreetypeServerFont& mrServerFont; public: - IcuFontFromServerFont( FreetypeServerFont* pFont ) - : mpServerFont(pFont) + IcuFontFromServerFont( FreetypeServerFont& rFont ) + : mrServerFont( rFont ) {} virtual const void* getFontTable(LETag tableTag) const; @@ -294,11 +258,11 @@ const void* IcuFontFromServerFont::getFontTable( LETag nICUTableTag ) const pTagName[4] = 0; ULONG nLength; - const unsigned char* pBuffer = mpServerFont->GetTable( pTagName, &nLength ); + const unsigned char* pBuffer = mrServerFont.GetTable( pTagName, &nLength ); #ifdef VERBOSE_DEBUG fprintf(stderr,"IcuGetTable(\"%s\") => %p\n", pTagName, pBuffer); - int mnHeight = mpServerFont->GetFontSelData().mnHeight; - const char* pName = mpServerFont->GetFontFileName()->getStr(); + int mnHeight = mrServerFont.GetFontSelData().mnHeight; + const char* pName = mrServerFont.GetFontFileName()->getStr(); fprintf(stderr,"font( h=%d, s=%\"%s\" )\n", mnHeight, pName ); #endif return (const void*)pBuffer; @@ -308,7 +272,7 @@ const void* IcuFontFromServerFont::getFontTable( LETag nICUTableTag ) const le_bool IcuFontFromServerFont::canDisplay( LEUnicode32 ch ) const { - le_bool rc = (mpServerFont->GetRawGlyphIndex( ch ) != 0); + le_bool rc = (mrServerFont.GetRawGlyphIndex( ch ) != 0); return rc; } @@ -316,7 +280,7 @@ le_bool IcuFontFromServerFont::canDisplay( LEUnicode32 ch ) const le_int32 IcuFontFromServerFont::getUnitsPerEM() const { - return mpServerFont->GetEmUnits(); + return mrServerFont.GetEmUnits(); } // ----------------------------------------------------------------------- @@ -347,7 +311,7 @@ LEGlyphID IcuFontFromServerFont::mapCharToGlyph( LEUnicode32 c1, LEUnicode32 c2 = c1; if( pMapper ) c2 = pMapper->mapChar( c1 ); - LEGlyphID nGlyphIndex = mpServerFont->GetRawGlyphIndex( c2 ); + LEGlyphID nGlyphIndex = mrServerFont.GetRawGlyphIndex( c2 ); return nGlyphIndex; } @@ -368,7 +332,7 @@ le_int32 IcuFontFromServerFont::getName( void IcuFontFromServerFont::getGlyphAdvance( LEGlyphID nGlyphIndex, LEPoint &advance ) const { - const GlyphMetric& rGM = mpServerFont->GetGlyphMetric( nGlyphIndex ); + const GlyphMetric& rGM = mrServerFont.GetGlyphMetric( nGlyphIndex ); advance.fX = rGM.GetCharWidth(); advance.fY = 0; } @@ -389,7 +353,7 @@ le_bool IcuFontFromServerFont::getGlyphPoint( LEGlyphID glyph, float IcuFontFromServerFont::getXPixelsPerEm() const { - const ImplFontSelectData& r = mpServerFont->GetFontSelData(); + const ImplFontSelectData& r = mrServerFont.GetFontSelData(); float fX = r.mnWidth ? r.mnWidth : r.mnHeight; return fX; } @@ -398,7 +362,7 @@ float IcuFontFromServerFont::getXPixelsPerEm() const float IcuFontFromServerFont::getYPixelsPerEm() const { - float fY = mpServerFont->GetFontSelData().mnHeight; + float fY = mrServerFont.GetFontSelData().mnHeight; return fY; } @@ -408,9 +372,9 @@ float IcuFontFromServerFont::xUnitsToPoints( float xUnits ) const { // TODO: avoid assumption: pixels==points float fPoints = xUnits; - const ImplFontSelectData& r = mpServerFont->GetFontSelData(); + const ImplFontSelectData& r = mrServerFont.GetFontSelData(); fPoints *= r.mnWidth ? r.mnWidth : r.mnHeight; - fPoints /= mpServerFont->GetEmUnits(); + fPoints /= mrServerFont.GetEmUnits(); return fPoints; } @@ -420,8 +384,8 @@ float IcuFontFromServerFont::yUnitsToPoints( float yUnits ) const { // TODO: avoid assumption pixels==points float fPoints = yUnits; - fPoints *= mpServerFont->GetFontSelData().mnHeight; - fPoints /= mpServerFont->GetEmUnits(); + fPoints *= mrServerFont.GetFontSelData().mnHeight; + fPoints /= mrServerFont.GetEmUnits(); return fPoints; } @@ -438,8 +402,8 @@ void IcuFontFromServerFont::unitsToPoints( LEPoint &units, LEPoint &points ) con float IcuFontFromServerFont::xPixelsToUnits( float xPixels ) const { float fPixels = xPixels; - fPixels *= mpServerFont->GetEmUnits(); - const ImplFontSelectData& r = mpServerFont->GetFontSelData(); + fPixels *= mrServerFont.GetEmUnits(); + const ImplFontSelectData& r = mrServerFont.GetFontSelData(); fPixels /= r.mnWidth ? r.mnWidth : r.mnHeight; return fPixels; } @@ -449,8 +413,8 @@ float IcuFontFromServerFont::xPixelsToUnits( float xPixels ) const float IcuFontFromServerFont::yPixelsToUnits( float yPixels ) const { float fPixels = yPixels; - fPixels *= mpServerFont->GetEmUnits(); - fPixels /= mpServerFont->GetFontSelData().mnHeight; + fPixels *= mrServerFont.GetEmUnits(); + fPixels /= mrServerFont.GetFontSelData().mnHeight; return fPixels; } @@ -482,17 +446,16 @@ private: LayoutEngine* mpIcuLE; public: - IcuLayoutEngine( FreetypeServerFont* pServerFont ); + IcuLayoutEngine( FreetypeServerFont& ); virtual ~IcuLayoutEngine(); - bool IsReady() const { return (mpIcuLE != NULL); } - virtual ServerFontLayout* operator()( ServerFont*, const ImplLayoutArgs& ); + virtual bool operator()( ServerFontLayout&, const ImplLayoutArgs& ); }; // ----------------------------------------------------------------------- -IcuLayoutEngine::IcuLayoutEngine( FreetypeServerFont* pServerFont ) -: maIcuFont( pServerFont ), +IcuLayoutEngine::IcuLayoutEngine( FreetypeServerFont& rServerFont ) +: maIcuFont( rServerFont ), mpIcuLE( NULL ), meScriptCode( USCRIPT_INVALID_CODE ) {} @@ -507,7 +470,7 @@ IcuLayoutEngine::~IcuLayoutEngine() // ----------------------------------------------------------------------- -ServerFontLayout* IcuLayoutEngine::operator()( ServerFont* pFont, +bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, const ImplLayoutArgs& rArgs ) { LEUnicode* pIcuChars; @@ -529,7 +492,7 @@ ServerFontLayout* IcuLayoutEngine::operator()( ServerFont* pFont, // find matching script // TODO: handle errors better // TODO: consider script changes - le_int32 eScriptCode = uscript_getScript( pIcuChars[rArgs.mnFirstCharIndex], &rcI18n ); + le_int32 eScriptCode = uscript_getScript( pIcuChars[rArgs.mnMinCharPos], &rcI18n ); // get layout engine matching to this script // no engine change necessary if script is latin @@ -551,81 +514,154 @@ ServerFontLayout* IcuLayoutEngine::operator()( ServerFont* pFont, // fall back to default layout if needed if( !mpIcuLE ) - return aSimpleLayoutEngine( pFont, rArgs ); - - // TODO: split up BiDi runs - le_bool bRightToLeft = (SAL_LAYOUT_BIDI_RTL & rArgs.mnFlags) != 0; + return aSimpleLayoutEngine( rLayout, rArgs ); + + // run Bidi algorithms if necessary + bool bRightToLeft = (0 != (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL)); + UBiDi* pParaBidi; + UBiDi* pLineBidi; + int32_t* pVisualMap; + UTextOffset nMinBidiPos; + UTextOffset nEndBidiPos; + int nRunCount = 1; + + if( rArgs.mnFlags & SAL_LAYOUT_BIDI_STRONG ) + { + pParaBidi = NULL; + pLineBidi = NULL; + pVisualMap = NULL; + nMinBidiPos = rArgs.mnMinCharPos; + nEndBidiPos = rArgs.mnEndCharPos; + } + else + { + pParaBidi = ubidi_openSized( rArgs.mnLength, 0, &rcI18n ); + ubidi_setPara( pParaBidi, rArgs.mpStr, rArgs.mnLength, + (bRightToLeft ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR), NULL, &rcI18n ); + pLineBidi = pParaBidi; + if( (0 < rArgs.mnMinCharPos) || (rArgs.mnEndCharPos < rArgs.mnLength) ) + { + pLineBidi = ubidi_openSized( rArgs.mnEndCharPos - rArgs.mnMinCharPos, 0, &rcI18n ); + ubidi_setLine( pParaBidi, rArgs.mnMinCharPos, rArgs.mnEndCharPos, pLineBidi, &rcI18n ); + } + nRunCount = ubidi_countRuns( pLineBidi, &rcI18n ); + pVisualMap = (int32_t*)alloca( nRunCount * sizeof(*pVisualMap) ); + ubidi_getVisualMap( pLineBidi, pVisualMap, &rcI18n ); + if( U_FAILURE(rcI18n) ) + return false; + } - // run ICU layout engine - int nGlyphCount = mpIcuLE->layoutChars( pIcuChars, rArgs.mnFirstCharIndex, - rArgs.mnEndCharIndex - rArgs.mnFirstCharIndex, rArgs.mnLength, - bRightToLeft, 0.0, 0.0, rcIcu ); - if( LE_FAILURE(rcIcu) ) - return NULL; + // layout bidi/script runs and export them to a ServerFontLayout + Point aNewPos( 0, 0 ); + bool bWantFallback = false; + int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos) + 16; + int nSumGlyphCount = 0; - // import layout info from icu + // allocate temporary arrays + GlyphItem* pGlyphItems = new GlyphItem[ nGlyphCapacity ]; struct IcuPosition{ float fX, fY; }; - LEGlyphID* pIcuGlyphs = (LEGlyphID*)alloca( nGlyphCount * sizeof(LEGlyphID) ); - le_int32* pCharIndices = (le_int32*)alloca( nGlyphCount * sizeof(le_int32) ); - IcuPosition* pGlyphPositions = (IcuPosition*)alloca( (nGlyphCount+1) * sizeof(IcuPosition) ); - - mpIcuLE->getGlyphs( pIcuGlyphs, rcIcu ); - mpIcuLE->getCharIndices( pCharIndices, rcIcu ); - mpIcuLE->getGlyphPositions( (float*)pGlyphPositions, rcIcu ); - mpIcuLE->reset(); - if( LE_FAILURE(rcIcu) ) - return NULL; - - // export layout info to ServerFontLayout - GlyphItem* pGlyphBuffer = new GlyphItem[ nGlyphCount ]; - bool bWantFallback = false; + LEGlyphID* pIcuGlyphs = (LEGlyphID*)alloca( nGlyphCapacity * sizeof(LEGlyphID) ); + le_int32* pCharIndices = (le_int32*)alloca( nGlyphCapacity * sizeof(le_int32) ); + IcuPosition* pGlyphPositions = (IcuPosition*)alloca( (nGlyphCapacity+1) * sizeof(IcuPosition) ); - Point aNewPos; - const IcuPosition* pPos = pGlyphPositions; - FreetypeServerFont* pFtFont = reinterpret_cast<FreetypeServerFont*>(pFont); - for( int i = 0; i < nGlyphCount; ++i, ++pPos ) + for( int i = 0; i < nRunCount; ++i ) { - //TODO: remove workaround below for ICU getting pCharIndex wrong - int nCharIndex = rArgs.mnFirstCharIndex + pCharIndices[i]; - int nGlyphIndex = pIcuGlyphs[i]; - if( nGlyphIndex != 0 ) + if( pVisualMap ) { - // apply vertical flags, etc. - sal_Unicode aChar = rArgs.mpStr[ pCharIndices[ i ] ]; - nGlyphIndex = pFtFont->FixupGlyphIndex( nGlyphIndex, aChar ); + nMinBidiPos = pVisualMap[i]; + bRightToLeft = (UBIDI_RTL == ubidi_getVisualRun( pLineBidi, i, &nMinBidiPos, &nEndBidiPos )); + nEndBidiPos += nMinBidiPos; } - else - bWantFallback = true; + // run ICU layout engine + int nRunGlyphCount = mpIcuLE->layoutChars( pIcuChars, nMinBidiPos, + nEndBidiPos - nMinBidiPos, rArgs.mnLength, bRightToLeft, + aNewPos.X(), aNewPos.Y(), rcIcu ); + if( LE_FAILURE(rcIcu) ) + break; + + // import layout info from icu + // TODO: reallocate also temporary arrays if necessary + if( nRunGlyphCount >= nGlyphCapacity ) + break; + mpIcuLE->getGlyphs( pIcuGlyphs, rcIcu ); + mpIcuLE->getCharIndices( pCharIndices, rcIcu ); + mpIcuLE->getGlyphPositions( &pGlyphPositions->fX, rcIcu ); + mpIcuLE->reset(); + if( LE_FAILURE(rcIcu) ) + break; + + if( nGlyphCapacity < nSumGlyphCount + nRunGlyphCount ) + { + nGlyphCapacity = 2 * (nSumGlyphCount + nRunGlyphCount) + 16; + GlyphItem* pNewGI = new GlyphItem[ nGlyphCapacity ]; + for( int j = 0; j < nSumGlyphCount; ++j ) + pNewGI[j] = pGlyphItems[j]; + delete[] pGlyphItems; + pGlyphItems = pNewGI; + } + + // convert results to GlyphItems + const IcuPosition* pPos = pGlyphPositions; + FreetypeServerFont& rFont = reinterpret_cast<FreetypeServerFont&>(rLayout.GetServerFont()); + for( int i = 0; i < nRunGlyphCount; ++i, ++pPos ) + { + //TODO: remove workaround below for ICU getting pCharIndex wrong + int nCharPos = nMinBidiPos + pCharIndices[i]; + int nGlyphIndex = pIcuGlyphs[i]; + if( !nGlyphIndex ) + bWantFallback = true; + { + // apply vertical flags, etc. + sal_Unicode aChar = rArgs.mpStr[ pCharIndices[ i ] ]; + nGlyphIndex = rFont.FixupGlyphIndex( nGlyphIndex, aChar ); + } + + aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) ); + const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex ); + int nGlyphWidth = rGM.GetCharWidth(); + long nGlyphFlags = (nGlyphWidth > 0) ? 0 : GlyphItem::IS_IN_CLUSTER; + if( bRightToLeft ) + nGlyphFlags |= GlyphItem::IS_RTL_GLYPH; + pGlyphItems[ nSumGlyphCount+i ] + = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth ); + //TODO: apply kerning if requested, set MOVED flag + } aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) ); - const GlyphMetric& rGM = pFont->GetGlyphMetric( nGlyphIndex ); - int nGlyphWidth = rGM.GetCharWidth(); - long nGlyphFlags = (nGlyphWidth > 0) ? GlyphItem::CLUSTER_START : 0; - pGlyphBuffer[i] = GlyphItem( nCharIndex, nGlyphIndex, aNewPos, - nGlyphFlags, nGlyphWidth ); - //TODO: apply kerning if requested, set MOVED flag + nSumGlyphCount += nRunGlyphCount; + } + + // cleanup Bidi engine + if( pLineBidi != pParaBidi ) + ubidi_close( pLineBidi ); + if( pParaBidi != NULL ) + ubidi_close( pParaBidi ); + + if( LE_FAILURE(rcIcu) ) + { + delete[] pGlyphItems; + return false; } - aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) ); - ServerFontLayout* pSalLayout = new ServerFontLayout( pFont, rArgs ); - pSalLayout->SetGlyphItems( pGlyphBuffer, nGlyphCount ); - pSalLayout->SetWantFallback( bWantFallback ); - return pSalLayout; + // create ServerFontLayout using GlyphItems from above + rLayout.SetGlyphItems( pGlyphItems, nSumGlyphCount ); + rLayout.SetWantFallback( bWantFallback ); + return true; } #endif // ENABLE_ICU_LAYOUT // ======================================================================= -bool FreetypeServerFont::InitLayoutEngine() +ServerFontLayoutEngine* FreetypeServerFont::GetLayoutEngine() { // find best layout engine for font, platform, script and language #ifdef ENABLE_ICU_LAYOUT - IcuLayoutEngine* pLE = new IcuLayoutEngine( this ); - mpLayoutData = (void*)pLE; + if( !mpLayoutEngine ) + mpLayoutEngine = new IcuLayoutEngine( *this ); #endif // ENABLE_ICU_LAYOUT - return (mpLayoutData != NULL); + return mpLayoutEngine; } // ======================================================================= |