LCOV - code coverage report
Current view: directory - gfx/thebes - gfxFontconfigUtils.h (source / functions) Found Hit Coverage
Test: app.info Lines: 61 24 39.3 %
Date: 2012-06-02 Functions: 36 13 36.1 %

       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 Japan code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Mozilla Japan.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2007
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Masayuki Nakano <masayuki@d-toybox.com>
      23                 :  *   Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
      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                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifndef GFX_FONTCONFIG_UTILS_H
      40                 : #define GFX_FONTCONFIG_UTILS_H
      41                 : 
      42                 : #include "gfxPlatform.h"
      43                 : 
      44                 : #include "nsAutoRef.h"
      45                 : #include "nsTArray.h"
      46                 : #include "nsTHashtable.h"
      47                 : #include "nsISupportsImpl.h"
      48                 : 
      49                 : #include <fontconfig/fontconfig.h>
      50                 : 
      51                 : 
      52                 : template <>
      53                 : class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
      54             429 : {
      55                 : public:
      56             429 :     static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); }
      57             429 :     static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); }
      58                 : };
      59                 : 
      60                 : template <>
      61                 : class nsAutoRefTraits<FcFontSet> : public nsPointerRefTraits<FcFontSet>
      62               0 : {
      63                 : public:
      64               0 :     static void Release(FcFontSet *ptr) { FcFontSetDestroy(ptr); }
      65                 : };
      66                 : 
      67                 : template <>
      68                 : class nsAutoRefTraits<FcCharSet> : public nsPointerRefTraits<FcCharSet>
      69               0 : {
      70                 : public:
      71               0 :     static void Release(FcCharSet *ptr) { FcCharSetDestroy(ptr); }
      72                 : };
      73                 : 
      74                 : class gfxIgnoreCaseCStringComparator
      75                 : {
      76                 :   public:
      77               0 :     bool Equals(const nsACString& a, const nsACString& b) const
      78                 :     {
      79               0 :       return nsCString(a).Equals(b, nsCaseInsensitiveCStringComparator());
      80                 :     }
      81                 : 
      82                 :     bool LessThan(const nsACString& a, const nsACString& b) const
      83                 :     { 
      84                 :       return a < b;
      85                 :     }
      86                 : };
      87                 : 
      88                 : class gfxFontNameList : public nsTArray<nsString>
      89                 : {
      90                 : public:
      91                 :     NS_INLINE_DECL_REFCOUNTING(gfxFontNameList)
      92                 :     bool Exists(nsAString& aName);
      93                 : };
      94                 : 
      95               3 : class gfxFontconfigUtils {
      96                 : public:
      97                 :     gfxFontconfigUtils();
      98                 : 
      99               3 :     static gfxFontconfigUtils* GetFontconfigUtils() {
     100               3 :         if (!sUtils)
     101               3 :             sUtils = new gfxFontconfigUtils();
     102               3 :         return sUtils;
     103                 :     }
     104                 : 
     105                 :     static void Shutdown();
     106                 : 
     107                 :     nsresult GetFontList(nsIAtom *aLangGroup,
     108                 :                          const nsACString& aGenericFamily,
     109                 :                          nsTArray<nsString>& aListOfFonts);
     110                 : 
     111                 :     nsresult UpdateFontList();
     112                 : 
     113                 :     nsresult ResolveFontName(const nsAString& aFontName,
     114                 :                              gfxPlatform::FontResolverCallback aCallback,
     115                 :                              void *aClosure, bool& aAborted);
     116                 : 
     117                 :     nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
     118                 : 
     119                 :     const nsTArray< nsCountedRef<FcPattern> >&
     120                 :     GetFontsForFamily(const FcChar8 *aFamilyName);
     121                 : 
     122                 :     const nsTArray< nsCountedRef<FcPattern> >&
     123                 :     GetFontsForFullname(const FcChar8 *aFullname);
     124                 : 
     125                 :     // Returns the best support that any font offers for |aLang|. 
     126                 :     FcLangResult GetBestLangSupport(const FcChar8 *aLang);
     127                 :     // Returns the fonts offering this best level of support.
     128                 :     const nsTArray< nsCountedRef<FcPattern> >&
     129                 :     GetFontsForLang(const FcChar8 *aLang);
     130                 : 
     131                 :     // Retuns the language support for a fontconfig font pattern
     132                 :     static FcLangResult GetLangSupport(FcPattern *aFont, const FcChar8 *aLang);
     133                 : 
     134                 :     // Conversions between FcChar8*, which is unsigned char*,
     135                 :     // and (signed) char*, that check the type of the argument.
     136               0 :     static const FcChar8 *ToFcChar8(const char *aCharPtr)
     137                 :     {
     138               0 :         return reinterpret_cast<const FcChar8*>(aCharPtr);
     139                 :     }
     140               0 :     static const FcChar8 *ToFcChar8(const nsCString& aCString)
     141                 :     {
     142               0 :         return ToFcChar8(aCString.get());
     143                 :     }
     144               0 :     static const char *ToCString(const FcChar8 *aChar8Ptr)
     145                 :     {
     146               0 :         return reinterpret_cast<const char*>(aChar8Ptr);
     147                 :     }
     148                 : 
     149                 :     static PRUint8 FcSlantToThebesStyle(int aFcSlant);
     150                 :     static PRUint8 GetThebesStyle(FcPattern *aPattern); // slant
     151                 :     static PRUint16 GetThebesWeight(FcPattern *aPattern);
     152                 :     static PRInt16 GetThebesStretch(FcPattern *aPattern);
     153                 : 
     154                 :     static int GetFcSlant(const gfxFontStyle& aFontStyle);
     155                 :     // Returns a precise FC_WEIGHT from |aBaseWeight|,
     156                 :     // which is a CSS absolute weight / 100.
     157                 :     static int FcWeightForBaseWeight(PRInt8 aBaseWeight);
     158                 : 
     159                 :     static int FcWidthForThebesStretch(PRInt16 aStretch);
     160                 : 
     161                 :     static bool GetFullnameFromFamilyAndStyle(FcPattern *aFont,
     162                 :                                                 nsACString *aFullname);
     163                 : 
     164                 :     // This doesn't consider which faces exist, and so initializes the pattern
     165                 :     // using a guessed weight, and doesn't consider sizeAdjust.
     166                 :     static nsReturnRef<FcPattern>
     167                 :     NewPattern(const nsTArray<nsString>& aFamilies,
     168                 :                const gfxFontStyle& aFontStyle, const char *aLang);
     169                 : 
     170                 :     /**
     171                 :      * @param aLangGroup [in] a Mozilla langGroup.
     172                 :      * @param aFcLang [out] returns a language suitable for fontconfig
     173                 :      *        matching |aLangGroup| or an empty string if no match is found.
     174                 :      */
     175                 :     static void GetSampleLangForGroup(nsIAtom *aLangGroup,
     176                 :                                       nsACString *aFcLang);
     177                 : 
     178                 : protected:
     179                 :     // Base class for hash table entries with case-insensitive FcChar8
     180                 :     // string keys.
     181             102 :     class FcStrEntryBase : public PLDHashEntryHdr {
     182                 :     public:
     183                 :         typedef const FcChar8 *KeyType;
     184                 :         typedef const FcChar8 *KeyTypePointer;
     185                 : 
     186             429 :         static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
     187                 :         // Case-insensitive hash.
     188                 :         //
     189                 :         // fontconfig always ignores case of ASCII characters in family
     190                 :         // names and languages, but treatment of whitespace in families is
     191                 :         // not consistent.  FcFontSort and FcFontMatch ignore whitespace
     192                 :         // except for whitespace in the first character, while FcFontList
     193                 :         // and config subsitution tests require whitespace to match
     194                 :         // exactly.  CSS 2.1 implies that whitespace is important in the
     195                 :         // font-family property.  FcStrCmpIgnoreCase considers whitespace
     196                 :         // important.
     197             429 :         static PLDHashNumber HashKey(const FcChar8 *aKey) {
     198             429 :             PRUint32 hash = 0;
     199            6588 :             for (const FcChar8 *c = aKey; *c != '\0'; ++c) {
     200            6159 :                 hash = PR_ROTATE_LEFT32(hash, 3) ^ FcToLower(*c);
     201                 :             }
     202             429 :             return hash;
     203                 :         }
     204                 :         enum { ALLOW_MEMMOVE = true };
     205                 :     };
     206                 : 
     207                 : public:
     208                 :     // Hash entry with a dependent const FcChar8* pointer to an external
     209                 :     // string for a key (and no data).  The user must ensure that the string
     210                 :     // associated with the pointer is not destroyed.  This entry type is
     211                 :     // useful for family name keys as the family name string is held in the
     212                 :     // font pattern.
     213               0 :     class DepFcStrEntry : public FcStrEntryBase {
     214                 :     public:
     215                 :         // When constructing a new entry in the hashtable, the key is left
     216                 :         // NULL.  The caller of PutEntry() must fill in mKey when NULL.  This
     217                 :         // provides a mechanism for the caller of PutEntry() to determine
     218                 :         // whether the entry has been initialized.
     219             102 :         DepFcStrEntry(KeyTypePointer aName)
     220             102 :             : mKey(NULL) { }
     221                 : 
     222               0 :         DepFcStrEntry(const DepFcStrEntry& toCopy)
     223               0 :             : mKey(toCopy.mKey) { }
     224                 : 
     225             327 :         bool KeyEquals(KeyTypePointer aKey) const {
     226             327 :             return FcStrCmpIgnoreCase(aKey, mKey) == 0;
     227                 :         }
     228                 : 
     229                 :         const FcChar8 *mKey;
     230                 :     };
     231                 : 
     232                 :     // Hash entry that uses a copy of an FcChar8 string to store the key.
     233                 :     // This entry type is useful for language keys, as languages are usually
     234                 :     // not stored as strings in font patterns.
     235               0 :     class CopiedFcStrEntry : public FcStrEntryBase {
     236                 :     public:
     237                 :         // When constructing a new entry in the hashtable, the key is void.
     238                 :         // The caller of PutEntry() must call InitKey() when IsKeyInitialized()
     239                 :         // returns false.  This provides a mechanism for the caller of
     240                 :         // PutEntry() to determine whether the entry has been initialized.
     241               0 :         CopiedFcStrEntry(KeyTypePointer aName) {
     242               0 :             mKey.SetIsVoid(true);
     243               0 :         }
     244                 : 
     245                 :         CopiedFcStrEntry(const CopiedFcStrEntry& toCopy)
     246                 :             : mKey(toCopy.mKey) { }
     247                 : 
     248               0 :         bool KeyEquals(KeyTypePointer aKey) const {
     249               0 :             return FcStrCmpIgnoreCase(aKey, ToFcChar8(mKey)) == 0;
     250                 :         }
     251                 : 
     252               0 :         bool IsKeyInitialized() { return !mKey.IsVoid(); }
     253               0 :         void InitKey(const FcChar8* aKey) { mKey.Assign(ToCString(aKey)); }
     254                 : 
     255                 :     private:
     256                 :         nsCString mKey;
     257                 :     };
     258                 : 
     259                 : protected:
     260             102 :     class FontsByFcStrEntry : public DepFcStrEntry {
     261                 :     public:
     262             102 :         FontsByFcStrEntry(KeyTypePointer aName)
     263             102 :             : DepFcStrEntry(aName) { }
     264                 : 
     265                 :         FontsByFcStrEntry(const FontsByFcStrEntry& toCopy)
     266                 :             : DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
     267                 : 
     268             429 :         bool AddFont(FcPattern *aFont) {
     269             429 :             return mFonts.AppendElement(aFont) != nsnull;
     270                 :         }
     271               0 :         const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
     272               0 :             return mFonts;
     273                 :         }
     274                 :     private:
     275                 :         nsTArray< nsCountedRef<FcPattern> > mFonts;
     276                 :     };
     277                 : 
     278                 :     // FontsByFullnameEntry is similar to FontsByFcStrEntry (used for
     279                 :     // mFontsByFamily) except for two differences:
     280                 :     //
     281                 :     // * The font does not always contain a single string for the fullname, so
     282                 :     //   the key is sometimes a combination of family and style.
     283                 :     //
     284                 :     // * There is usually only one font.
     285               0 :     class FontsByFullnameEntry : public DepFcStrEntry {
     286                 :     public:
     287                 :         // When constructing a new entry in the hashtable, the key is left
     288                 :         // NULL.  The caller of PutEntry() is must fill in mKey when adding
     289                 :         // the first font if the key is not derived from the family and style.
     290                 :         // If the key is derived from family and style, a font must be added.
     291               0 :         FontsByFullnameEntry(KeyTypePointer aName)
     292               0 :             : DepFcStrEntry(aName) { }
     293                 : 
     294               0 :         FontsByFullnameEntry(const FontsByFullnameEntry& toCopy)
     295               0 :             : DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
     296                 : 
     297                 :         bool KeyEquals(KeyTypePointer aKey) const;
     298                 : 
     299               0 :         bool AddFont(FcPattern *aFont) {
     300               0 :             return mFonts.AppendElement(aFont) != nsnull;
     301                 :         }
     302               0 :         const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
     303               0 :             return mFonts;
     304                 :         }
     305                 : 
     306                 :         // Don't memmove the nsAutoTArray.
     307                 :         enum { ALLOW_MEMMOVE = false };
     308                 :     private:
     309                 :         // There is usually only one font, but sometimes more.
     310                 :         nsAutoTArray<nsCountedRef<FcPattern>,1> mFonts;
     311                 :     };
     312                 : 
     313               0 :     class LangSupportEntry : public CopiedFcStrEntry {
     314                 :     public:
     315               0 :         LangSupportEntry(KeyTypePointer aName)
     316               0 :             : CopiedFcStrEntry(aName) { }
     317                 : 
     318                 :         LangSupportEntry(const LangSupportEntry& toCopy)
     319                 :             : CopiedFcStrEntry(toCopy), mSupport(toCopy.mSupport) { }
     320                 : 
     321                 :         FcLangResult mSupport;
     322                 :         nsTArray< nsCountedRef<FcPattern> > mFonts;
     323                 :     };
     324                 : 
     325                 :     static gfxFontconfigUtils* sUtils;
     326                 : 
     327                 :     bool IsExistingFamily(const nsCString& aFamilyName);
     328                 : 
     329                 :     nsresult GetFontListInternal(nsTArray<nsCString>& aListOfFonts,
     330                 :                                  nsIAtom *aLangGroup);
     331                 :     nsresult UpdateFontListInternal(bool aForce = false);
     332                 : 
     333                 :     void AddFullnameEntries();
     334                 : 
     335                 :     LangSupportEntry *GetLangSupportEntry(const FcChar8 *aLang,
     336                 :                                           bool aWithFonts);
     337                 : 
     338                 :     // mFontsByFamily and mFontsByFullname contain entries only for families
     339                 :     // and fullnames for which there are fonts.
     340                 :     nsTHashtable<FontsByFcStrEntry> mFontsByFamily;
     341                 :     nsTHashtable<FontsByFullnameEntry> mFontsByFullname;
     342                 :     // mLangSupportTable contains an entry for each language that has been
     343                 :     // looked up through GetLangSupportEntry, even when the language is not
     344                 :     // supported.
     345                 :     nsTHashtable<LangSupportEntry> mLangSupportTable;
     346                 :     const nsTArray< nsCountedRef<FcPattern> > mEmptyPatternArray;
     347                 : 
     348                 :     nsTArray<nsCString> mAliasForMultiFonts;
     349                 : 
     350                 :     FcConfig *mLastConfig;
     351                 : };
     352                 : 
     353                 : #endif /* GFX_FONTCONFIG_UTILS_H */

Generated by: LCOV version 1.7