Bug 412859. Some code to dump the contents of the textrun word cache. debug only. r=pavlov
authorroc+@cs.cmu.edu
Sun, 20 Jan 2008 17:23:50 -0800
changeset 10484 d17f36435df4bf15caa73faf67dd73bd5a2edf79
parent 10483 01c6f17849d73ab020ab0c92288686e1afd12957
child 10485 f5c8286b2966b1b27a5a6a868113369e67e4ff51
push idunknown
push userunknown
push dateunknown
reviewerspavlov
bugs412859
milestone1.9b3pre
Bug 412859. Some code to dump the contents of the textrun word cache. debug only. r=pavlov
gfx/thebes/public/gfxFont.h
gfx/thebes/src/gfxFont.cpp
gfx/thebes/src/gfxTextRunWordCache.cpp
--- a/gfx/thebes/public/gfxFont.h
+++ b/gfx/thebes/public/gfxFont.h
@@ -47,16 +47,20 @@
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "gfxSkipChars.h"
 #include "gfxRect.h"
 #include "nsExpirationTracker.h"
 #include "nsMathUtils.h"
 #include "nsBidiUtils.h"
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 class gfxContext;
 class gfxTextRun;
 class nsIAtom;
 class gfxFont;
 class gfxFontGroup;
 
 #define FONT_STYLE_NORMAL              0
 #define FONT_STYLE_ITALIC              1
@@ -1255,16 +1259,18 @@ public:
         
         PRPackedBool mPartIsStartOfLigature;
         PRPackedBool mPartIsEndOfLigature;
     };
 
 #ifdef DEBUG
     // number of entries referencing this textrun in the gfxTextRunWordCache
     PRUint32 mCachedWords;
+    
+    void Dump(FILE* aOutput);
 #endif
 
 protected:
     // Allocates extra space for the CompressedGlyph array and the text
     // (if needed)
     void *operator new(size_t aSize, PRUint32 aLength, PRUint32 aFlags);
 
     /**
--- a/gfx/thebes/src/gfxFont.cpp
+++ b/gfx/thebes/src/gfxFont.cpp
@@ -1974,8 +1974,41 @@ gfxTextRun::FetchGlyphExtents(gfxContext
 #endif
                         font->SetupGlyphExtents(aRefContext, glyphIndex, PR_TRUE, extents);
                     }
                 }
             }
         }
     }
 }
+
+#ifdef DEBUG
+void
+gfxTextRun::Dump(FILE* aOutput) {
+    if (!aOutput) {
+        aOutput = stdout;
+    }
+
+    PRUint32 i;
+    fputc('"', aOutput);
+    for (i = 0; i < mCharacterCount; ++i) {
+        PRUnichar ch = GetChar(i);
+        if (ch >= 32 && ch < 128) {
+            fputc(ch, aOutput);
+        } else {
+            fprintf(aOutput, "\\u%4x", ch);
+        }
+    }
+    fputs("\" [", aOutput);
+    for (i = 0; i < mGlyphRuns.Length(); ++i) {
+        if (i > 0) {
+            fputc(',', aOutput);
+        }
+        gfxFont* font = mGlyphRuns[i].mFont;
+        const gfxFontStyle* style = font->GetStyle();
+        NS_ConvertUTF16toUTF8 fontName(font->GetName());
+        fprintf(aOutput, "%d: %s %f/%d/%d/%s", mGlyphRuns[i].mCharacterOffset,
+                fontName.get(), style->size,
+                style->weight, style->style, style->langGroup.get());
+    }
+    fputc(']', aOutput);
+}
+#endif
--- a/gfx/thebes/src/gfxTextRunWordCache.cpp
+++ b/gfx/thebes/src/gfxTextRunWordCache.cpp
@@ -32,16 +32,20 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "gfxTextRunWordCache.h"
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 /**
  * Cache individual "words" (strings delimited by white-space or white-space-like
  * characters that don't involve kerning or ligatures) in textruns.
   */
 class TextRunWordCache {
 public:
     TextRunWordCache() {
         mCache.Init(100);
@@ -78,16 +82,20 @@ public:
                             PRUint32 aFlags);
 
     /**
      * Remove a textrun from the cache. This must be called before aTextRun
      * is deleted! The text in the textrun must still be valid.
      */
     void RemoveTextRun(gfxTextRun *aTextRun);
 
+#ifdef DEBUG
+    void Dump();
+#endif
+
 protected:
     struct CacheHashKey {
         void        *mFontOrGroup;
         const void  *mString;
         PRUint32     mLength;
         PRUint32     mAppUnitsPerDevUnit;
         PRUint32     mStringHash;
         PRPackedBool mIsDoubleByteText;
@@ -153,16 +161,20 @@ protected:
     void FinishTextRun(gfxTextRun *aTextRun, gfxTextRun *aNewRun,
                        gfxContext *aContext,
                        const nsTArray<DeferredWord>& aDeferredWords,
                        PRBool aSuccessful);
     void RemoveWord(gfxTextRun *aTextRun, PRUint32 aStart,
                     PRUint32 aEnd, PRUint32 aHash);    
 
     nsTHashtable<CacheHashEntry> mCache;
+    
+#ifdef DEBUG
+    static PLDHashOperator PR_CALLBACK CacheDumpEntry(CacheHashEntry* aEntry, void* userArg);
+#endif
 };
 
 static PRLogModuleInfo *gWordCacheLog = PR_NewLogModule("wordCache");
 
 static inline PRUint32
 HashMix(PRUint32 aHash, PRUnichar aCh)
 {
     return (aHash >> 28) ^ (aHash << 4) ^ aCh;
@@ -655,16 +667,38 @@ TextRunWordCache::CacheHashEntry::KeyEqu
 PLDHashNumber
 TextRunWordCache::CacheHashEntry::HashKey(const KeyTypePointer aKey)
 {
     return aKey->mStringHash + (long)aKey->mFontOrGroup + aKey->mAppUnitsPerDevUnit +
         aKey->mIsDoubleByteText + aKey->mIsRTL*2 + aKey->mEnabledOptionalLigatures*4 +
         aKey->mOptimizeSpeed*8;
 }
 
+#ifdef DEBUG
+PLDHashOperator PR_CALLBACK
+TextRunWordCache::CacheDumpEntry(CacheHashEntry* aEntry, void* userArg)
+{
+    FILE* output = static_cast<FILE*>(userArg);
+    if (!aEntry->mTextRun) {
+        fprintf(output, "<EMPTY>\n");
+        return PL_DHASH_NEXT;
+    }
+    fprintf(output, "Word at %x:%d => ", aEntry->mTextRun, aEntry->mWordOffset);
+    aEntry->mTextRun->Dump(output);
+    fprintf(output, " (hashed by %s)\n", aEntry->mHashedByFont ? "font" : "fontgroup");
+    return PL_DHASH_NEXT;
+}
+
+void
+TextRunWordCache::Dump()
+{
+    mCache.EnumerateEntries(CacheDumpEntry, stdout);
+}
+#endif
+
 static TextRunWordCache *gTextRunWordCache = nsnull;
 
 nsresult
 gfxTextRunWordCache::Init()
 {
     gTextRunWordCache = new TextRunWordCache();
     return gTextRunWordCache ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }