Bug 602792. Clean up font logs and add system fallback logging. r=bas, a=blocker
authorJohn Daggett <jdaggett@mozilla.com>
Sat, 22 Jan 2011 01:44:33 +0900
changeset 61084 3428fc1009fe85194867d91679a90116b1ad6ff9
parent 61083 ea3a3ca326ee7b1cf907a87afc98727a3557e592
child 61085 5c836d01b70a82e75e33fa538b7bc1cdb5fe8acb
push idunknown
push userunknown
push dateunknown
reviewersbas, blocker
bugs602792
milestone2.0b10pre
Bug 602792. Clean up font logs and add system fallback logging. r=bas, a=blocker
gfx/thebes/gfxCoreTextShaper.cpp
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxFontUtils.cpp
gfx/thebes/gfxGDIFontList.cpp
gfx/thebes/gfxMacPlatformFontList.mm
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPlatformFontList.cpp
gfx/thebes/gfxUniscribeShaper.cpp
--- a/gfx/thebes/gfxCoreTextShaper.cpp
+++ b/gfx/thebes/gfxCoreTextShaper.cpp
@@ -57,24 +57,16 @@
 #include "gfxFontUtils.h"
 
 #include "gfxQuartzSurface.h"
 #include "gfxMacPlatformFontList.h"
 #include "gfxUserFontSet.h"
 
 #include "nsUnicodeRange.h"
 
-// Uncomment this to dump all text runs created to the log (if enabled)
-//#define DUMP_TEXT_RUNS
-
-#ifdef DUMP_TEXT_RUNS
-static PRLogModuleInfo *gCoreTextTextRunLog = PR_NewLogModule("coreTextTextRun");
-#endif
-
-
 // standard font descriptors that we construct the first time they're needed
 CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = NULL;
 CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = NULL;
 
 gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
     : gfxFontShaper(aFont)
 {
     // Create our CTFontRef
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -46,20 +46,30 @@
 #include "nsIPrefBranch2.h"
 #include "nsServiceManagerUtils.h"
 
 #include "gfxGDIFontList.h"
 
 #include "nsIWindowsRegKey.h"
 
 #ifdef PR_LOGGING
-static PRLogModuleInfo *gFontInitLog = nsnull;
-#define LOG(args) PR_LOG(gFontInitLog, PR_LOG_DEBUG, args)
-#define LOG_ENABLED() (gFontInitLog) && PR_LOG_TEST(gFontInitLog, PR_LOG_DEBUG)
-#endif /* PR_LOGGING */
+
+#define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
+                               PR_LOG_DEBUG, args)
+#define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontlist), \
+                                   PR_LOG_DEBUG)
+
+#define LOG_FONTINIT(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontinit), \
+                               PR_LOG_DEBUG, args)
+#define LOG_FONTINIT_ENABLED() PR_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontinit), \
+                                   PR_LOG_DEBUG)
+
+#endif // PR_LOGGING
 
 // font info loader constants
 
 // avoid doing this during startup even on slow machines but try to start
 // it soon enough so that system fallback doesn't happen first
 static const PRUint32 kDelayBeforeLoadingFonts = 120 * 1000; // 2 minutes after init
 static const PRUint32 kIntervalBetweenLoadingFonts = 2000;   // every 2 seconds until complete
 
@@ -130,26 +140,38 @@ gfxDWriteFontFamily::FindStyleVariations
         }
 
         hr = names->GetString(englishIdx, faceName.Elements(), length + 1);
         if (FAILED(hr)) {
             continue;
         }
 
         nsString fullID(mName);
+        fullID.Append(NS_LITERAL_STRING(" "));
         fullID.Append(faceName.Elements());
 
         /**
          * Faces do not have a localized name so we just put the en-us name in
          * here.
          */
         gfxDWriteFontEntry *fe = 
             new gfxDWriteFontEntry(fullID, font);
         fe->SetFamily(this);
 
+#ifdef PR_LOGGING
+    if (LOG_FONTLIST_ENABLED()) {
+        LOG_FONTLIST(("(fontlist) added (%s) to family (%s)"
+             " with style: %s weight: %d stretch: %d",
+             NS_ConvertUTF16toUTF8(fe->Name()).get(),
+             NS_ConvertUTF16toUTF8(Name()).get(),
+             (fe->IsItalic()) ? "italic" : "normal",
+             fe->Weight(), fe->Stretch()));
+    }
+#endif
+
         mAvailableFonts.AppendElement(fe);
     }
     if (!mAvailableFonts.Length()) {
         NS_WARNING("Family with no font faces in it.");
     }
 
     if (mIsBadUnderlineFamily) {
         SetBadUnderlineFonts();
@@ -355,16 +377,21 @@ gfxDWriteFontEntry::ReadCMAP()
                                     len,
                                     mCharacterMap,
                                     mUVSOffset,
                                     isUnicode,
                                     isSymbol);
     }
     fontFace->ReleaseFontTable(tableContext);
 
