Revision: 201021 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 15 Sep 2010 00:39:40 +0300
branchRCL_3
changeset 18 dd58c6eee052
parent 17 336bee5c2d35
Revision: 201021 Kit: 201035
fontservices/fontstore/inc/OPENFONT.H
fontservices/fontstore/inc/openfontsprivate.h
fontservices/fontstore/src/OPENFONT.CPP
textrendering/textformatting/tagma/TMGLYPH.CPP
--- 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);
 	
--- 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<COpenFontSessionCacheEntry> iEntryArray;
     };
 
--- 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 <graphics/openfontrasterizer.h>
 #include <graphics/gdi/glyphsample.h>
+#include <e32math.h>
 
 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<COpenFontGlyphCache*>(PtrAdd(this, iGlyphCacheOffset));
+    return reinterpret_cast<COpenFontGlyphCache*>(PtrAdd(const_cast<COpenFont*>(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)
--- 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;
 		}