# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1284500380 -10800 # Node ID dd58c6eee052ceb963811e185a7956bed27ab986 # Parent 336bee5c2d357335f00cdda35fc106ecff282cea Revision: 201021 Kit: 201035 diff -r 336bee5c2d35 -r dd58c6eee052 fontservices/fontstore/inc/OPENFONT.H --- a/fontservices/fontstore/inc/OPENFONT.H Wed Sep 01 12:39:40 2010 +0100 +++ b/fontservices/fontstore/inc/OPENFONT.H Wed Sep 15 00:39:40 2010 +0300 @@ -327,7 +327,7 @@ TBool HasCharacterL(TInt aCode) const; TBool GetCharacterData(TInt aSessionHandle,TInt aCode,const TOpenFontCharMetrics*& aMetrics,const TUint8*& aBitmap) const; void OnFileDeleted(); - COpenFontGlyphCache* GetGlyphCache(); + COpenFontGlyphCache* GetGlyphCache() const; inline TInt FontCapitalAscent() const; inline TInt FontMaxAscent() const; inline TInt FontStandardDescent() const; @@ -368,7 +368,7 @@ private: const COpenFontGlyph* Glyph(TInt aSessionHandle,TInt aCode) const; - const COpenFontGlyph* FontCacheGlyph(TInt aCode); + const COpenFontGlyph* FontCacheGlyph(TInt aCode) const; void SetGlyphCache(COpenFontGlyphCache* aGlyphCache); diff -r 336bee5c2d35 -r dd58c6eee052 fontservices/fontstore/inc/openfontsprivate.h --- a/fontservices/fontstore/inc/openfontsprivate.h Wed Sep 01 12:39:40 2010 +0100 +++ b/fontservices/fontstore/inc/openfontsprivate.h Wed Sep 15 00:39:40 2010 +0300 @@ -133,8 +133,6 @@ private: inline COpenFontSessionCacheEntry(const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics); ~COpenFontSessionCacheEntry(); -public: - TInt iLastAccess; // serial number of the last access to the glyph private: TInt iFontOffset; // offset of the font that contains this glyph, (not owned by this class!) @@ -148,20 +146,21 @@ */ class COpenFontSessionCache { + friend class COpenFontSessionCacheList; public: static COpenFontSessionCache* NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries); void Delete(RHeap* aHeap); TInt SessionHandle() { return iSessionHandle; } - const COpenFontGlyph* Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex); + const COpenFontGlyph* Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) const; void Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex); private: COpenFontSessionCache(TInt aSessionHandle); ~COpenFontSessionCache(); -public: - TInt iSessionHandle; - TInt iLastAccess; +private: + TInt iSessionHandle; + TInt64 iRandomSeed; ROffsetArray iEntryArray; }; diff -r 336bee5c2d35 -r dd58c6eee052 fontservices/fontstore/src/OPENFONT.CPP --- a/fontservices/fontstore/src/OPENFONT.CPP Wed Sep 01 12:39:40 2010 +0100 +++ b/fontservices/fontstore/src/OPENFONT.CPP Wed Sep 15 00:39:40 2010 +0300 @@ -26,6 +26,7 @@ #include "linkedfontsprivate.h" #include #include +#include const TInt KSessionCacheEntries = 512; const TInt KDefaultSlantFactor = 20480; @@ -848,13 +849,13 @@ iFileOffset = 0; } -COpenFontGlyphCache* COpenFont::GetGlyphCache() +COpenFontGlyphCache* COpenFont::GetGlyphCache() const { if (iGlyphCacheOffset == 0) { return NULL; } - return reinterpret_cast(PtrAdd(this, iGlyphCacheOffset)); + return reinterpret_cast(PtrAdd(const_cast(this), iGlyphCacheOffset)); } const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const @@ -893,7 +894,7 @@ @param aCode The code for the glpyh to look for in the cache @return A pointer to the requested glyph if it was found in the glyph cache, NULL if it was not found. */ -const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode) +const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode) const { if (COpenFontGlyphCache* glyphCache = GetGlyphCache()) { @@ -1056,58 +1057,52 @@ iEntryArray.Close(aHeap); } -const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) +const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) const { aIndex = -1; - TInt oldest = KMaxTInt; - TInt oldest_index = 0; TInt numEntries = iEntryArray.Count(); TInt index = GLYPH_CODE(aCode) % numEntries; // simple hash function to shorten searches for (TInt i = 0; i < numEntries; ++i, ++index) { if (index >= numEntries) + { index = 0; - COpenFontSessionCacheEntry* entry = iEntryArray[index]; + } + const COpenFontSessionCacheEntry* entry = iEntryArray[index]; if (entry == NULL) { - if (aIndex == -1) - aIndex = index; - } - else - { - if (entry->Font() == aFont && entry->iCode == aCode) + if (aIndex < 0) { - entry->iLastAccess = iLastAccess++; - return entry; - } - if (entry->iLastAccess < oldest) - { - oldest = entry->iLastAccess; - oldest_index = index; + aIndex = index; } } + else if (entry->Font() == aFont && entry->iCode == aCode) + { + return entry; + } } - if (aIndex == -1) - aIndex = oldest_index; return NULL; } void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex) { - if (aIndex < 0 || aIndex >= iEntryArray.Count()) + if (aIndex >= iEntryArray.Count()) { Panic(EFntSessionCacheIndexOutOfRange); } + if (aIndex < 0) + { + aIndex = Math::Rand(iRandomSeed) % iEntryArray.Count(); + } COpenFontSessionCacheEntry::Delete(aHeap, iEntryArray[aIndex]); iEntryArray.SetAt(aIndex, aEntry); - aEntry->iLastAccess = iLastAccess++; } COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle): iSessionHandle(aSessionHandle), - iLastAccess(0) - { + iRandomSeed(0) + { } TInt COpenFontSessionCacheList::AddCache(COpenFontSessionCache* aCache) diff -r 336bee5c2d35 -r dd58c6eee052 textrendering/textformatting/tagma/TMGLYPH.CPP --- a/textrendering/textformatting/tagma/TMGLYPH.CPP Wed Sep 01 12:39:40 2010 +0100 +++ b/textrendering/textformatting/tagma/TMGLYPH.CPP Wed Sep 15 00:39:40 2010 +0300 @@ -170,7 +170,32 @@ cat == TChar::ERightToLeftArabic)) { iContextCharPerChunk = last; - break; + // Begin defect fixing for case ou1cimx1#475636. + // The defect: Popup panic 12 (ECharPosBeyondDocument) when display special Arabic + // text string. + // The direct reason: in function RTmGraphemeInTextChunkIterator::Next(), + // iFont->Font().GetCharacterPosition2() returns with + // iPosition.iPosInText equal to iPosition.iText.Length(), + // so that iPosition.iPosInText is an invalid document position. + // The root cause: When call GetCharacterPosition2(), FORM gives a text string, + // which contains characters to check, and the context characters. + // GetCharacterPosition2() handles the whole string from sub index + // 1 (given by FORM). But actually, each text string has two context + // characters, one leading and one trailing. That is to say, the + // trailing context character is incorrectly taken as normal text in + // GetCharacterPosition2(). It's fine normally, since + // GetCharacterPosition2() handles ONE glyph. Unfortunately, if the + // trailing context character is special, such as 0x644, + // GetCharacterPosition2() will try to composite 0x644 with the text + // character before it. If the composition success (like this defect), + // FORM will receive invalid document position. + // Solution: Never take 0x644 as context character. + if (iContextCharPerChunk == 0x644) + { + iContextCharPerChunk = 0x643; + } + // End defect fixing for case ou1cimx1#475636. + break; } textLength -= charSize; }