+#ifdef PR_LOGGING
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+                  NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
+#endif
+
     mHasCmapTable = NS_SUCCEEDED(rv);
     return rv;
 }
 
 gfxFont *
 gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
                                        PRBool aNeedsBold)
 {
@@ -553,24 +580,22 @@ gfxDWriteFontList::MakePlatformFont(cons
     return entry;
 }
 
 nsresult
 gfxDWriteFontList::InitFontList()
 {
 
 #ifdef PR_LOGGING
-    gFontInitLog = PR_NewLogModule("fontinit");
-
     LARGE_INTEGER frequency;        // ticks per second
     LARGE_INTEGER t1, t2, t3, t4, t5, t6;           // ticks
     double elapsedTime, upTime;
     char nowTime[256], nowDate[256];
 
-    if (LOG_ENABLED()) {    
+    if (LOG_FONTINIT_ENABLED()) {    
         GetTimeFormat(LOCALE_INVARIANT, TIME_FORCE24HOURFORMAT, 
                       NULL, NULL, nowTime, 256);
         GetDateFormat(LOCALE_INVARIANT, NULL, NULL, NULL, nowDate, 256);
         upTime = (double) GetTickCount();
         QueryPerformanceFrequency(&frequency);
         QueryPerformanceCounter(&t1);
     }
 #endif
@@ -592,44 +617,44 @@ gfxDWriteFontList::InitFontList()
     }
 
     gfxPlatformFontList::InitFontList();
 
     mFontSubstitutes.Clear();
     mNonExistingFonts.Clear();
 
 #ifdef PR_LOGGING
-    if (LOG_ENABLED()) {
+    if (LOG_FONTINIT_ENABLED()) {
         QueryPerformanceCounter(&t2);
     }
 #endif
 
     nsRefPtr<IDWriteFontCollection> systemFonts;
     hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
         GetSystemFontCollection(getter_AddRefs(systemFonts));
     NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
 
     if (FAILED(hr)) {
         return NS_ERROR_FAILURE;
     }
 
 #ifdef PR_LOGGING
-    if (LOG_ENABLED()) {
+    if (LOG_FONTINIT_ENABLED()) {
         QueryPerformanceCounter(&t3);
     }
 #endif
 
     hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
         GetGdiInterop(getter_AddRefs(mGDIInterop));
     if (FAILED(hr)) {
         return NS_ERROR_FAILURE;
     }
 
 #ifdef PR_LOGGING
-    if (LOG_ENABLED()) {
+    if (LOG_FONTINIT_ENABLED()) {
         QueryPerformanceCounter(&t4);
     }
 #endif
 
     for (UINT32 i = 0; i < systemFonts->GetFontFamilyCount(); i++) {
         nsRefPtr<IDWriteFontFamily> family;
         systemFonts->GetFontFamily(i, getter_AddRefs(family));
 
@@ -731,39 +756,41 @@ gfxDWriteFontList::InitFontList()
     }
 
     mOtherFamilyNamesInitialized = PR_TRUE;
     GetFontSubstitutes();
 
     StartLoader(kDelayBeforeLoadingFonts, kIntervalBetweenLoadingFonts);
 
 #ifdef PR_LOGGING
-    if (LOG_ENABLED()) {
+    if (LOG_FONTINIT_ENABLED()) {
         QueryPerformanceCounter(&t5);
 
         // determine dwrite version
         nsAutoString dwriteVers;
         gfxWindowsPlatform::GetPlatform()->GetDLLVersion(L"dwrite.dll",
                                                          dwriteVers);
-        LOG(("InitFontList\n"));
-        LOG(("Start: %s %s\n", nowDate, nowTime));
-        LOG(("Uptime: %9.3f s\n", upTime/1000));
-        LOG(("dwrite version: %s\n", NS_ConvertUTF16toUTF8(dwriteVers).get()));
+        LOG_FONTINIT(("InitFontList\n"));
+        LOG_FONTINIT(("Start: %s %s\n", nowDate, nowTime));
+        LOG_FONTINIT(("Uptime: %9.3f s\n", upTime/1000));
+        LOG_FONTINIT(("dwrite version: %s\n", 
+                      NS_ConvertUTF16toUTF8(dwriteVers).get()));
         elapsedTime = (t5.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
-        LOG(("Total time in InitFontList:    %9.3f ms (families: %d, %s)\n", 
-          elapsedTime, systemFonts->GetFontFamilyCount(), 
+        LOG_FONTINIT((
+          "Total time in InitFontList:    %9.3f ms (families: %d, %s)\n",
+          elapsedTime, systemFonts->GetFontFamilyCount(),
           (mGDIFontTableAccess ? "gdi table access" : "dwrite table access")));
         elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
-        LOG((" --- gfxPlatformFontList init: %9.3f ms\n", elapsedTime));
+        LOG_FONTINIT((" --- gfxPlatformFontList init: %9.3f ms\n", elapsedTime));
         elapsedTime = (t3.QuadPart - t2.QuadPart) * 1000.0 / frequency.QuadPart;
-        LOG((" --- GetSystemFontCollection:  %9.3f ms\n", elapsedTime));
+        LOG_FONTINIT((" --- GetSystemFontCollection:  %9.3f ms\n", elapsedTime));
         elapsedTime = (t4.QuadPart - t3.QuadPart) * 1000.0 / frequency.QuadPart;
-        LOG((" --- GdiInterop object:        %9.3f ms\n", elapsedTime));
+        LOG_FONTINIT((" --- GdiInterop object:        %9.3f ms\n", elapsedTime));
         elapsedTime = (t5.QuadPart - t4.QuadPart) * 1000.0 / frequency.QuadPart;
-        LOG((" --- iterate over families:    %9.3f ms\n", elapsedTime));
+        LOG_FONTINIT((" --- iterate over families:    %9.3f ms\n", elapsedTime));
     }
 #endif
 
     return NS_OK;
 }
 
 static void
 RemoveCharsetFromFontSubstitute(nsAString &aName)
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -33,16 +33,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * 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 ***** */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include "nsIPrefService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsReadableUtils.h"
 #include "nsExpirationTracker.h"
 #include "nsILanguageAtomService.h"
 
 #include "gfxFont.h"
 #include "gfxPlatform.h"
@@ -67,18 +72,16 @@
 #include "harfbuzz/hb-blob.h"
 
 #include "nsCRT.h"
 
 using namespace mozilla;
 
 gfxFontCache *gfxFontCache::gGlobalCache = nsnull;
 
-static PRLogModuleInfo *gFontSelection = PR_NewLogModule("fontSelectionLog");
-
 #ifdef DEBUG_roc
 #define DEBUG_TEXT_RUN_STORAGE_METRICS
 #endif
 
 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
 static PRUint32 gTextRunStorageHighWaterMark = 0;
 static PRUint32 gTextRunStorage = 0;
 static PRUint32 gFontCount = 0;
@@ -461,21 +464,16 @@ gfxFontFamily::FindFontForStyle(const gf
             { kItalicFaceIndex, kBoldFaceIndex, kRegularFaceIndex }       // BoldItalic
         };
         const PRUint8 *order = simpleFallbacks[faceIndex];
 
         for (PRUint8 trial = 0; trial < 3; ++trial) {
             // check remaining faces in order of preference to find the first that actually exists
             fe = mAvailableFonts[order[trial]];
             if (fe) {
-                PR_LOG(gFontSelection, PR_LOG_DEBUG,
-                       ("(FindFontForStyle) name: %s, sty: %02x, wt: %d, sz: %.1f -> %s (trial %d)\n", 
-                        NS_ConvertUTF16toUTF8(mName).get(),
-                        aFontStyle.style, aFontStyle.weight, aFontStyle.size,
-                        NS_ConvertUTF16toUTF8(fe->Name()).get(), trial));
                 aNeedsSyntheticBold = wantBold && !fe->IsBold();
                 return fe;
             }
         }
 
         // this can't happen unless we have totally broken the font-list manager!
         NS_NOTREACHED("no face found in simple font family!");
         return nsnull;
@@ -484,20 +482,16 @@ gfxFontFamily::FindFontForStyle(const gf
     // This is a large/rich font family, so we do full style- and weight-matching:
     // first collect a list of weights that are the best match for the requested
     // font-stretch and font-style, then pick the best weight match among those
     // available.
 
     gfxFontEntry *weightList[10] = { 0 };
     PRBool foundWeights = FindWeightsForStyle(weightList, wantItalic, aFontStyle.stretch);
     if (!foundWeights) {
-        PR_LOG(gFontSelection, PR_LOG_DEBUG,
-               ("(FindFontForStyle) name: %s, sty: %02x, wt: %d, sz: %.1f -> null\n", 
-                NS_ConvertUTF16toUTF8(mName).get(),
-                aFontStyle.style, aFontStyle.weight, aFontStyle.size));
         return nsnull;
     }
 
     // First find a match for the best weight
     PRInt8 matchBaseWeight = 0;
     PRInt8 i = baseWeight;
 
     // Need to special case when normal face doesn't exist but medium does.
@@ -530,21 +524,16 @@ gfxFontFamily::FindFontForStyle(const gf
     NS_ASSERTION(matchFE,
                  "weight mapping should always find at least one font in a family");
 
     if (!matchFE->IsBold() && baseWeight >= 6)
     {
         aNeedsSyntheticBold = PR_TRUE;
     }
 
-    PR_LOG(gFontSelection, PR_LOG_DEBUG,
-           ("(FindFontForStyle) name: %s, sty: %02x, wt: %d, sz: %.1f -> %s\n", 
-            NS_ConvertUTF16toUTF8(mName).get(),
-            aFontStyle.style, aFontStyle.weight, aFontStyle.size,
-            NS_ConvertUTF16toUTF8(matchFE->Name()).get()));
     return matchFE;
 }
 
 void
 gfxFontFamily::CheckForSimpleFamily()
 {
     if (mAvailableFonts.Length() > 4 || mAvailableFonts.Length() == 0) {
         return; // can't be "simple" if there are >4 faces;
@@ -672,16 +661,32 @@ gfxFontFamily::FindFontForChar(FontSearc
         // skip certain fonts during system fallback
         if (!fe || fe->SkipDuringSystemFallback())
             continue;
 
         PRInt32 rank = 0;
 
         if (fe->TestCharacterMap(aMatchData->mCh)) {
             rank += 20;
+            aMatchData->mCount++;
+#ifdef PR_LOGGING
+            PRLogModuleInfo *log = gfxPlatform::GetLog(eGfxLog_textrun);
+        
+            if (NS_UNLIKELY(log)) {
+                PRUint32 charRange = gfxFontUtils::CharRangeBit(aMatchData->mCh);
+                PRUint32 unicodeRange = FindCharUnicodeRange(aMatchData->mCh);
+                PRUint32 hbscript = gfxUnicodeProperties::GetScriptCode(aMatchData->mCh);
+                PR_LOG(log, PR_LOG_DEBUG,\
+                       ("(textrun-systemfallback-fonts) char: u+%6.6x "
+                        "char-range: %d unicode-range: %d script: %d match: [%s]\n",
+                        aMatchData->mCh,
+                        charRange, unicodeRange, hbscript,
+                        NS_ConvertUTF16toUTF8(fe->Name()).get()));
+            }
+#endif
         }
 
         // if we didn't match any characters don't bother wasting more time with this face.
         if (rank == 0)
             continue;
             
         // omitting from original windows code -- family name, lang group, pitch
         // not available in current FontEntry implementation
@@ -1439,16 +1444,34 @@ gfxFont::SplitAndInitTextRun(gfxContext 
                              gfxTextRun *aTextRun,
                              const PRUnichar *aString,
                              PRUint32 aRunStart,
                              PRUint32 aRunLength,
                              PRInt32 aRunScript)
 {
     PRBool ok;
 
+#ifdef PR_LOGGING
+    PRLogModuleInfo *log = (mStyle.systemFont ?
+                            gfxPlatform::GetLog(eGfxLog_textrunui) :
+                            gfxPlatform::GetLog(eGfxLog_textrun));
+
+    if (NS_UNLIKELY(log)) {
+        nsCAutoString lang;
+        mStyle.language->ToUTF8String(lang);
+        PR_LOG(log, PR_LOG_DEBUG,\
+               ("(%s-fontmatching) font: [%s] lang: %s script: %d len: %d "
+                "TEXTRUN [%s] ENDTEXTRUN\n",
+                (mStyle.systemFont ? "textrunui" : "textrun"),
+                NS_ConvertUTF16toUTF8(GetName()).get(),
+                lang.get(), aRunScript, aRunLength,
+                NS_ConvertUTF16toUTF8(aString + aRunStart, aRunLength).get()));
+    }
+#endif
+
     do {
         // Because various shaping backends struggle with very long runs,
         // we look for appropriate break locations (preferring whitespace),
         // and shape sub-runs of no more than 32K characters at a time.
         // See bug 606714 (CoreText), and similar Uniscribe issues.
         // This loop always executes at least once, and "processes" up to
         // MAX_RUN_LENGTH_FOR_SHAPING characters, updating aRunStart and
         // aRunLength accordingly. It terminates when the entire run has
@@ -2380,19 +2403,46 @@ gfxFontGroup::InitTextRun(gfxContext *aC
                           gfxTextRun *aTextRun,
                           const PRUnichar *aString,
                           PRUint32 aLength)
 {
     // split into script runs so that script can potentially influence
     // the font matching process below
     gfxScriptItemizer scriptRuns(aString, aLength);
 
+#ifdef PR_LOGGING
+    PRLogModuleInfo *log = (mStyle.systemFont ?
+                            gfxPlatform::GetLog(eGfxLog_textrunui) :
+                            gfxPlatform::GetLog(eGfxLog_textrun));
+#endif
+
     PRUint32 runStart = 0, runLimit = aLength;
     PRInt32 runScript = HB_SCRIPT_LATIN;
     while (scriptRuns.Next(runStart, runLimit, runScript)) {
+
+#ifdef PR_LOGGING
+        if (NS_UNLIKELY(log)) {
+            nsCAutoString lang;
+            mStyle.language->ToUTF8String(lang);
+            PRUint32 runLen = runLimit - runStart;
+            PR_LOG(log, PR_LOG_DEBUG,\
+                   ("(%s) fontgroup: [%s] lang: %s script: %d len %d "
+                    "weight: %d width: %d style: %s "
+                    "TEXTRUN [%s] ENDTEXTRUN\n",
+                    (mStyle.systemFont ? "textrunui" : "textrun"),
+                    NS_ConvertUTF16toUTF8(mFamilies).get(),
+                    lang.get(), runScript, runLen,
+                    PRUint32(mStyle.weight), PRUint32(mStyle.stretch),
+                    (mStyle.style & FONT_STYLE_ITALIC ? "italic" :
+                    (mStyle.style & FONT_STYLE_OBLIQUE ? "oblique" :
+                                                            "normal")),
+                    NS_ConvertUTF16toUTF8(aString + runStart, runLen).get()));
+        }
+#endif
+
         InitScriptRun(aContext, aTextRun, aString, aLength,
                       runStart, runLimit, runScript);
     }
 
     aTextRun->SortGlyphRuns();
 }
 
 void
@@ -2449,28 +2499,16 @@ gfxFontGroup::InitScriptRun(gfxContext *
     }
 
     // It's possible for CoreText to omit glyph runs if it decides they contain
     // only invisibles (e.g., U+FEFF, see reftest 474417-1). In this case, we
     // need to eliminate them from the glyph run array to avoid drawing "partial
     // ligatures" with the wrong font.
     aTextRun->SanitizeGlyphRuns();
 
-#ifdef DUMP_TEXT_RUNS
-    nsCAutoString lang;
-    style->language->ToUTF8String(lang);
-    PR_LOG(gFontSelection, PR_LOG_DEBUG,\
-           ("InitTextRun %p fontgroup %p (%s) lang: %s len %d features: %s "
-            "TEXTRUN \"%s\" ENDTEXTRUN\n",
-            aTextRun, this,
-            NS_ConvertUTF16toUTF8(mFamilies).get(),
-            lang.get(), aLength,
-            NS_ConvertUTF16toUTF8(mStyle.featureSettings).get(),
-            NS_ConvertUTF16toUTF8(aString, aLength).get()) );
-#endif
 }
 
 
 already_AddRefed<gfxFont>
 gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
                               PRInt32 aRunScript, gfxFont *aPrevMatchedFont)
 {
     nsRefPtr<gfxFont>    selectedFont;
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -455,22 +455,23 @@ private:
     gfxFontEntry(const gfxFontEntry&);
     gfxFontEntry& operator=(const gfxFontEntry&);
 };
 
 
 // used when picking fallback font
 struct FontSearch {
     FontSearch(const PRUint32 aCharacter, gfxFont *aFont) :
-        mCh(aCharacter), mFontToMatch(aFont), mMatchRank(0) {
+        mCh(aCharacter), mFontToMatch(aFont), mMatchRank(0), mCount(0) {
     }
     const PRUint32         mCh;
     gfxFont*               mFontToMatch;
     PRInt32                mMatchRank;
     nsRefPtr<gfxFontEntry> mBestMatch;
+    PRUint32               mCount;
 };
 
 class gfxFontFamily {
 public:
     NS_INLINE_DECL_REFCOUNTING(gfxFontFamily)
 
     gfxFontFamily(const nsAString& aName) :
         mName(aName),
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -60,52 +60,54 @@
 
 #define NO_RANGE_FOUND 126 // bit 126 in the font unicode ranges is required to be 0
 
 #define UNICODE_BMP_LIMIT 0x10000
 
 using namespace mozilla; // for the AutoSwap_* types
 
 /* Unicode subrange table
- *   from: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_63ub.asp
+ *   from: http://msdn.microsoft.com/en-us/library/dd374090
  *
- * Use something like:
- * perl -pi -e 's/^(\d+)\s+([\dA-Fa-f]+)\s+-\s+([\dA-Fa-f]+)\s+\b(.*)/    { \1, 0x\2, 0x\3,\"\4\" },/' < unicoderanges.txt
+ * Edit the text to extend the initial digit, then use something like:
+ * perl -pi -e 's/^(\d+)\t([\dA-Fa-f]+)\s+-\s+([\dA-Fa-f]+)\s+\b([a-zA-Z0-9\(\)\- ]+)/    { \1, 0x\2, 0x\3, \"\4\" },/' < unicoderange.txt
  * to generate the below list.
  */
 struct UnicodeRangeTableEntry
 {
     PRUint8 bit;
     PRUint32 start;
     PRUint32 end;
     const char *info;
 };
 
-static const struct UnicodeRangeTableEntry gUnicodeRanges[] = {
+static struct UnicodeRangeTableEntry gUnicodeRanges[] = {
     { 0, 0x0000, 0x007F, "Basic Latin" },
     { 1, 0x0080, 0x00FF, "Latin-1 Supplement" },
     { 2, 0x0100, 0x017F, "Latin Extended-A" },
     { 3, 0x0180, 0x024F, "Latin Extended-B" },
     { 4, 0x0250, 0x02AF, "IPA Extensions" },
     { 4, 0x1D00, 0x1D7F, "Phonetic Extensions" },
     { 4, 0x1D80, 0x1DBF, "Phonetic Extensions Supplement" },
     { 5, 0x02B0, 0x02FF, "Spacing Modifier Letters" },
     { 5, 0xA700, 0xA71F, "Modifier Tone Letters" },
-    { 6, 0x0300, 0x036F, "Spacing Modifier Letters" },
+    { 6, 0x0300, 0x036F, "Combining Diacritical Marks" },
     { 6, 0x1DC0, 0x1DFF, "Combining Diacritical Marks Supplement" },
     { 7, 0x0370, 0x03FF, "Greek and Coptic" },
     { 8, 0x2C80, 0x2CFF, "Coptic" },
     { 9, 0x0400, 0x04FF, "Cyrillic" },
-    { 9, 0x0500, 0x052F, "Cyrillic Supplementary" },
+    { 9, 0x0500, 0x052F, "Cyrillic Supplement" },
+    { 9, 0x2DE0, 0x2DFF, "Cyrillic Extended-A" },
+    { 9, 0xA640, 0xA69F, "Cyrillic Extended-B" },
     { 10, 0x0530, 0x058F, "Armenian" },
-    { 11, 0x0590, 0x05FF, "Basic Hebrew" },
-    /* 12 - reserved */
-    { 13, 0x0600, 0x06FF, "Basic Arabic" },
+    { 11, 0x0590, 0x05FF, "Hebrew" },
+    { 12, 0xA500, 0xA63F, "Vai" },
+    { 13, 0x0600, 0x06FF, "Arabic" },
     { 13, 0x0750, 0x077F, "Arabic Supplement" },
-    { 14, 0x07C0, 0x07FF, "N'Ko" },
+    { 14, 0x07C0, 0x07FF, "NKo" },
     { 15, 0x0900, 0x097F, "Devanagari" },
     { 16, 0x0980, 0x09FF, "Bengali" },
     { 17, 0x0A00, 0x0A7F, "Gurmukhi" },
     { 18, 0x0A80, 0x0AFF, "Gujarati" },
     { 19, 0x0B00, 0x0B7F, "Oriya" },
     { 20, 0x0B80, 0x0BFF, "Tamil" },
     { 21, 0x0C00, 0x0C7F, "Telugu" },
     { 22, 0x0C80, 0x0CFF, "Kannada" },
@@ -113,23 +115,24 @@ static const struct UnicodeRangeTableEnt
     { 24, 0x0E00, 0x0E7F, "Thai" },
     { 25, 0x0E80, 0x0EFF, "Lao" },
     { 26, 0x10A0, 0x10FF, "Georgian" },
     { 26, 0x2D00, 0x2D2F, "Georgian Supplement" },
     { 27, 0x1B00, 0x1B7F, "Balinese" },
     { 28, 0x1100, 0x11FF, "Hangul Jamo" },
     { 29, 0x1E00, 0x1EFF, "Latin Extended Additional" },
     { 29, 0x2C60, 0x2C7F, "Latin Extended-C" },
+    { 29, 0xA720, 0xA7FF, "Latin Extended-D" },
     { 30, 0x1F00, 0x1FFF, "Greek Extended" },
     { 31, 0x2000, 0x206F, "General Punctuation" },
     { 31, 0x2E00, 0x2E7F, "Supplemental Punctuation" },
-    { 32, 0x2070, 0x209F, "Subscripts and Superscripts" },
+    { 32, 0x2070, 0x209F, "Superscripts And Subscripts" },
     { 33, 0x20A0, 0x20CF, "Currency Symbols" },
-    { 34, 0x20D0, 0x20FF, "Combining Diacritical Marks for Symbols" },
-    { 35, 0x2100, 0x214F, "Letter-like Symbols" },
+    { 34, 0x20D0, 0x20FF, "Combining Diacritical Marks For Symbols" },
+    { 35, 0x2100, 0x214F, "Letterlike Symbols" },
     { 36, 0x2150, 0x218F, "Number Forms" },
     { 37, 0x2190, 0x21FF, "Arrows" },
     { 37, 0x27F0, 0x27FF, "Supplemental Arrows-A" },
     { 37, 0x2900, 0x297F, "Supplemental Arrows-B" },
     { 37, 0x2B00, 0x2BFF, "Miscellaneous Symbols and Arrows" },
     { 38, 0x2200, 0x22FF, "Mathematical Operators" },
     { 38, 0x27C0, 0x27EF, "Miscellaneous Mathematical Symbols-A" },
     { 38, 0x2980, 0x29FF, "Miscellaneous Mathematical Symbols-B" },
@@ -138,105 +141,119 @@ static const struct UnicodeRangeTableEnt
     { 40, 0x2400, 0x243F, "Control Pictures" },
     { 41, 0x2440, 0x245F, "Optical Character Recognition" },
     { 42, 0x2460, 0x24FF, "Enclosed Alphanumerics" },
     { 43, 0x2500, 0x257F, "Box Drawing" },
     { 44, 0x2580, 0x259F, "Block Elements" },
     { 45, 0x25A0, 0x25FF, "Geometric Shapes" },
     { 46, 0x2600, 0x26FF, "Miscellaneous Symbols" },
     { 47, 0x2700, 0x27BF, "Dingbats" },
-    { 48, 0x3000, 0x303F, "Chinese, Japanese, and Korean (CJK) Symbols and Punctuation" },
+    { 48, 0x3000, 0x303F, "CJK Symbols And Punctuation" },
     { 49, 0x3040, 0x309F, "Hiragana" },
     { 50, 0x30A0, 0x30FF, "Katakana" },
     { 50, 0x31F0, 0x31FF, "Katakana Phonetic Extensions" },
     { 51, 0x3100, 0x312F, "Bopomofo" },
-    { 51, 0x31A0, 0x31BF, "Extended Bopomofo" },
+    { 50, 0x31A0, 0x31BF, "Bopomofo Extended" },
     { 52, 0x3130, 0x318F, "Hangul Compatibility Jamo" },
     { 53, 0xA840, 0xA87F, "Phags-pa" },
-    { 54, 0x3200, 0x32FF, "Enclosed CJK Letters and Months" },
+    { 54, 0x3200, 0x32FF, "Enclosed CJK Letters And Months" },
     { 55, 0x3300, 0x33FF, "CJK Compatibility" },
-    { 56, 0xAC00, 0xD7A3, "Hangul" },
-    { 57, 0xD800, 0xDFFF, "Surrogates. Note that setting this bit implies that there is at least one supplementary code point beyond the Basic Multilingual Plane (BMP) that is supported by this font. See Surrogates and Supplementary Characters." },
+    { 56, 0xAC00, 0xD7AF, "Hangul Syllables" },
+    { 57, 0xD800, 0xDFFF, "Non-Plane 0" },
     { 58, 0x10900, 0x1091F, "Phoenician" },
     { 59, 0x2E80, 0x2EFF, "CJK Radicals Supplement" },
     { 59, 0x2F00, 0x2FDF, "Kangxi Radicals" },
     { 59, 0x2FF0, 0x2FFF, "Ideographic Description Characters" },
     { 59, 0x3190, 0x319F, "Kanbun" },
     { 59, 0x3400, 0x4DBF, "CJK Unified Ideographs Extension A" },
     { 59, 0x4E00, 0x9FFF, "CJK Unified Ideographs" },
     { 59, 0x20000, 0x2A6DF, "CJK Unified Ideographs Extension B" },
-    { 60, 0xE000, 0xF8FF, "Private Use (Plane 0)" },
-    { 61, 0x31C0, 0x31EF, "CJK Base Strokes" },
+    { 60, 0xE000, 0xF8FF, "Private Use Area" },
+    { 61, 0x31C0, 0x31EF, "CJK Strokes" },
     { 61, 0xF900, 0xFAFF, "CJK Compatibility Ideographs" },
     { 61, 0x2F800, 0x2FA1F, "CJK Compatibility Ideographs Supplement" },
-    { 62, 0xFB00, 0xFB4F, "Alphabetical Presentation Forms" },
+    { 62, 0xFB00, 0xFB4F, "Alphabetic Presentation Forms" },
     { 63, 0xFB50, 0xFDFF, "Arabic Presentation Forms-A" },
     { 64, 0xFE20, 0xFE2F, "Combining Half Marks" },
     { 65, 0xFE10, 0xFE1F, "Vertical Forms" },
     { 65, 0xFE30, 0xFE4F, "CJK Compatibility Forms" },
     { 66, 0xFE50, 0xFE6F, "Small Form Variants" },
-    { 67, 0xFE70, 0xFEFE, "Arabic Presentation Forms-B" },
-    { 68, 0xFF00, 0xFFEF, "Halfwidth and Fullwidth Forms" },
+    { 67, 0xFE70, 0xFEFF, "Arabic Presentation Forms-B" },
+    { 68, 0xFF00, 0xFFEF, "Halfwidth And Fullwidth Forms" },
     { 69, 0xFFF0, 0xFFFF, "Specials" },
     { 70, 0x0F00, 0x0FFF, "Tibetan" },
     { 71, 0x0700, 0x074F, "Syriac" },
     { 72, 0x0780, 0x07BF, "Thaana" },
     { 73, 0x0D80, 0x0DFF, "Sinhala" },
     { 74, 0x1000, 0x109F, "Myanmar" },
     { 75, 0x1200, 0x137F, "Ethiopic" },
     { 75, 0x1380, 0x139F, "Ethiopic Supplement" },
     { 75, 0x2D80, 0x2DDF, "Ethiopic Extended" },
     { 76, 0x13A0, 0x13FF, "Cherokee" },
-    { 77, 0x1400, 0x167F, "Canadian Aboriginal Syllabics" },
+    { 77, 0x1400, 0x167F, "Unified Canadian Aboriginal Syllabics" },
     { 78, 0x1680, 0x169F, "Ogham" },
     { 79, 0x16A0, 0x16FF, "Runic" },
     { 80, 0x1780, 0x17FF, "Khmer" },
     { 80, 0x19E0, 0x19FF, "Khmer Symbols" },
     { 81, 0x1800, 0x18AF, "Mongolian" },
-    { 82, 0x2800, 0x28FF, "Braille" },
-    { 83, 0xA000, 0xA48F, "Yi" },
+    { 82, 0x2800, 0x28FF, "Braille Patterns" },
+    { 83, 0xA000, 0xA48F, "Yi Syllables" },
     { 83, 0xA490, 0xA4CF, "Yi Radicals" },
     { 84, 0x1700, 0x171F, "Tagalog" },
     { 84, 0x1720, 0x173F, "Hanunoo" },
     { 84, 0x1740, 0x175F, "Buhid" },
     { 84, 0x1760, 0x177F, "Tagbanwa" },
     { 85, 0x10300, 0x1032F, "Old Italic" },
     { 86, 0x10330, 0x1034F, "Gothic" },
-    { 87, 0x10440, 0x1044F, "Deseret" },
+    { 87, 0x10400, 0x1044F, "Deseret" },
     { 88, 0x1D000, 0x1D0FF, "Byzantine Musical Symbols" },
     { 88, 0x1D100, 0x1D1FF, "Musical Symbols" },
     { 88, 0x1D200, 0x1D24F, "Ancient Greek Musical Notation" },
     { 89, 0x1D400, 0x1D7FF, "Mathematical Alphanumeric Symbols" },
-    { 90, 0xFF000, 0xFFFFD, "Private Use (Plane 15)" },
-    { 90, 0x100000, 0x10FFFD, "Private Use (Plane 16)" },
+    { 90, 0xFF000, 0xFFFFD, "Private Use (plane 15)" },
+    { 90, 0x100000, 0x10FFFD, "Private Use (plane 16)" },
     { 91, 0xFE00, 0xFE0F, "Variation Selectors" },
     { 91, 0xE0100, 0xE01EF, "Variation Selectors Supplement" },
     { 92, 0xE0000, 0xE007F, "Tags" },
     { 93, 0x1900, 0x194F, "Limbu" },
     { 94, 0x1950, 0x197F, "Tai Le" },
     { 95, 0x1980, 0x19DF, "New Tai Lue" },
     { 96, 0x1A00, 0x1A1F, "Buginese" },
     { 97, 0x2C00, 0x2C5F, "Glagolitic" },
-    { 98, 0x2D40, 0x2D7F, "Tifinagh" },
+    { 98, 0x2D30, 0x2D7F, "Tifinagh" },
     { 99, 0x4DC0, 0x4DFF, "Yijing Hexagram Symbols" },
     { 100, 0xA800, 0xA82F, "Syloti Nagri" },
     { 101, 0x10000, 0x1007F, "Linear B Syllabary" },
     { 101, 0x10080, 0x100FF, "Linear B Ideograms" },
     { 101, 0x10100, 0x1013F, "Aegean Numbers" },
     { 102, 0x10140, 0x1018F, "Ancient Greek Numbers" },
     { 103, 0x10380, 0x1039F, "Ugaritic" },
     { 104, 0x103A0, 0x103DF, "Old Persian" },
     { 105, 0x10450, 0x1047F, "Shavian" },
     { 106, 0x10480, 0x104AF, "Osmanya" },
     { 107, 0x10800, 0x1083F, "Cypriot Syllabary" },
     { 108, 0x10A00, 0x10A5F, "Kharoshthi" },
     { 109, 0x1D300, 0x1D35F, "Tai Xuan Jing Symbols" },
     { 110, 0x12000, 0x123FF, "Cuneiform" },
     { 110, 0x12400, 0x1247F, "Cuneiform Numbers and Punctuation" },
-    { 111, 0x1D360, 0x1D37F, "Counting Rod Numerals" }
+    { 111, 0x1D360, 0x1D37F, "Counting Rod Numerals" },
+    { 112, 0x1B80, 0x1BBF, "Sundanese" },
+    { 113, 0x1C00, 0x1C4F, "Lepcha" },
+    { 114, 0x1C50, 0x1C7F, "Ol Chiki" },
+    { 115, 0xA880, 0xA8DF, "Saurashtra" },
+    { 116, 0xA900, 0xA92F, "Kayah Li" },
+    { 117, 0xA930, 0xA95F, "Rejang" },
+    { 118, 0xAA00, 0xAA5F, "Cham" },
+    { 119, 0x10190, 0x101CF, "Ancient Symbols" },
+    { 120, 0x101D0, 0x101FF, "Phaistos Disc" },
+    { 121, 0x10280, 0x1029F, "Lycian" },
+    { 121, 0x102A0, 0x102DF, "Carian" },
+    { 121, 0x10920, 0x1093F, "Lydian" },
+    { 122, 0x1F000, 0x1F02F, "Mahjong Tiles" },
+    { 122, 0x1F030, 0x1F09F, "Domino Tiles" }
 };
 
 #pragma pack(1)
 
 typedef struct {
     AutoSwap_PRUint16 format;
     AutoSwap_PRUint16 reserved;
     AutoSwap_PRUint32 length;
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -34,16 +34,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * 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 ***** */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include "gfxGDIFontList.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxUserFontSet.h"
 #include "gfxFontUtils.h"
 #include "gfxGDIFont.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
@@ -60,21 +65,23 @@
 #define ROUND(x) floor((x) + 0.5)
 
 
 #ifndef CLEARTYPE_QUALITY
 #define CLEARTYPE_QUALITY 5
 #endif
 
 #ifdef PR_LOGGING
-static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog");
-#endif /* PR_LOGGING */
+#define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
+                               PR_LOG_DEBUG, args)
+#define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontlist), \
+                                   PR_LOG_DEBUG)
 
-#define LOG(args) PR_LOG(gFontInfoLog, PR_LOG_DEBUG, args)
-#define LOG_ENABLED() PR_LOG_TEST(gFontInfoLog, PR_LOG_DEBUG)
+#endif // PR_LOGGING
 
 // font info loader constants
 
 // avoid doing this during startup even on slow machines but try to start
 // it soon enough so that system fallback doesn't happen first
 static const PRUint32 kDelayBeforeLoadingFonts = 120 * 1000; // 2 minutes after init
 static const PRUint32 kIntervalBetweenLoadingFonts = 2000;   // every 2 seconds until complete
 
@@ -246,18 +253,20 @@ GDIFontEntry::ReadCMAP()
     PRPackedBool  unicodeFont = PR_FALSE, symbolFont = PR_FALSE;
     nsresult rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
                                          mCharacterMap, mUVSOffset,
                                          unicodeFont, symbolFont);
     mUnicodeFont = unicodeFont;
     mSymbolFont = symbolFont;
     mHasCmapTable = NS_SUCCEEDED(rv);
 
-    PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n", 
-                                        NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
+#ifdef PR_LOGGING
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+                  NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
+#endif
     return rv;
 }
 
 gfxFont *
 GDIFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, PRBool aNeedsBold)
 {
     PRBool isXP = (gfxWindowsPlatform::WindowsOSVersion() 
                        < gfxWindowsPlatform::kWindowsVista);
@@ -523,18 +532,18 @@ GDIFontFamily::FamilyAddStylesProc(const
             DWORD range = nmetrics->ntmFontSig.fsUsb[i];
             for (PRUint32 k = 0; k < 32; ++k) {
                 fe->mUnicodeRanges.set(x++, (range & (1 << k)) != 0);
             }
         }
     }
 
 #ifdef PR_LOGGING
-    if (LOG_ENABLED()) {
-        LOG(("(fontinit) added (%s) to family (%s)"
+    if (LOG_FONTLIST_ENABLED()) {
+        LOG_FONTLIST(("(fontlist) added (%s) to family (%s)"
              " with style: %s weight: %d stretch: %d",
              NS_ConvertUTF16toUTF8(fe->Name()).get(), 
              NS_ConvertUTF16toUTF8(ff->Name()).get(), 
              (logFont.lfItalic == 0xff) ? "italic" : "normal",
              logFont.lfWeight, fe->Stretch()));
     }
 #endif
     return 1;
@@ -559,18 +568,19 @@ GDIFontFamily::FindStyleVariations()
            nsPromiseFlatString(mName).get(),
            l * sizeof(PRUnichar));
     logFont.lfFaceName[l] = 0;
 
     EnumFontFamiliesExW(hdc, &logFont,
                         (FONTENUMPROCW)GDIFontFamily::FamilyAddStylesProc,
                         (LPARAM)this, 0);
 #ifdef PR_LOGGING
-    if (LOG_ENABLED() && mAvailableFonts.Length() == 0) {
-        LOG(("no styles available in family \"%s\"", NS_ConvertUTF16toUTF8(mName).get()));
+    if (LOG_FONTLIST_ENABLED() && mAvailableFonts.Length() == 0) {
+        LOG_FONTLIST(("(fontlist) no styles available in family \"%s\"",
+                      NS_ConvertUTF16toUTF8(mName).get()));
     }
 #endif
 
     ReleaseDC(nsnull, hdc);
 
     if (mIsBadUnderlineFamily)
         SetBadUnderlineFonts();
 }
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -33,16 +33,21 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include <Carbon/Carbon.h>
 
 #import <AppKit/AppKit.h>
 
 #include "gfxPlatformMac.h"
 #include "gfxMacPlatformFontList.h"
 #include "gfxMacFont.h"
 #include "gfxUserFontSet.h"
@@ -116,21 +121,24 @@ static void GetStringForNSString(const N
 
 static NSString* GetNSStringForString(const nsAString& aSrc)
 {
     return [NSString stringWithCharacters:aSrc.BeginReading()
                      length:aSrc.Length()];
 }
 
 #ifdef PR_LOGGING
-static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog");
-#endif /* PR_LOGGING */
 
-#define LOG(args) PR_LOG(gFontInfoLog, PR_LOG_DEBUG, args)
-#define LOG_ENABLED() PR_LOG_TEST(gFontInfoLog, PR_LOG_DEBUG)
+#define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
+                               PR_LOG_DEBUG, args)
+#define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontlist), \
+                                   PR_LOG_DEBUG)
+
+#endif // PR_LOGGING
 
 /* MacOSFontEntry */
 #pragma mark-
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
                                PRInt32 aWeight,
                                gfxFontFamily *aFamily,
                                PRBool aIsStandardFace)
@@ -282,19 +290,21 @@ MacOSFontEntry::ReadCMAP()
 
             if (omitRange) {
                 mCharacterMap.ClearRange(gScriptsThatRequireShaping[s].rangeStart,
                                          gScriptsThatRequireShaping[s].rangeEnd);
             }
         }
     }
 
-    PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n",
-                                        NS_ConvertUTF16toUTF8(mName).get(),
-                                        mCharacterMap.GetSize()));
+#ifdef PR_LOGGING
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+                  NS_ConvertUTF16toUTF8(mName).get(),
+                  mCharacterMap.GetSize()));
+#endif
 
     return rv;
 }
 
 nsresult
 MacOSFontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
 {
     nsAutoreleasePool localPool;
@@ -462,18 +472,18 @@ gfxMacFontFamily::FindStyleVariations()
         {
             fontEntry->mItalic = PR_TRUE;
         }
         if (macTraits & NSFixedPitchFontMask) {
             fontEntry->mFixedPitch = PR_TRUE;
         }
 
 #ifdef PR_LOGGING
-        if (LOG_ENABLED()) {
-            LOG(("(fontinit) added (%s) to family (%s)"
+        if (LOG_FONTLIST_ENABLED()) {
+            LOG_FONTLIST(("(fontlist) added (%s) to family (%s)"
                  " with style: %s weight: %d stretch: %d"
                  " (apple-weight: %d macTraits: %8.8x)",
                  NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), 
                  NS_ConvertUTF16toUTF8(Name()).get(), 
                  fontEntry->IsItalic() ? "italic" : "normal",
                  cssWeight, fontEntry->Stretch(),
                  appKitWeight, macTraits));
         }
@@ -631,17 +641,19 @@ gfxMacPlatformFontList::InitFontList()
 
     ATSGeneration currentGeneration = ::ATSGetGeneration();
 
     // need to ignore notifications after adding each font
     if (mATSGeneration == currentGeneration)
         return NS_OK;
 
     mATSGeneration = currentGeneration;
-    PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) updating to generation: %d", mATSGeneration));
+#ifdef PR_LOGGING
+    LOG_FONTLIST(("(fontlist) updating to generation: %d", mATSGeneration));
+#endif
 
     // reset font lists
     gfxPlatformFontList::InitFontList();
     
     // iterate over available families
     NSEnumerator *families = [[sFontManager availableFontFamilies]
                               objectEnumerator];  // returns "canonical", non-localized family name
 
@@ -695,37 +707,45 @@ gfxMacPlatformFontList::InitFontList()
 void
 gfxMacPlatformFontList::InitSingleFaceList()
 {
     nsAutoTArray<nsString, 10> singleFaceFonts;
     gfxFontUtils::GetPrefsFontList("font.single-face-list", singleFaceFonts);
 
     PRUint32 numFonts = singleFaceFonts.Length();
     for (PRUint32 i = 0; i < numFonts; i++) {
-        PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontlist-singleface) face name: %s\n",
-                                            NS_ConvertUTF16toUTF8(singleFaceFonts[i]).get()));
+#ifdef PR_LOGGING
+        LOG_FONTLIST(("(fontlist-singleface) face name: %s\n",
+                      NS_ConvertUTF16toUTF8(singleFaceFonts[i]).get()));
+#endif
         gfxFontEntry *fontEntry = LookupLocalFont(nsnull, singleFaceFonts[i]);
         if (fontEntry) {
             nsAutoString familyName, key;
             familyName = singleFaceFonts[i];
             GenerateFontListKey(familyName, key);
-            PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontlist-singleface) family name: %s, key: %s\n",
-                   NS_ConvertUTF16toUTF8(familyName).get(), NS_ConvertUTF16toUTF8(key).get()));
+#ifdef PR_LOGGING
+            LOG_FONTLIST(("(fontlist-singleface) family name: %s, key: %s\n",
+                          NS_ConvertUTF16toUTF8(familyName).get(),
+                          NS_ConvertUTF16toUTF8(key).get()));
+#endif
 
             // add only if doesn't exist already
             PRBool found;
             gfxFontFamily *familyEntry;
             if (!(familyEntry = mFontFamilies.GetWeak(key, &found))) {
                 familyEntry = new gfxSingleFaceMacFontFamily(familyName);
                 familyEntry->AddFontEntry(fontEntry);
                 familyEntry->SetHasStyles(PR_TRUE);
                 mFontFamilies.Put(key, familyEntry);
                 fontEntry->mFamily = familyEntry;
-                PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontlist-singleface) added new family\n",
-                       NS_ConvertUTF16toUTF8(familyName).get(), NS_ConvertUTF16toUTF8(key).get()));
+#ifdef PR_LOGGING
+                LOG_FONTLIST(("(fontlist-singleface) added new family\n",
+                              NS_ConvertUTF16toUTF8(familyName).get(),
+                              NS_ConvertUTF16toUTF8(key).get()));
+#endif
             }
         }
     }
 }
 
 void
 gfxMacPlatformFontList::EliminateDuplicateFaces(const nsAString& aFamilyName)
 {
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -30,16 +30,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * 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 ***** */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include "gfxPlatform.h"
 
 #if defined(XP_WIN)
 #include "gfxWindowsPlatform.h"
 #elif defined(XP_MACOSX)
 #include "gfxPlatformMac.h"
 #elif defined(MOZ_WIDGET_GTK2)
 #include "gfxPlatformGtk.h"
@@ -106,16 +111,25 @@ static const char *CMPrefName = "gfx.col
 static const char *CMPrefNameOld = "gfx.color_management.enabled";
 static const char *CMIntentPrefName = "gfx.color_management.rendering_intent";
 static const char *CMProfilePrefName = "gfx.color_management.display_profile";
 static const char *CMForceSRGBPrefName = "gfx.color_management.force_srgb";
 
 static void ShutdownCMS();
 static void MigratePrefs();
 
+
+// logs shared across gfx
+#ifdef PR_LOGGING
+static PRLogModuleInfo *sFontlistLog = nsnull;
+static PRLogModuleInfo *sFontInitLog = nsnull;
+static PRLogModuleInfo *sTextrunLog = nsnull;
+static PRLogModuleInfo *sTextrunuiLog = nsnull;
+#endif
+
 /* Class to listen for pref changes so that chrome code can dynamically
    force sRGB as an output profile. See Bug #452125. */
 class SRGBOverrideObserver : public nsIObserver,
                              public nsSupportsWeakReference
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
@@ -224,16 +238,24 @@ gfxPlatform::GetPlatform()
 
 nsresult
 gfxPlatform::Init()
 {
     NS_ASSERTION(!gPlatform, "Already started???");
 
     gfxAtoms::RegisterAtoms();
 
+#ifdef PR_LOGGING
+    sFontlistLog = PR_NewLogModule("fontlist");;
+    sFontInitLog = PR_NewLogModule("fontinit");;
+    sTextrunLog = PR_NewLogModule("textrun");;
+    sTextrunuiLog = PR_NewLogModule("textrunui");;
+#endif
+
+
     /* Initialize the GfxInfo service.
      * Note: we can't call functions on GfxInfo that depend
      * on gPlatform until after it has been initialized
      * below. GfxInfo initialization annotates our
      * crash reports so we want to do it before
      * we try to load any drivers and do device detection
      * incase that code crashes. See bug #591561. */
     nsCOMPtr<nsIGfxInfo> gfxInfo;
@@ -1241,8 +1263,36 @@ gfxPlatform::FontsPrefsChanged(nsIPrefBr
     } else if (!strcmp(GFX_DOWNLOADABLE_FONTS_SANITIZE_PRESERVE_OTL, aPref)) {
         mSanitizePreserveOTLTables = UNINITIALIZED_VALUE;
     } else if (!strcmp(GFX_PREF_HARFBUZZ_LEVEL, aPref)) {
         mUseHarfBuzzLevel = UNINITIALIZED_VALUE;
         gfxTextRunWordCache::Flush();
         gfxFontCache::GetCache()->AgeAllGenerations();
     }
 }
+
+
+PRLogModuleInfo*
+gfxPlatform::GetLog(eGfxLog aWhichLog)
+{
+#ifdef PR_LOGGING
+    switch (aWhichLog) {
+    case eGfxLog_fontlist:
+        return sFontlistLog;
+        break;
+    case eGfxLog_fontinit:
+        return sFontInitLog;
+        break;
+    case eGfxLog_textrun:
+        return sTextrunLog;
+        break;
+    case eGfxLog_textrunui:
+        return sTextrunuiLog;
+        break;
+    default:
+        break;
+    }
+
+    return nsnull;
+#else
+    return nsnull;
+#endif
+}
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -35,16 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_PLATFORM_H
 #define GFX_PLATFORM_H
 
 #include "prtypes.h"
+#include "prlog.h"
 #include "nsTArray.h"
 
 #include "nsIObserver.h"
 
 #include "gfxTypes.h"
 #include "gfxASurface.h"
 #include "gfxColor.h"
 
@@ -113,16 +114,27 @@ enum eFontPrefLang {
 
 enum eCMSMode {
     eCMSMode_Off          = 0,     // No color management
     eCMSMode_All          = 1,     // Color manage everything
     eCMSMode_TaggedOnly   = 2,     // Color manage tagged Images Only
     eCMSMode_AllCount     = 3
 };
 
+enum eGfxLog {
+    // all font enumerations, localized names, fullname/psnames, cmap loads
+    eGfxLog_fontlist         = 0,
+    // timing info on font initialization
+    eGfxLog_fontinit         = 1,
+    // dump text runs, font matching, system fallback for content
+    eGfxLog_textrun          = 2,
+    // dump text runs, font matching, system fallback for chrome
+    eGfxLog_textrunui        = 3
+};
+
 // when searching through pref langs, max number of pref langs
 const PRUint32 kMaxLenPrefLangList = 32;
 
 #define UNINITIALIZED_VALUE  (-1)
 
 typedef gfxASurface::gfxImageFormat gfxImageFormat;
 
 class THEBES_API gfxPlatform {
@@ -357,16 +369,21 @@ public:
      * Returns a 1x1 surface that can be used to create graphics contexts
      * for measuring text etc as if they will be rendered to the screen
      */
     gfxASurface* ScreenReferenceSurface() { return mScreenReferenceSurface; }
 
     virtual gfxImageFormat GetOffscreenFormat()
     { return gfxASurface::FormatFromContent(gfxASurface::CONTENT_COLOR); }
 
+    /**
+     * Returns a logger if one is available and logging is enabled
+     */
+    static PRLogModuleInfo* GetLog(eGfxLog aWhichLog);
+
 protected:
     gfxPlatform();
     virtual ~gfxPlatform();
 
     static PRBool GetBoolPref(const char *aPref, PRBool aDefault);
 
     void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, 
                             eFontPrefLang aCharLang, eFontPrefLang aPageLang);
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -59,31 +59,45 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include "gfxPlatformFontList.h"
 #include "gfxTextRunWordCache.h"
 
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"  // for pref changes callback notification
 #include "nsServiceManagerUtils.h"
 #include "nsUnicharUtils.h"
+#include "nsUnicodeRange.h"
+#include "gfxUnicodeProperties.h"
 
 // font info loader constants
 static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
 static const PRUint32 kIntervalBetweenLoadingCmaps = 150; // 150ms
 static const PRUint32 kNumFontsPerSlice = 10; // read in info 10 fonts at a time
 
-static PRLogModuleInfo *gFontListLog = PR_NewLogModule("fontListLog");
+#ifdef PR_LOGGING
 
+#define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
+                               PR_LOG_DEBUG, args)
+#define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
+                                   gfxPlatform::GetLog(eGfxLog_fontlist), \
+                                   PR_LOG_DEBUG)
+
+#endif // PR_LOGGING
 
 gfxPlatformFontList *gfxPlatformFontList::sPlatformFontList = nsnull;
 
 
 class gfxFontListPrefObserver : public nsIObserver {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
@@ -378,16 +392,35 @@ gfxPlatformFontList::FindFontForChar(con
             return fontEntry;
     }
 
     FontSearch data(aCh, aPrevFont);
 
     // iterate over all font families to find a font that support the character
     mFontFamilies.Enumerate(gfxPlatformFontList::FindFontForCharProc, &data);
 
+#ifdef PR_LOGGING
+    PRLogModuleInfo *log = gfxPlatform::GetLog(eGfxLog_textrun);
+
+    if (NS_UNLIKELY(log)) {
+        PRUint32 charRange = gfxFontUtils::CharRangeBit(aCh);
+        PRUint32 unicodeRange = FindCharUnicodeRange(aCh);
+        PRUint32 hbscript = gfxUnicodeProperties::GetScriptCode(aCh);
+        PR_LOG(log, PR_LOG_DEBUG,\
+               ("(textrun-systemfallback) char: u+%6.6x "
+                "char-range: %d unicode-range: %d script: %d match: [%s] count: %d\n",
+                aCh,
+                charRange, unicodeRange, hbscript,
+                (data.mBestMatch ?
+                 NS_ConvertUTF16toUTF8(data.mBestMatch->Name()).get() :
+                 "<none>"),
+                data.mCount));
+    }
+#endif
+
     // no match? add to set of non-matching codepoints
     if (!data.mBestMatch) {
         mCodepointsWithNoFonts.set(aCh);
     } else if (aCh == 0xFFFD) {
         mReplacementCharFallbackFamily = data.mBestMatch->FamilyName();
     }
 
     return data.mBestMatch;
@@ -466,47 +499,54 @@ void
 gfxPlatformFontList::AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString& aOtherFamilyName)
 {
     nsAutoString key;
     PRBool found;
     GenerateFontListKey(aOtherFamilyName, key);
 
     if (!mOtherFamilyNames.GetWeak(key, &found)) {
         mOtherFamilyNames.Put(key, aFamilyEntry);
-        PR_LOG(gFontListLog, PR_LOG_DEBUG, ("(fontlist-otherfamily) canonical family: %s, other family: %s\n", 
-                                            NS_ConvertUTF16toUTF8(aFamilyEntry->Name()).get(), 
-                                            NS_ConvertUTF16toUTF8(aOtherFamilyName).get()));
+#ifdef PR_LOGGING
+        LOG_FONTLIST(("(fontlist-otherfamily) canonical family: %s, "
+                      "other family: %s\n",
+                      NS_ConvertUTF16toUTF8(aFamilyEntry->Name()).get(),
+                      NS_ConvertUTF16toUTF8(aOtherFamilyName).get()));
+#endif
         if (mBadUnderlineFamilyNames.Contains(key))
             aFamilyEntry->SetBadUnderlineFamily();
     }
 }
 
 void
 gfxPlatformFontList::AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname)
 {
     PRBool found;
 
     if (!mFullnames.GetWeak(aFullname, &found)) {
         mFullnames.Put(aFullname, aFontEntry);
-        PR_LOG(gFontListLog, PR_LOG_DEBUG, ("(fontlist-fullname) name: %s, fullname: %s\n", 
-                                            NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(), 
-                                            NS_ConvertUTF16toUTF8(aFullname).get()));
+#ifdef PR_LOGGING
+        LOG_FONTLIST(("(fontlist-fullname) name: %s, fullname: %s\n",
+                      NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(),
+                      NS_ConvertUTF16toUTF8(aFullname).get()));
+#endif
     }
 }
 
 void
 gfxPlatformFontList::AddPostscriptName(gfxFontEntry *aFontEntry, nsAString& aPostscriptName)
 {
     PRBool found;
 
     if (!mPostscriptNames.GetWeak(aPostscriptName, &found)) {
         mPostscriptNames.Put(aPostscriptName, aFontEntry);
-        PR_LOG(gFontListLog, PR_LOG_DEBUG, ("(fontlist-postscript) name: %s, psname: %s\n", 
-                                            NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(), 
-                                            NS_ConvertUTF16toUTF8(aPostscriptName).get()));
+#ifdef PR_LOGGING
+        LOG_FONTLIST(("(fontlist-postscript) name: %s, psname: %s\n",
+                      NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(),
+                      NS_ConvertUTF16toUTF8(aPostscriptName).get()));
+#endif
     }
 }
 
 PRBool
 gfxPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
 {
     aFamilyName.Truncate();
     ResolveFontName(aFontName, aFamilyName);
--- a/gfx/thebes/gfxUniscribeShaper.cpp
+++ b/gfx/thebes/gfxUniscribeShaper.cpp
@@ -34,18 +34,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * 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 ***** */
 
-//#define FORCE_PR_LOG
-
 #include "prtypes.h"
 #include "gfxTypes.h"
 
 #include "gfxContext.h"
 #include "gfxUniscribeShaper.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxAtoms.h"
 
@@ -53,19 +51,17 @@
 
 #include "cairo.h"
 #include "cairo-win32.h"
 
 #include <windows.h>
 
 #include "nsTArray.h"
 
-#include "prlog.h"
 #include "prinit.h"
-static PRLogModuleInfo *gFontLog = PR_NewLogModule("winfonts");
 
 /**********************************************************************
  *
  * class gfxUniscribeShaper
  *
  **********************************************************************/
 
 #define ESTIMATE_MAX_GLYPHS(L) (((3 * (L)) >> 1) + 16)
@@ -518,17 +514,16 @@ gfxUniscribeShaper::InitTextRun(gfxConte
         }
 
         if (!item.ShapingEnabled()) {
             item.EnableShaping();
         }
 
         rv = item.Shape();
         if (FAILED(rv)) {
-            PR_LOG(gFontLog, PR_LOG_DEBUG, ("shaping failed"));
             // we know we have the glyphs to display this font already
             // so Uniscribe just doesn't know how to shape the script.
             // Render the glyphs without shaping.
             item.DisableShaping();
             rv = item.Shape();
         }
 #ifdef DEBUG
         if (FAILED(rv)) {