LCOV - code coverage report
Current view: directory - gfx/thebes - gfxPlatformFontList.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 266 0 0.0 %
Date: 2012-06-02 Functions: 39 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Corporation code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2006-2009
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Jonathan Kew <jfkthame@gmail.com>
      23                 :  *   John Daggett <jdaggett@mozilla.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * Based in part on sample code provided by Apple Computer, Inc.,
      38                 :  * under the following license:
      39                 :  *
      40                 :  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
      41                 :  *
      42                 :  * Redistribution and use in source and binary forms, with or without
      43                 :  * modification, are permitted provided that the following conditions
      44                 :  * are met:
      45                 :  *
      46                 :  * 1.  Redistributions of source code must retain the above copyright
      47                 :  *     notice, this list of conditions and the following disclaimer.
      48                 :  * 2.  Redistributions in binary form must reproduce the above copyright
      49                 :  *     notice, this list of conditions and the following disclaimer in the
      50                 :  *     documentation and/or other materials provided with the distribution.
      51                 :  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
      52                 :  *     its contributors may be used to endorse or promote products derived
      53                 :  *     from this software without specific prior written permission.
      54                 :  *
      55                 :  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
      56                 :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      57                 :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      58                 :  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
      59                 :  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      60                 :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      61                 :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      62                 :  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      63                 :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      64                 :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      65                 :  *
      66                 :  * ***** END LICENSE BLOCK ***** */
      67                 : 
      68                 : #ifdef MOZ_LOGGING
      69                 : #define FORCE_PR_LOG /* Allow logging in the release build */
      70                 : #endif
      71                 : #include "prlog.h"
      72                 : 
      73                 : #include "gfxPlatformFontList.h"
      74                 : 
      75                 : #include "nsUnicharUtils.h"
      76                 : #include "nsUnicodeRange.h"
      77                 : #include "nsUnicodeProperties.h"
      78                 : 
      79                 : #include "mozilla/Preferences.h"
      80                 : #include "mozilla/Telemetry.h"
      81                 : #include "mozilla/TimeStamp.h"
      82                 : 
      83                 : using namespace mozilla;
      84                 : 
      85                 : // font info loader constants
      86                 : static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
      87                 : static const PRUint32 kIntervalBetweenLoadingCmaps = 150; // 150ms
      88                 : static const PRUint32 kNumFontsPerSlice = 10; // read in info 10 fonts at a time
      89                 : 
      90                 : #ifdef PR_LOGGING
      91                 : 
      92                 : #define LOG_FONTLIST(args) PR_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
      93                 :                                PR_LOG_DEBUG, args)
      94                 : #define LOG_FONTLIST_ENABLED() PR_LOG_TEST( \
      95                 :                                    gfxPlatform::GetLog(eGfxLog_fontlist), \
      96                 :                                    PR_LOG_DEBUG)
      97                 : 
      98                 : #endif // PR_LOGGING
      99                 : 
     100                 : gfxPlatformFontList *gfxPlatformFontList::sPlatformFontList = nsnull;
     101                 : 
     102                 : 
     103                 : static const char* kObservedPrefs[] = {
     104                 :     "font.",
     105                 :     "font.name-list.",
     106                 :     "intl.accept_languages",  // hmmmm...
     107                 :     nsnull
     108                 : };
     109                 : 
     110               0 : class gfxFontListPrefObserver : public nsIObserver {
     111                 : public:
     112                 :     NS_DECL_ISUPPORTS
     113                 :     NS_DECL_NSIOBSERVER
     114                 : };
     115                 : 
     116                 : static gfxFontListPrefObserver* gFontListPrefObserver = nsnull;
     117                 : 
     118               0 : NS_IMPL_ISUPPORTS1(gfxFontListPrefObserver, nsIObserver)
     119                 : 
     120                 : NS_IMETHODIMP
     121               0 : gfxFontListPrefObserver::Observe(nsISupports     *aSubject,
     122                 :                                  const char      *aTopic,
     123                 :                                  const PRUnichar *aData)
     124                 : {
     125               0 :     NS_ASSERTION(!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID), "invalid topic");
     126                 :     // XXX this could be made to only clear out the cache for the prefs that were changed
     127                 :     // but it probably isn't that big a deal.
     128               0 :     gfxPlatformFontList::PlatformFontList()->ClearPrefFonts();
     129               0 :     gfxFontCache::GetCache()->AgeAllGenerations();
     130               0 :     return NS_OK;
     131                 : }
     132                 : 
     133                 : 
     134               0 : gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
     135                 :     : mNeedFullnamePostscriptNames(aNeedFullnamePostscriptNames),
     136               0 :       mStartIndex(0), mIncrement(kNumFontsPerSlice), mNumFamilies(0)
     137                 : {
     138               0 :     mFontFamilies.Init(100);
     139               0 :     mOtherFamilyNames.Init(30);
     140               0 :     mOtherFamilyNamesInitialized = false;
     141                 : 
     142               0 :     if (mNeedFullnamePostscriptNames) {
     143               0 :         mFullnames.Init(100);
     144               0 :         mPostscriptNames.Init(100);
     145                 :     }
     146               0 :     mFaceNamesInitialized = false;
     147                 : 
     148               0 :     mPrefFonts.Init(10);
     149                 : 
     150               0 :     mBadUnderlineFamilyNames.Init(10);
     151               0 :     LoadBadUnderlineList();
     152                 : 
     153                 :     // pref changes notification setup
     154               0 :     NS_ASSERTION(!gFontListPrefObserver,
     155                 :                  "There has been font list pref observer already");
     156               0 :     gFontListPrefObserver = new gfxFontListPrefObserver();
     157               0 :     NS_ADDREF(gFontListPrefObserver);
     158               0 :     Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
     159               0 : }
     160                 : 
     161               0 : gfxPlatformFontList::~gfxPlatformFontList()
     162                 : {
     163               0 :     NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
     164               0 :     Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs);
     165               0 :     NS_RELEASE(gFontListPrefObserver);
     166               0 : }
     167                 : 
     168                 : nsresult
     169               0 : gfxPlatformFontList::InitFontList()
     170                 : {
     171               0 :     mFontFamilies.Clear();
     172               0 :     mOtherFamilyNames.Clear();
     173               0 :     mOtherFamilyNamesInitialized = false;
     174               0 :     if (mNeedFullnamePostscriptNames) {
     175               0 :         mFullnames.Clear();
     176               0 :         mPostscriptNames.Clear();
     177                 :     }
     178               0 :     mFaceNamesInitialized = false;
     179               0 :     mPrefFonts.Clear();
     180               0 :     CancelLoader();
     181                 : 
     182                 :     // initialize ranges of characters for which system-wide font search should be skipped
     183               0 :     mCodepointsWithNoFonts.reset();
     184               0 :     mCodepointsWithNoFonts.SetRange(0,0x1f);     // C0 controls
     185               0 :     mCodepointsWithNoFonts.SetRange(0x7f,0x9f);  // C1 controls
     186                 : 
     187               0 :     sPlatformFontList = this;
     188                 : 
     189               0 :     return NS_OK;
     190                 : }
     191                 : 
     192                 : void
     193               0 : gfxPlatformFontList::GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult)
     194                 : {
     195               0 :     aResult = aKeyName;
     196               0 :     ToLowerCase(aResult);
     197               0 : }
     198                 : 
     199                 : void 
     200               0 : gfxPlatformFontList::InitOtherFamilyNames()
     201                 : {
     202               0 :     mOtherFamilyNamesInitialized = true;
     203                 : 
     204               0 :     Telemetry::AutoTimer<Telemetry::FONTLIST_INITOTHERFAMILYNAMES> timer;
     205                 :     // iterate over all font families and read in other family names
     206               0 :     mFontFamilies.Enumerate(gfxPlatformFontList::InitOtherFamilyNamesProc, this);
     207               0 : }
     208                 :                                                          
     209                 : PLDHashOperator PR_CALLBACK
     210               0 : gfxPlatformFontList::InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
     211                 :                                               nsRefPtr<gfxFontFamily>& aFamilyEntry,
     212                 :                                               void* userArg)
     213                 : {
     214               0 :     gfxPlatformFontList *fc = static_cast<gfxPlatformFontList*>(userArg);
     215               0 :     aFamilyEntry->ReadOtherFamilyNames(fc);
     216               0 :     return PL_DHASH_NEXT;
     217                 : }
     218                 : 
     219                 : void
     220               0 : gfxPlatformFontList::InitFaceNameLists()
     221                 : {
     222               0 :     mFaceNamesInitialized = true;
     223                 : 
     224                 :     // iterate over all font families and read in other family names
     225               0 :     Telemetry::AutoTimer<Telemetry::FONTLIST_INITFACENAMELISTS> timer;
     226               0 :     mFontFamilies.Enumerate(gfxPlatformFontList::InitFaceNameListsProc, this);
     227               0 : }
     228                 : 
     229                 : PLDHashOperator PR_CALLBACK
     230               0 : gfxPlatformFontList::InitFaceNameListsProc(nsStringHashKey::KeyType aKey,
     231                 :                                            nsRefPtr<gfxFontFamily>& aFamilyEntry,
     232                 :                                            void* userArg)
     233                 : {
     234               0 :     gfxPlatformFontList *fc = static_cast<gfxPlatformFontList*>(userArg);
     235               0 :     aFamilyEntry->ReadFaceNames(fc, fc->NeedFullnamePostscriptNames());
     236               0 :     return PL_DHASH_NEXT;
     237                 : }
     238                 : 
     239                 : void
     240               0 : gfxPlatformFontList::PreloadNamesList()
     241                 : {
     242               0 :     nsAutoTArray<nsString, 10> preloadFonts;
     243               0 :     gfxFontUtils::GetPrefsFontList("font.preload-names-list", preloadFonts);
     244                 : 
     245               0 :     PRUint32 numFonts = preloadFonts.Length();
     246               0 :     for (PRUint32 i = 0; i < numFonts; i++) {
     247                 :         bool found;
     248               0 :         nsAutoString key;
     249               0 :         GenerateFontListKey(preloadFonts[i], key);
     250                 :         
     251                 :         // only search canonical names!
     252               0 :         gfxFontFamily *familyEntry = mFontFamilies.GetWeak(key, &found);
     253               0 :         if (familyEntry) {
     254               0 :             familyEntry->ReadOtherFamilyNames(this);
     255                 :         }
     256                 :     }
     257                 : 
     258               0 : }
     259                 : 
     260                 : void 
     261               0 : gfxPlatformFontList::SetFixedPitch(const nsAString& aFamilyName)
     262                 : {
     263               0 :     gfxFontFamily *family = FindFamily(aFamilyName);
     264               0 :     if (!family) return;
     265                 : 
     266               0 :     family->FindStyleVariations();
     267               0 :     nsTArray<nsRefPtr<gfxFontEntry> >& fontlist = family->GetFontList();
     268                 : 
     269               0 :     PRUint32 i, numFonts = fontlist.Length();
     270                 : 
     271               0 :     for (i = 0; i < numFonts; i++) {
     272               0 :         fontlist[i]->mFixedPitch = 1;
     273                 :     }
     274                 : }
     275                 : 
     276                 : void
     277               0 : gfxPlatformFontList::LoadBadUnderlineList()
     278                 : {
     279               0 :     nsAutoTArray<nsString, 10> blacklist;
     280               0 :     gfxFontUtils::GetPrefsFontList("font.blacklist.underline_offset", blacklist);
     281               0 :     PRUint32 numFonts = blacklist.Length();
     282               0 :     for (PRUint32 i = 0; i < numFonts; i++) {
     283               0 :         nsAutoString key;
     284               0 :         GenerateFontListKey(blacklist[i], key);
     285               0 :         mBadUnderlineFamilyNames.PutEntry(key);
     286                 :     }
     287               0 : }
     288                 : 
     289                 : bool 
     290               0 : gfxPlatformFontList::ResolveFontName(const nsAString& aFontName, nsAString& aResolvedFontName)
     291                 : {
     292               0 :     gfxFontFamily *family = FindFamily(aFontName);
     293               0 :     if (family) {
     294               0 :         aResolvedFontName = family->Name();
     295               0 :         return true;
     296                 :     }
     297               0 :     return false;
     298                 : }
     299                 : 
     300                 : struct FontListData {
     301               0 :     FontListData(nsIAtom *aLangGroup,
     302                 :                  const nsACString& aGenericFamily,
     303                 :                  nsTArray<nsString>& aListOfFonts) :
     304                 :         mLangGroup(aLangGroup), mGenericFamily(aGenericFamily),
     305               0 :         mListOfFonts(aListOfFonts) {}
     306                 :     nsIAtom *mLangGroup;
     307                 :     const nsACString& mGenericFamily;
     308                 :     nsTArray<nsString>& mListOfFonts;
     309                 : };
     310                 : 
     311                 : PLDHashOperator PR_CALLBACK
     312               0 : gfxPlatformFontList::HashEnumFuncForFamilies(nsStringHashKey::KeyType aKey,
     313                 :                                              nsRefPtr<gfxFontFamily>& aFamilyEntry,
     314                 :                                              void *aUserArg)
     315                 : {
     316               0 :     FontListData *data = static_cast<FontListData*>(aUserArg);
     317                 : 
     318                 :     // use the first variation for now.  This data should be the same
     319                 :     // for all the variations and should probably be moved up to
     320                 :     // the Family
     321               0 :     gfxFontStyle style;
     322               0 :     style.language = data->mLangGroup;
     323                 :     bool needsBold;
     324               0 :     nsRefPtr<gfxFontEntry> aFontEntry = aFamilyEntry->FindFontForStyle(style, needsBold);
     325               0 :     NS_ASSERTION(aFontEntry, "couldn't find any font entry in family");
     326               0 :     if (!aFontEntry)
     327               0 :         return PL_DHASH_NEXT;
     328                 : 
     329                 :     /* skip symbol fonts */
     330               0 :     if (aFontEntry->IsSymbolFont())
     331               0 :         return PL_DHASH_NEXT;
     332                 : 
     333               0 :     if (aFontEntry->SupportsLangGroup(data->mLangGroup) &&
     334               0 :         aFontEntry->MatchesGenericFamily(data->mGenericFamily)) {
     335               0 :         nsAutoString localizedFamilyName;
     336               0 :         aFamilyEntry->LocalizedName(localizedFamilyName);
     337               0 :         data->mListOfFonts.AppendElement(localizedFamilyName);
     338                 :     }
     339                 : 
     340               0 :     return PL_DHASH_NEXT;
     341                 : }
     342                 : 
     343                 : void
     344               0 : gfxPlatformFontList::GetFontList(nsIAtom *aLangGroup,
     345                 :                                  const nsACString& aGenericFamily,
     346                 :                                  nsTArray<nsString>& aListOfFonts)
     347                 : {
     348               0 :     FontListData data(aLangGroup, aGenericFamily, aListOfFonts);
     349                 : 
     350               0 :     mFontFamilies.Enumerate(gfxPlatformFontList::HashEnumFuncForFamilies, &data);
     351                 : 
     352               0 :     aListOfFonts.Sort();
     353               0 :     aListOfFonts.Compact();
     354               0 : }
     355                 : 
     356                 : struct FontFamilyListData {
     357               0 :     FontFamilyListData(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray) 
     358               0 :         : mFamilyArray(aFamilyArray)
     359               0 :     {}
     360                 : 
     361               0 :     static PLDHashOperator PR_CALLBACK AppendFamily(nsStringHashKey::KeyType aKey,
     362                 :                                                     nsRefPtr<gfxFontFamily>& aFamilyEntry,
     363                 :                                                     void *aUserArg)
     364                 :     {
     365               0 :         FontFamilyListData *data = static_cast<FontFamilyListData*>(aUserArg);
     366               0 :         data->mFamilyArray.AppendElement(aFamilyEntry);
     367               0 :         return PL_DHASH_NEXT;
     368                 :     }
     369                 : 
     370                 :     nsTArray<nsRefPtr<gfxFontFamily> >& mFamilyArray;
     371                 : };
     372                 : 
     373                 : void
     374               0 : gfxPlatformFontList::GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray)
     375                 : {
     376               0 :     FontFamilyListData data(aFamilyArray);
     377               0 :     mFontFamilies.Enumerate(FontFamilyListData::AppendFamily, &data);
     378               0 : }
     379                 : 
     380                 : gfxFontEntry*
     381               0 : gfxPlatformFontList::SystemFindFontForChar(const PRUint32 aCh,
     382                 :                                            PRInt32 aRunScript,
     383                 :                                            const gfxFontStyle* aStyle)
     384                 :  {
     385               0 :     gfxFontEntry* fontEntry = nsnull;
     386                 : 
     387                 :     // is codepoint with no matching font? return null immediately
     388               0 :     if (mCodepointsWithNoFonts.test(aCh)) {
     389               0 :         return nsnull;
     390                 :     }
     391                 : 
     392                 :     // try to short-circuit font fallback for U+FFFD, used to represent
     393                 :     // encoding errors: just use a platform-specific fallback system
     394                 :     // font that is guaranteed (or at least highly likely) to be around,
     395                 :     // or a cached family from last time U+FFFD was seen. this helps
     396                 :     // speed up pages with lots of encoding errors, binary-as-text, etc.
     397               0 :     if (aCh == 0xFFFD && mReplacementCharFallbackFamily.Length() > 0) {
     398                 :         bool needsBold;  // ignored in the system fallback case
     399                 : 
     400                 :         fontEntry = FindFontForFamily(mReplacementCharFallbackFamily,
     401               0 :                                       aStyle, needsBold);
     402                 : 
     403               0 :         if (fontEntry && fontEntry->TestCharacterMap(aCh))
     404               0 :             return fontEntry;
     405                 :     }
     406                 : 
     407               0 :     TimeStamp start = TimeStamp::Now();
     408                 : 
     409                 :     // search commonly available fonts
     410               0 :     bool common = true;
     411               0 :     fontEntry = CommonFontFallback(aCh, aRunScript, aStyle);
     412                 :  
     413                 :     // if didn't find a font, do system-wide fallback (except for specials)
     414               0 :     PRUint32 cmapCount = 0;
     415               0 :     if (!fontEntry) {
     416               0 :         common = false;
     417               0 :         fontEntry = GlobalFontFallback(aCh, aRunScript, aStyle, cmapCount);
     418                 :     }
     419               0 :     TimeDuration elapsed = TimeStamp::Now() - start;
     420                 : 
     421                 : #ifdef PR_LOGGING
     422               0 :     PRLogModuleInfo *log = gfxPlatform::GetLog(eGfxLog_textrun);
     423                 : 
     424               0 :     if (NS_UNLIKELY(log)) {
     425               0 :         PRUint32 charRange = gfxFontUtils::CharRangeBit(aCh);
     426               0 :         PRUint32 unicodeRange = FindCharUnicodeRange(aCh);
     427               0 :         PRInt32 script = mozilla::unicode::GetScriptCode(aCh);
     428               0 :         PR_LOG(log, PR_LOG_WARNING,\
     429                 :                ("(textrun-systemfallback-%s) char: u+%6.6x "
     430                 :                  "char-range: %d unicode-range: %d script: %d match: [%s]"
     431                 :                 " time: %dus cmaps: %d\n",
     432                 :                 (common ? "common" : "global"), aCh,
     433                 :                  charRange, unicodeRange, script,
     434                 :                 (fontEntry ? NS_ConvertUTF16toUTF8(fontEntry->Name()).get() :
     435                 :                     "<none>"),
     436                 :                 PRInt32(elapsed.ToMicroseconds()),
     437                 :                 cmapCount));
     438                 :     }
     439                 : #endif
     440                 : 
     441                 :     // no match? add to set of non-matching codepoints
     442               0 :     if (!fontEntry) {
     443               0 :          mCodepointsWithNoFonts.set(aCh);
     444               0 :     } else if (aCh == 0xFFFD && fontEntry) {
     445               0 :         mReplacementCharFallbackFamily = fontEntry->FamilyName();
     446                 :      }
     447                 :  
     448                 :     // track system fallback time
     449                 :     static bool first = true;
     450               0 :     PRInt32 intElapsed = PRInt32(first ? elapsed.ToMilliseconds() :
     451               0 :                                          elapsed.ToMicroseconds());
     452                 :     Telemetry::Accumulate((first ? Telemetry::SYSTEM_FONT_FALLBACK_FIRST :
     453                 :                                    Telemetry::SYSTEM_FONT_FALLBACK),
     454               0 :                           intElapsed);
     455               0 :     first = false;
     456                 : 
     457                 :     // track the script for which fallback occurred (incremented one make it
     458                 :     // 1-based)
     459               0 :     Telemetry::Accumulate(Telemetry::SYSTEM_FONT_FALLBACK_SCRIPT, aRunScript + 1);
     460                 : 
     461               0 :     return fontEntry;
     462                 : }
     463                 : 
     464                 : PLDHashOperator PR_CALLBACK 
     465               0 : gfxPlatformFontList::FindFontForCharProc(nsStringHashKey::KeyType aKey, nsRefPtr<gfxFontFamily>& aFamilyEntry,
     466                 :      void *userArg)
     467                 : {
     468               0 :     GlobalFontMatch *data = static_cast<GlobalFontMatch*>(userArg);
     469                 :  
     470                 :      // evaluate all fonts in this family for a match
     471               0 :      aFamilyEntry->FindFontForChar(data);
     472                 : 
     473               0 :      return PL_DHASH_NEXT;
     474                 : }
     475                 : 
     476                 : #define NUM_FALLBACK_FONTS        8
     477                 : 
     478                 : gfxFontEntry*
     479               0 : gfxPlatformFontList::CommonFontFallback(const PRUint32 aCh,
     480                 :                                         PRInt32 aRunScript,
     481                 :                                         const gfxFontStyle* aMatchStyle)
     482                 : {
     483               0 :     nsAutoTArray<const char*,NUM_FALLBACK_FONTS> defaultFallbacks;
     484                 :     PRUint32 i, numFallbacks;
     485                 : 
     486               0 :     gfxPlatform::GetPlatform()->GetCommonFallbackFonts(aCh, aRunScript,
     487               0 :                                                        defaultFallbacks);
     488               0 :     numFallbacks = defaultFallbacks.Length();
     489               0 :     for (i = 0; i < numFallbacks; i++) {
     490               0 :         nsAutoString familyName;
     491               0 :         const char *fallbackFamily = defaultFallbacks[i];
     492                 : 
     493               0 :         familyName.AppendASCII(fallbackFamily);
     494                 :         gfxFontFamily *fallback =
     495               0 :                 gfxPlatformFontList::PlatformFontList()->FindFamily(familyName);
     496               0 :         if (!fallback)
     497               0 :             continue;
     498                 : 
     499                 :         gfxFontEntry *fontEntry;
     500                 :         bool needsBold;  // ignored in the system fallback case
     501                 : 
     502                 :         // use first font in list that supports a given character
     503               0 :         fontEntry = fallback->FindFontForStyle(*aMatchStyle, needsBold);
     504               0 :         if (fontEntry && fontEntry->TestCharacterMap(aCh)) {
     505               0 :             return fontEntry;
     506                 :         }
     507                 :     }
     508                 : 
     509               0 :     return nsnull;
     510                 : }
     511                 : 
     512                 : gfxFontEntry*
     513               0 : gfxPlatformFontList::GlobalFontFallback(const PRUint32 aCh,
     514                 :                                         PRInt32 aRunScript,
     515                 :                                         const gfxFontStyle* aMatchStyle,
     516                 :                                         PRUint32& aCmapCount)
     517                 : {
     518                 :     // otherwise, try to find it among local fonts
     519               0 :     GlobalFontMatch data(aCh, aRunScript, aMatchStyle);
     520                 : 
     521                 :     // iterate over all font families to find a font that support the character
     522               0 :     mFontFamilies.Enumerate(gfxPlatformFontList::FindFontForCharProc, &data);
     523                 : 
     524               0 :     aCmapCount = data.mCmapsTested;
     525                 : 
     526               0 :     return data.mBestMatch;
     527                 : }
     528                 : 
     529                 : #ifdef XP_WIN
     530                 : #include <windows.h>
     531                 : 
     532                 : // crude hack for using when monitoring process
     533                 : static void LogRegistryEvent(const wchar_t *msg)
     534                 : {
     535                 :   HKEY dummyKey;
     536                 :   HRESULT hr;
     537                 :   wchar_t buf[512];
     538                 : 
     539                 :   wsprintfW(buf, L" log %s", msg);
     540                 :   hr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buf, 0, KEY_READ, &dummyKey);
     541                 :   if (SUCCEEDED(hr)) {
     542                 :     RegCloseKey(dummyKey);
     543                 :   }
     544                 : }
     545                 : #endif
     546                 : 
     547                 : gfxFontFamily* 
     548               0 : gfxPlatformFontList::FindFamily(const nsAString& aFamily)
     549                 : {
     550               0 :     nsAutoString key;
     551                 :     gfxFontFamily *familyEntry;
     552                 :     bool found;
     553               0 :     GenerateFontListKey(aFamily, key);
     554                 : 
     555               0 :     NS_ASSERTION(mFontFamilies.Count() != 0, "system font list was not initialized correctly");
     556                 : 
     557                 :     // lookup in canonical (i.e. English) family name list
     558               0 :     if ((familyEntry = mFontFamilies.GetWeak(key, &found))) {
     559               0 :         return familyEntry;
     560                 :     }
     561                 : 
     562                 :     // lookup in other family names list (mostly localized names)
     563               0 :     if ((familyEntry = mOtherFamilyNames.GetWeak(key, &found)) != nsnull) {
     564               0 :         return familyEntry;
     565                 :     }
     566                 : 
     567                 :     // name not found and other family names not yet fully initialized so
     568                 :     // initialize the rest of the list and try again.  this is done lazily
     569                 :     // since reading name table entries is expensive.
     570                 :     // although ASCII localized family names are possible they don't occur
     571                 :     // in practice so avoid pulling in names at startup
     572               0 :     if (!mOtherFamilyNamesInitialized && !IsASCII(aFamily)) {
     573               0 :         InitOtherFamilyNames();
     574               0 :         if ((familyEntry = mOtherFamilyNames.GetWeak(key, &found)) != nsnull) {
     575               0 :             return familyEntry;
     576                 :         }
     577                 :     }
     578                 : 
     579               0 :     return nsnull;
     580                 : }
     581                 : 
     582                 : gfxFontEntry*
     583               0 : gfxPlatformFontList::FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, bool& aNeedsBold)
     584                 : {
     585               0 :     gfxFontFamily *familyEntry = FindFamily(aFamily);
     586                 : 
     587               0 :     aNeedsBold = false;
     588                 : 
     589               0 :     if (familyEntry)
     590               0 :         return familyEntry->FindFontForStyle(*aStyle, aNeedsBold);
     591                 : 
     592               0 :     return nsnull;
     593                 : }
     594                 : 
     595                 : bool
     596               0 : gfxPlatformFontList::GetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> > *array)
     597                 : {
     598               0 :     return mPrefFonts.Get(PRUint32(aLangGroup), array);
     599                 : }
     600                 : 
     601                 : void
     602               0 : gfxPlatformFontList::SetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> >& array)
     603                 : {
     604               0 :     mPrefFonts.Put(PRUint32(aLangGroup), array);
     605               0 : }
     606                 : 
     607                 : void 
     608               0 : gfxPlatformFontList::AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString& aOtherFamilyName)
     609                 : {
     610               0 :     nsAutoString key;
     611                 :     bool found;
     612               0 :     GenerateFontListKey(aOtherFamilyName, key);
     613                 : 
     614               0 :     if (!mOtherFamilyNames.GetWeak(key, &found)) {
     615               0 :         mOtherFamilyNames.Put(key, aFamilyEntry);
     616                 : #ifdef PR_LOGGING
     617               0 :         LOG_FONTLIST(("(fontlist-otherfamily) canonical family: %s, "
     618                 :                       "other family: %s\n",
     619                 :                       NS_ConvertUTF16toUTF8(aFamilyEntry->Name()).get(),
     620                 :                       NS_ConvertUTF16toUTF8(aOtherFamilyName).get()));
     621                 : #endif
     622               0 :         if (mBadUnderlineFamilyNames.Contains(key))
     623               0 :             aFamilyEntry->SetBadUnderlineFamily();
     624                 :     }
     625               0 : }
     626                 : 
     627                 : void
     628               0 : gfxPlatformFontList::AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname)
     629                 : {
     630                 :     bool found;
     631                 : 
     632               0 :     if (!mFullnames.GetWeak(aFullname, &found)) {
     633               0 :         mFullnames.Put(aFullname, aFontEntry);
     634                 : #ifdef PR_LOGGING
     635               0 :         LOG_FONTLIST(("(fontlist-fullname) name: %s, fullname: %s\n",
     636                 :                       NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(),
     637                 :                       NS_ConvertUTF16toUTF8(aFullname).get()));
     638                 : #endif
     639                 :     }
     640               0 : }
     641                 : 
     642                 : void
     643               0 : gfxPlatformFontList::AddPostscriptName(gfxFontEntry *aFontEntry, nsAString& aPostscriptName)
     644                 : {
     645                 :     bool found;
     646                 : 
     647               0 :     if (!mPostscriptNames.GetWeak(aPostscriptName, &found)) {
     648               0 :         mPostscriptNames.Put(aPostscriptName, aFontEntry);
     649                 : #ifdef PR_LOGGING
     650               0 :         LOG_FONTLIST(("(fontlist-postscript) name: %s, psname: %s\n",
     651                 :                       NS_ConvertUTF16toUTF8(aFontEntry->Name()).get(),
     652                 :                       NS_ConvertUTF16toUTF8(aPostscriptName).get()));
     653                 : #endif
     654                 :     }
     655               0 : }
     656                 : 
     657                 : bool
     658               0 : gfxPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
     659                 : {
     660               0 :     aFamilyName.Truncate();
     661               0 :     ResolveFontName(aFontName, aFamilyName);
     662               0 :     return !aFamilyName.IsEmpty();
     663                 : }
     664                 : 
     665                 : void 
     666               0 : gfxPlatformFontList::InitLoader()
     667                 : {
     668               0 :     GetFontFamilyList(mFontFamiliesToLoad);
     669               0 :     mStartIndex = 0;
     670               0 :     mNumFamilies = mFontFamiliesToLoad.Length();
     671               0 : }
     672                 : 
     673                 : bool
     674               0 : gfxPlatformFontList::RunLoader()
     675                 : {
     676               0 :     PRUint32 i, endIndex = (mStartIndex + mIncrement < mNumFamilies ? mStartIndex + mIncrement : mNumFamilies);
     677               0 :     bool loadCmaps = !UsesSystemFallback() ||
     678               0 :         gfxPlatform::GetPlatform()->UseCmapsDuringSystemFallback();
     679                 : 
     680                 :     // for each font family, load in various font info
     681               0 :     for (i = mStartIndex; i < endIndex; i++) {
     682               0 :         gfxFontFamily* familyEntry = mFontFamiliesToLoad[i];
     683                 : 
     684                 :         // find all faces that are members of this family
     685               0 :         familyEntry->FindStyleVariations();
     686               0 :         if (familyEntry->GetFontList().Length() == 0) {
     687                 :             // failed to load any faces for this family, so discard it
     688               0 :             nsAutoString key;
     689               0 :             GenerateFontListKey(familyEntry->Name(), key);
     690               0 :             mFontFamilies.Remove(key);
     691               0 :             continue;
     692                 :         }
     693                 : 
     694                 :         // load the cmaps if needed
     695               0 :         if (loadCmaps) {
     696               0 :             familyEntry->ReadAllCMAPs();
     697                 :         }
     698                 : 
     699                 :         // read in face names
     700               0 :         familyEntry->ReadFaceNames(this, mNeedFullnamePostscriptNames);
     701                 : 
     702                 :         // check whether the family can be considered "simple" for style matching
     703               0 :         familyEntry->CheckForSimpleFamily();
     704                 :     }
     705                 : 
     706               0 :     mStartIndex = endIndex;
     707                 : 
     708               0 :     return (mStartIndex >= mNumFamilies);
     709                 : }
     710                 : 
     711                 : void 
     712               0 : gfxPlatformFontList::FinishLoader()
     713                 : {
     714               0 :     mFontFamiliesToLoad.Clear();
     715               0 :     mNumFamilies = 0;
     716               0 : }

Generated by: LCOV version 1.7