diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2013-05-13 19:38:04 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2013-06-16 22:17:00 +0200 |
commit | b6ecac9fb90c9caa684a10ca0f108da70e4d3245 (patch) | |
tree | 73a89f692a70e944e47c15a09d0e8c94546644ef /vcl/generic | |
parent | 7aa42913bb1828b877c2f73b4fe59cc3c65a67bf (diff) |
Bye Bye ICU Layout Engine
Change-Id: I0f887ba378f9dac45a3736e4d1789585651148d1
Diffstat (limited to 'vcl/generic')
-rw-r--r-- | vcl/generic/glyphs/gcach_layout.cxx | 680 |
1 files changed, 4 insertions, 676 deletions
diff --git a/vcl/generic/glyphs/gcach_layout.cxx b/vcl/generic/glyphs/gcach_layout.cxx index 3c3c6de52055..4826936c59fd 100644 --- a/vcl/generic/glyphs/gcach_layout.cxx +++ b/vcl/generic/glyphs/gcach_layout.cxx @@ -33,13 +33,7 @@ #include <hb-icu.h> #include <hb-ot.h> -#include <layout/LayoutEngine.h> -#include <layout/LEFontInstance.h> -#include <layout/LELanguages.h> -#include <layout/LEScripts.h> - #include <unicode/uscript.h> -#include <unicode/ubidi.h> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/i18n/CharacterIteratorMode.hpp> @@ -51,9 +45,7 @@ ServerFontLayout::ServerFontLayout( ServerFont& rFont ) : mrServerFont( rFont ) -{ - bUseHarfBuzz = (getenv("SAL_USE_ICULE") == NULL); -} +{ } void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const { @@ -64,7 +56,7 @@ void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs ) { - ServerFontLayoutEngine* pLE = mrServerFont.GetLayoutEngine(bUseHarfBuzz); + ServerFontLayoutEngine* pLE = mrServerFont.GetLayoutEngine(); assert(pLE); bool bRet = pLE ? pLE->layout(*this, rArgs) : false; return bRet; @@ -502,676 +494,12 @@ bool HbLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs) } // ======================================================================= -// bridge to ICU LayoutEngine -// ======================================================================= - -using namespace U_ICU_NAMESPACE; - -static const LEGlyphID ICU_DELETED_GLYPH = 0xFFFF; -static const LEGlyphID ICU_MARKED_GLYPH = 0xFFFE; - -// ----------------------------------------------------------------------- - -class IcuFontFromServerFont -: public LEFontInstance -{ -private: - ServerFont& mrServerFont; - -public: - IcuFontFromServerFont( ServerFont& rFont ) - : mrServerFont( rFont ) - {} - - virtual const void* getFontTable(LETag tableTag, size_t &length) const; - virtual const void* getFontTable(LETag tableTag) const; - virtual le_int32 getUnitsPerEM() const; - virtual float getXPixelsPerEm() const; - virtual float getYPixelsPerEm() const; - virtual float getScaleFactorX() const; - virtual float getScaleFactorY() const; - - using LEFontInstance::mapCharToGlyph; - virtual LEGlyphID mapCharToGlyph( LEUnicode32 ch ) const; - virtual LEGlyphID mapCharToGlyph( LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth ) const; - - virtual le_int32 getAscent() const; - virtual le_int32 getDescent() const; - virtual le_int32 getLeading() const; - - virtual void getGlyphAdvance( LEGlyphID glyph, LEPoint &advance ) const; - virtual le_bool getGlyphPoint( LEGlyphID glyph, le_int32 pointNumber, LEPoint& point ) const; -}; - -// ----------------------------------------------------------------------- - -const void* IcuFontFromServerFont::getFontTable( LETag nICUTableTag, size_t & rLength ) const -{ - char pTagName[5]; - pTagName[0] = (char)(nICUTableTag >> 24); - pTagName[1] = (char)(nICUTableTag >> 16); - pTagName[2] = (char)(nICUTableTag >> 8); - pTagName[3] = (char)(nICUTableTag); - pTagName[4] = 0; - - sal_uLong nLength = 0; - const unsigned char* pBuffer = mrServerFont.GetTable( pTagName, &nLength ); - rLength = static_cast<size_t>(nLength); - SAL_INFO("vcl", "IcuGetTable(\"" << pTagName << "\") => " << pBuffer << ", len=" << rLength); - SAL_INFO( - "vcl", - "font( h=" << mrServerFont.GetFontSelData().mnHeight << ", \"" - << mrServerFont.GetFontFileName()->getStr() << "\" )"); - return pBuffer; -} - -const void* IcuFontFromServerFont::getFontTable( LETag nICUTableTag ) const -{ - size_t nLength = 0; - return getFontTable( nICUTableTag, nLength); -} - -// ----------------------------------------------------------------------- - -le_int32 IcuFontFromServerFont::getUnitsPerEM() const -{ - return mrServerFont.GetEmUnits(); -} - -// ----------------------------------------------------------------------- - -float IcuFontFromServerFont::getXPixelsPerEm() const -{ - const FontSelectPattern& r = mrServerFont.GetFontSelData(); - float fX = r.mnWidth ? r.mnWidth : r.mnHeight; - return fX; -} - -// ----------------------------------------------------------------------- - -float IcuFontFromServerFont::getYPixelsPerEm() const -{ - float fY = mrServerFont.GetFontSelData().mnHeight; - return fY; -} - -// ----------------------------------------------------------------------- - -float IcuFontFromServerFont::getScaleFactorX() const -{ - return 1.0; -} - -// ----------------------------------------------------------------------- - -float IcuFontFromServerFont::getScaleFactorY() const -{ - return 1.0; -} - -// ----------------------------------------------------------------------- - -LEGlyphID IcuFontFromServerFont::mapCharToGlyph( LEUnicode32 ch ) const -{ - LEGlyphID nGlyphIndex = mrServerFont.GetRawGlyphIndex( ch ); - return nGlyphIndex; -} - -LEGlyphID IcuFontFromServerFont::mapCharToGlyph( LEUnicode32 ch, const LECharMapper *mapper, le_bool /*filterZeroWidth*/ ) const -{ - /* - fdo#31821, icu has... - >│93 if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) { │ - │94 return canDisplay(mappedChar) ? 0x0001 : 0xFFFF; │ - │95 } - so only the Indic layouts allow the joiners to get mapped to glyphs - */ - return LEFontInstance::mapCharToGlyph( ch, mapper, false ); -} - -// ----------------------------------------------------------------------- - -le_int32 IcuFontFromServerFont::getAscent() const -{ - const FT_Size_Metrics& rMetrics = mrServerFont.GetMetricsFT(); - le_int32 nAscent = (+rMetrics.ascender + 32) >> 6; - return nAscent; -} - -// ----------------------------------------------------------------------- - -le_int32 IcuFontFromServerFont::getDescent() const -{ - const FT_Size_Metrics& rMetrics = mrServerFont.GetMetricsFT(); - le_int32 nDescent = (-rMetrics.descender + 32) >> 6; - return nDescent; -} - -// ----------------------------------------------------------------------- - -le_int32 IcuFontFromServerFont::getLeading() const -{ - const FT_Size_Metrics& rMetrics = mrServerFont.GetMetricsFT(); - le_int32 nLeading = ((rMetrics.height - rMetrics.ascender + rMetrics.descender) + 32) >> 6; - return nLeading; -} - -// ----------------------------------------------------------------------- - -void IcuFontFromServerFont::getGlyphAdvance( LEGlyphID nGlyphIndex, - LEPoint &advance ) const -{ - if( (nGlyphIndex == ICU_MARKED_GLYPH) - || (nGlyphIndex == ICU_DELETED_GLYPH) ) - { - // deleted glyph or mark glyph has not advance - advance.fX = 0; - } - else - { - const GlyphMetric& rGM = mrServerFont.GetGlyphMetric( nGlyphIndex ); - advance.fX = rGM.GetCharWidth(); - } - - advance.fY = 0; -} - -// ----------------------------------------------------------------------- - -le_bool IcuFontFromServerFont::getGlyphPoint( LEGlyphID, - le_int32 pointNumber, LEPoint& ) const -{ - //TODO: replace dummy implementation - SAL_INFO("vcl", "getGlyphPoint(" << pointNumber << ")"); - return false; -} - -// ======================================================================= - -class IcuLayoutEngine : public ServerFontLayoutEngine -{ -private: - IcuFontFromServerFont maIcuFont; - - LanguageCodes meLanguageCode; - le_int32 meScriptCode; - le_int32 mnLayoutFlags; - LayoutEngine* mpIcuLE; - -public: - IcuLayoutEngine( ServerFont& ); - virtual ~IcuLayoutEngine(); - - virtual bool layout( ServerFontLayout&, ImplLayoutArgs& ); -}; - -// ----------------------------------------------------------------------- - -IcuLayoutEngine::IcuLayoutEngine( ServerFont& rServerFont ) -: maIcuFont( rServerFont ), - meLanguageCode( nullLanguageCode ), - meScriptCode( USCRIPT_INVALID_CODE ), - mnLayoutFlags( 0 ), - mpIcuLE( NULL ) -{} - -// ----------------------------------------------------------------------- - -IcuLayoutEngine::~IcuLayoutEngine() -{ - delete mpIcuLE; -} - -// ----------------------------------------------------------------------- - -namespace -{ - LanguageCodes mapLanguageTypetoICU(LanguageType eLangCode) - { - LanguageTag aLangTag(eLangCode); - OUString sLanguage = aLangTag.getLanguage(); - - if (sLanguage == "af") // Afrikaans - return afkLanguageCode; - else if (sLanguage == "ar") // Arabic - return araLanguageCode; - else if (sLanguage == "as") // Assamese - return asmLanguageCode; - else if (sLanguage == "be") // Belarussian - return belLanguageCode; - else if (sLanguage == "bn") // Bengali - return benLanguageCode; - else if (sLanguage == "bo") // Tibetan - return tibLanguageCode; - else if (sLanguage == "bu") // Bulgarian - return bgrLanguageCode; - else if (sLanguage == "ca") // Catalan - return catLanguageCode; - else if (sLanguage == "cs") // Czech - return csyLanguageCode; - else if (sLanguage == "ch") // Chechen - return cheLanguageCode; - else if (sLanguage == "co") // Coptic - return copLanguageCode; - else if (sLanguage == "cy") // Welsh - return welLanguageCode; - else if (sLanguage == "da") // Danish - return danLanguageCode; - else if (sLanguage == "de") // German - return deuLanguageCode; - else if (sLanguage == "dz") // Dzongkha - return dznLanguageCode; - else if (sLanguage == "el") // Greek - return ellLanguageCode; - else if (sLanguage == "en") // English - return engLanguageCode; - else if (sLanguage == "et") // Estonian - return etiLanguageCode; - else if (sLanguage == "eu") // Basque - return euqLanguageCode; - else if (sLanguage == "fa") // Farsi - return farLanguageCode; - else if (sLanguage == "fi") // Finnish - return finLanguageCode; - else if (sLanguage == "fr") // French - return fraLanguageCode; - else if (sLanguage == "ga") // Irish Gaelic - return gaeLanguageCode; - else if (sLanguage == "gu") // Gujarati - return gujLanguageCode; - else if (sLanguage == "ha") // Hausa - return hauLanguageCode; - else if (sLanguage == "he") // Hebrew - return iwrLanguageCode; - else if (sLanguage == "hi") // Hindi - return hinLanguageCode; - else if (sLanguage == "hr") // Croatian - return hrvLanguageCode; - else if (sLanguage == "hu") // Hungarian - return hunLanguageCode; - else if (sLanguage == "hy") // Armenian - return hyeLanguageCode; - else if (sLanguage == "id") // Indonesian - return indLanguageCode; - else if (sLanguage == "it") // Italian - return itaLanguageCode; - else if (sLanguage == "ja") // Japanese - return janLanguageCode; - else if (sLanguage == "kn") // Kannada - return kanLanguageCode; - else if (sLanguage == "ks") // Kashmiri - return kshLanguageCode; - else if (sLanguage == "kh") // Khmer - return khmLanguageCode; - else if (sLanguage == "kok") // Konkani - return kokLanguageCode; - else if (sLanguage == "ko") // Korean - return korLanguageCode; - else if (sLanguage == "ml") // Malayalam - Reformed (should there be some bcp47 tag for Traditional Malayalam) - return mlrLanguageCode; - else if (sLanguage == "mr") // Marathi - return marLanguageCode; - else if (sLanguage == "mt") // Maltese - return mtsLanguageCode; - else if (sLanguage == "mni") // Manipuri - return mniLanguageCode; - else if (sLanguage == "mn") // Mongolian - return mngLanguageCode; - else if (sLanguage == "ne") // Nepali - return nepLanguageCode; - else if (sLanguage == "or") // Oriya - return oriLanguageCode; - else if (sLanguage == "pl") // Polish - return plkLanguageCode; - else if (sLanguage == "po") // Portuguese - return ptgLanguageCode; - else if (sLanguage == "ps") // Pashto - return pasLanguageCode; - else if (sLanguage == "ro") // Romanian - return romLanguageCode; - else if (sLanguage == "ru") // Russian - return rusLanguageCode; - else if (sLanguage == "sa") // Sanskrit - return sanLanguageCode; - else if (sLanguage == "si") // Sinhalese - return snhLanguageCode; - else if (sLanguage == "sk") // Slovak - return skyLanguageCode; - else if (sLanguage == "sd") // Sindhi - return sndLanguageCode; - else if (sLanguage == "sl") // Slovenian - return slvLanguageCode; - else if (sLanguage == "es") // Spanish - return espLanguageCode; - else if (sLanguage == "sq") // Albanian - return sqiLanguageCode; - else if (sLanguage == "sr") // Serbian - return srbLanguageCode; - else if (sLanguage == "sv") // Swedish - return sveLanguageCode; - else if (sLanguage == "syr") // Syriac - return syrLanguageCode; - else if (sLanguage == "ta") // Tamil - return tamLanguageCode; - else if (sLanguage == "te") // Telugu - return telLanguageCode; - else if (sLanguage == "th") // Thai - return thaLanguageCode; - else if (sLanguage == "tu") // Turkish - return trkLanguageCode; - else if (sLanguage == "ur") // Urdu - return urdLanguageCode; - else if (sLanguage == "yi") // Yiddish - return jiiLanguageCode; - else if (sLanguage == "zh") // Chinese - { - OUString sScript = aLangTag.getScript(); - if (sScript.isEmpty()) - { - if (MsLangId::isTraditionalChinese(eLangCode)) - sScript = "Hant"; - else - sScript = "Hans"; - } - if (sScript == "Latn") - return zhpLanguageCode; - else if (sScript == "Hans") - return zhsLanguageCode; - else if (sScript == "Hant") - return zhtLanguageCode; - } - - //if there are new ones, please reexamine the mapping list for the new ones - BOOST_STATIC_ASSERT(languageCodeCount == 72); - return nullLanguageCode; - } -} - -//See https://bugs.freedesktop.org/show_bug.cgi?id=31016 -#define ARABIC_BANDAID - -bool IcuLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs) -{ - le_int32 nLayoutFlags = 0; -#if (U_ICU_VERSION_MAJOR_NUM > 4) - if (rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) - nLayoutFlags |= LayoutEngine::kTypoFlagKern; - if (rArgs.mnFlags & SAL_LAYOUT_ENABLE_LIGATURES) - nLayoutFlags |= LayoutEngine::kTypoFlagLiga; -#else - if (rArgs.mnFlags & SAL_LAYOUT_KERNING_PAIRS) - nLayoutFlags |= 0x01; - if (rArgs.mnFlags & SAL_LAYOUT_ENABLE_LIGATURES) - nLayoutFlags |= 0x10; -#endif - - LEUnicode* pIcuChars; - if( sizeof(LEUnicode) == sizeof(*rArgs.mpStr) ) - pIcuChars = (LEUnicode*)rArgs.mpStr; - else - { - // this conversion will only be needed when either - // ICU's or OOo's unicodes stop being unsigned shorts - // TODO: watch out for surrogates! - pIcuChars = (LEUnicode*)alloca( rArgs.mnLength * sizeof(LEUnicode) ); - for( xub_StrLen ic = 0; ic < rArgs.mnLength; ++ic ) - pIcuChars[ic] = static_cast<LEUnicode>( rArgs.mpStr[ic] ); - } - - // allocate temporary arrays, note: round to even - int nGlyphCapacity = (3 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos ) | 15) + 1; - - rLayout.Reserve(nGlyphCapacity); - - struct IcuPosition{ float fX, fY; }; - const int nAllocSize = sizeof(LEGlyphID) + sizeof(le_int32) + sizeof(IcuPosition); - LEGlyphID* pIcuGlyphs = (LEGlyphID*)alloca( (nGlyphCapacity * nAllocSize) + sizeof(IcuPosition) ); - le_int32* pCharIndices = (le_int32*)((char*)pIcuGlyphs + nGlyphCapacity * sizeof(LEGlyphID) ); - IcuPosition* pGlyphPositions = (IcuPosition*)((char*)pCharIndices + nGlyphCapacity * sizeof(le_int32) ); - - ServerFont& rFont = rLayout.GetServerFont(); - - UErrorCode rcI18n = U_ZERO_ERROR; - LEErrorCode rcIcu = LE_NO_ERROR; - Point aNewPos( 0, 0 ); - for( int nGlyphCount = 0;; ) - { - int nMinRunPos, nEndRunPos; - bool bRightToLeft; - if( !rArgs.GetNextRun( &nMinRunPos, &nEndRunPos, &bRightToLeft ) ) - break; - - // find matching script - // TODO: split up bidi run into script runs - le_int32 eScriptCode = -1; - for( int i = nMinRunPos; i < nEndRunPos; ++i ) - { - le_int32 eNextScriptCode = uscript_getScript( pIcuChars[i], &rcI18n ); - if( (eNextScriptCode > USCRIPT_INHERITED) ) - { - eScriptCode = eNextScriptCode; - if (eNextScriptCode != latnScriptCode) - break; - } - } - if( eScriptCode < 0 ) // TODO: handle errors better - eScriptCode = latnScriptCode; - - LanguageCodes eLanguageCode = mapLanguageTypetoICU(rArgs.meLanguage); - - // get layout engine matching to this script and ligature/kerning combination - // no engine change necessary if script is latin - if ( !mpIcuLE || - ((eScriptCode != meScriptCode) && (eScriptCode > USCRIPT_INHERITED)) || - (mnLayoutFlags != nLayoutFlags) || (meLanguageCode != eLanguageCode) ) - { - // TODO: cache multiple layout engines when multiple scripts are used - delete mpIcuLE; - meLanguageCode = eLanguageCode; - meScriptCode = eScriptCode; - mnLayoutFlags = nLayoutFlags; - mpIcuLE = LayoutEngine::layoutEngineFactory( &maIcuFont, eScriptCode, eLanguageCode, nLayoutFlags, rcIcu ); - if( LE_FAILURE(rcIcu) ) - { - delete mpIcuLE; - mpIcuLE = NULL; - } - } - - // fall back to default layout if needed - if( !mpIcuLE ) - break; - - // run ICU layout engine - // TODO: get enough context, remove extra glyps below - int nRawRunGlyphCount = mpIcuLE->layoutChars( pIcuChars, - nMinRunPos, nEndRunPos - nMinRunPos, rArgs.mnLength, - bRightToLeft, aNewPos.X(), aNewPos.Y(), rcIcu ); - if( LE_FAILURE(rcIcu) ) - return false; - - // import layout info from icu - mpIcuLE->getGlyphs( pIcuGlyphs, rcIcu ); - mpIcuLE->getCharIndices( pCharIndices, rcIcu ); - mpIcuLE->getGlyphPositions( &pGlyphPositions->fX, rcIcu ); - if( LE_FAILURE(rcIcu) ) - return false; - - // layout bidi/script runs and export them to a ServerFontLayout - // convert results to GlyphItems - int nLastCharPos = -1; - int nClusterMinPos = -1; - int nClusterMaxPos = -1; - bool bClusterStart = true; - int nFilteredRunGlyphCount = 0; - const IcuPosition* pPos = pGlyphPositions; - for( int i = 0; i < nRawRunGlyphCount; ++i, ++pPos ) - { - LEGlyphID nGlyphIndex = pIcuGlyphs[i]; - // ignore glyphs which were marked or deleted by ICU - if( (nGlyphIndex == ICU_MARKED_GLYPH) - || (nGlyphIndex == ICU_DELETED_GLYPH) ) - continue; - - // adjust the relative char pos - int nCharPos = pCharIndices[i]; - if( nCharPos >= 0 ) { - nCharPos += nMinRunPos; - // ICU seems to return bad pCharIndices - // for some combinations of ICU+font+text - // => better give up now than crash later - if( nCharPos >= nEndRunPos ) - continue; - } - - // if needed request glyph fallback by updating LayoutArgs - if( !nGlyphIndex ) - { - rLayout.setNeedFallback(rArgs, nCharPos, bRightToLeft); - if( SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags ) - continue; - } - - - // apply vertical flags, etc. - bool bDiacritic = false; - if( nCharPos >= 0 ) - { - sal_UCS4 aChar = rArgs.mpStr[ nCharPos ]; - nGlyphIndex = rFont.FixupGlyphIndex( nGlyphIndex, aChar ); - - // i#99367# HACK: try to detect all diacritics - if( aChar>=0x0300 && aChar<0x2100 ) - bDiacritic = IsDiacritic( aChar ); - } - - // get glyph position and its metrics - aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) ); - const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex ); - int nGlyphWidth = rGM.GetCharWidth(); - int nNewWidth = nGlyphWidth; - if( nGlyphWidth <= 0 ) - bDiacritic |= true; - // i#99367# force all diacritics to zero width - // TODO: we need mnOrigWidth/mnLogicWidth/mnNewWidth - else if( bDiacritic ) - nGlyphWidth = nNewWidth = 0; - else - { - // Hack, find next +ve width glyph and calculate current - // glyph width by substracting the two posituons - const IcuPosition* pNextPos = pPos+1; - for ( int j = i + 1; j <= nRawRunGlyphCount; ++j, ++pNextPos ) - { - if ( j == nRawRunGlyphCount ) - { - nNewWidth = static_cast<int>(pNextPos->fX - pPos->fX); - break; - } - - LEGlyphID nNextGlyphIndex = pIcuGlyphs[j]; - if( (nNextGlyphIndex == ICU_MARKED_GLYPH) - || (nNextGlyphIndex == ICU_DELETED_GLYPH) ) - continue; - - const GlyphMetric& rNextGM = rFont.GetGlyphMetric( nNextGlyphIndex ); - int nNextGlyphWidth = rNextGM.GetCharWidth(); - if ( nNextGlyphWidth > 0 ) - { - nNewWidth = static_cast<int>(pNextPos->fX - pPos->fX); - break; - } - } - } - - // heuristic to detect glyph clusters - bool bInCluster = true; - if( nLastCharPos == -1 ) - { - nClusterMinPos = nClusterMaxPos = nCharPos; - bInCluster = false; - } - else if( !bRightToLeft ) - { - // left-to-right case - if( nClusterMinPos > nCharPos ) - nClusterMinPos = nCharPos; // extend cluster - else if( nCharPos <= nClusterMaxPos ) - /*NOTHING*/; // inside cluster - else if( bDiacritic ) - nClusterMaxPos = nCharPos; // add diacritic to cluster - else { - nClusterMinPos = nClusterMaxPos = nCharPos; // new cluster - bInCluster = false; - } - } - else - { - // right-to-left case - if( nClusterMaxPos < nCharPos ) - nClusterMaxPos = nCharPos; // extend cluster - else if( nCharPos >= nClusterMinPos ) - /*NOTHING*/; // inside cluster - else if( bDiacritic ) - { - nClusterMinPos = nCharPos; // ICU often has [diacritic* baseglyph*] - if( bClusterStart ) { - nClusterMaxPos = nCharPos; - bInCluster = false; - } - } - else - { - nClusterMinPos = nClusterMaxPos = nCharPos; // new cluster - bInCluster = !bClusterStart; - } - } - - long nGlyphFlags = 0; - if( bInCluster ) - nGlyphFlags |= GlyphItem::IS_IN_CLUSTER; - if( bRightToLeft ) - nGlyphFlags |= GlyphItem::IS_RTL_GLYPH; - if( bDiacritic ) - nGlyphFlags |= GlyphItem::IS_DIACRITIC; - - // add resulting glyph item to layout - GlyphItem aGI( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth ); -#ifdef ARABIC_BANDAID - aGI.mnNewWidth = nNewWidth; -#endif - - rLayout.AppendGlyph( aGI ); - ++nFilteredRunGlyphCount; - nLastCharPos = nCharPos; - bClusterStart = !aGI.IsDiacritic(); // TODO: only needed in RTL-codepath - } - aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) ); - nGlyphCount += nFilteredRunGlyphCount; - } - - // sort glyphs in visual order - // and then in logical order (e.g. diacritics after cluster start) - rLayout.SortGlyphItems(); - - // determine need for kashida justification - if( (rArgs.mpDXArray || rArgs.mnLayoutWidth) - && ((meScriptCode == arabScriptCode) || (meScriptCode == syrcScriptCode)) ) - rArgs.mnFlags |= SAL_LAYOUT_KASHIDA_JUSTIFICATON; - - return true; -} - -// ======================================================================= -ServerFontLayoutEngine* ServerFont::GetLayoutEngine(bool bUseHarfBuzz) +ServerFontLayoutEngine* ServerFont::GetLayoutEngine() { // find best layout engine for font, platform, script and language if (!mpLayoutEngine) { - if (bUseHarfBuzz) - mpLayoutEngine = new HbLayoutEngine(*this); - else - mpLayoutEngine = new IcuLayoutEngine(*this); + mpLayoutEngine = new HbLayoutEngine(*this); } return mpLayoutEngine; } |