LCOV - code coverage report
Current view: top level - gfx/thebes - gfxFontFamilyList.h (source / functions) Hit Total Coverage
Test: output.info Lines: 66 180 36.7 %
Date: 2017-07-14 16:53:18 Functions: 21 36 58.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef GFX_FONT_FAMILY_LIST_H
       7             : #define GFX_FONT_FAMILY_LIST_H
       8             : 
       9             : #include "nsDebug.h"
      10             : #include "nsISupportsImpl.h"
      11             : #include "nsString.h"
      12             : #include "nsUnicharUtils.h"
      13             : #include "nsTArray.h"
      14             : #include "mozilla/MemoryReporting.h"
      15             : 
      16             : namespace mozilla {
      17             : 
      18             : /**
      19             :  * type of font family name, either a name (e.g. Helvetica) or a
      20             :  * generic (e.g. serif, sans-serif), with the ability to distinguish
      21             :  * between unquoted and quoted names for serializaiton
      22             :  */ 
      23             : 
      24             : enum FontFamilyType : uint32_t {
      25             :   eFamily_none = 0,  // used when finding generics
      26             : 
      27             :   // explicitly named font family (e.g. Helvetica)
      28             :   eFamily_named,
      29             :   eFamily_named_quoted,
      30             : 
      31             :   // generics
      32             :   eFamily_serif,         // pref font code relies on this ordering!!!
      33             :   eFamily_sans_serif,
      34             :   eFamily_monospace,
      35             :   eFamily_cursive,
      36             :   eFamily_fantasy,
      37             : 
      38             :   // special
      39             :   eFamily_moz_variable,
      40             :   eFamily_moz_fixed,
      41             : 
      42             :   eFamily_generic_first = eFamily_serif,
      43             :   eFamily_generic_last = eFamily_fantasy,
      44             :   eFamily_generic_count = (eFamily_fantasy - eFamily_serif + 1)
      45             : };
      46             : 
      47             : enum QuotedName { eQuotedName, eUnquotedName };
      48             : 
      49             : /**
      50             :  * font family name, a string for the name if not a generic and
      51             :  * a font type indicated named family or which generic family
      52             :  */
      53             : 
      54         392 : struct FontFamilyName final {
      55           0 :     FontFamilyName()
      56           0 :         : mType(eFamily_named)
      57           0 :     {}
      58             : 
      59             :     // named font family - e.g. Helvetica
      60          10 :     explicit FontFamilyName(const nsAString& aFamilyName,
      61          10 :                             QuotedName aQuoted = eUnquotedName) {
      62          10 :         mType = (aQuoted == eQuotedName) ? eFamily_named_quoted : eFamily_named;
      63          10 :         mName = aFamilyName;
      64          10 :     }
      65             : 
      66             :     // generic font family - e.g. sans-serif
      67         247 :     explicit FontFamilyName(FontFamilyType aType) {
      68         247 :         NS_ASSERTION(aType != eFamily_named &&
      69             :                      aType != eFamily_named_quoted &&
      70             :                      aType != eFamily_none,
      71             :                      "expected a generic font type");
      72         247 :         mName.Truncate();
      73         247 :         mType = aType;
      74         247 :     }
      75             : 
      76         391 :     FontFamilyName(const FontFamilyName& aCopy) {
      77         391 :         mType = aCopy.mType;
      78         391 :         mName = aCopy.mName;
      79         391 :     }
      80             : 
      81           7 :     bool IsNamed() const {
      82           7 :         return mType == eFamily_named || mType == eFamily_named_quoted;
      83             :     }
      84             : 
      85           1 :     bool IsGeneric() const {
      86           1 :         return !IsNamed();
      87             :     }
      88             : 
      89           0 :     void AppendToString(nsAString& aFamilyList, bool aQuotes = true) const {
      90           0 :         switch (mType) {
      91             :             case eFamily_named:
      92           0 :                 aFamilyList.Append(mName);
      93           0 :                 break;
      94             :             case eFamily_named_quoted:
      95           0 :                 if (aQuotes) {
      96           0 :                     aFamilyList.Append('"');
      97             :                 }
      98           0 :                 aFamilyList.Append(mName);
      99           0 :                 if (aQuotes) {
     100           0 :                     aFamilyList.Append('"');
     101             :                 }
     102           0 :                 break;
     103             :             case eFamily_serif:
     104           0 :                 aFamilyList.AppendLiteral("serif");
     105           0 :                 break;
     106             :             case eFamily_sans_serif:
     107           0 :                 aFamilyList.AppendLiteral("sans-serif");
     108           0 :                 break;
     109             :             case eFamily_monospace:
     110           0 :                 aFamilyList.AppendLiteral("monospace");
     111           0 :                 break;
     112             :             case eFamily_cursive:
     113           0 :                 aFamilyList.AppendLiteral("cursive");
     114           0 :                 break;
     115             :             case eFamily_fantasy:
     116           0 :                 aFamilyList.AppendLiteral("fantasy");
     117           0 :                 break;
     118             :             case eFamily_moz_fixed:
     119           0 :                 aFamilyList.AppendLiteral("-moz-fixed");
     120           0 :                 break;
     121             :             default:
     122           0 :                 break;
     123             :         }
     124           0 :     }
     125             : 
     126             :     // helper method that converts generic names to the right enum value
     127             :     static FontFamilyName
     128           8 :     Convert(const nsAString& aFamilyOrGenericName) {
     129             :         // should only be passed a single font - not entirely correct, a family
     130             :         // *could* have a comma in it but in practice never does so
     131             :         // for debug purposes this is fine
     132           8 :         NS_ASSERTION(aFamilyOrGenericName.FindChar(',') == -1,
     133             :                      "Convert method should only be passed a single family name");
     134             : 
     135           8 :         FontFamilyType genericType = eFamily_none;
     136           8 :         if (aFamilyOrGenericName.LowerCaseEqualsLiteral("serif")) {
     137           7 :             genericType = eFamily_serif;
     138           1 :         } else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("sans-serif")) {
     139           0 :             genericType = eFamily_sans_serif;
     140           1 :         } else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("monospace")) {
     141           0 :             genericType = eFamily_monospace;
     142           1 :         } else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("cursive")) {
     143           0 :             genericType = eFamily_cursive;
     144           1 :         } else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("fantasy")) {
     145           0 :             genericType = eFamily_fantasy;
     146           1 :         } else if (aFamilyOrGenericName.LowerCaseEqualsLiteral("-moz-fixed")) {
     147           0 :             genericType = eFamily_moz_fixed;
     148             :         } else {
     149           1 :             return FontFamilyName(aFamilyOrGenericName, eUnquotedName);
     150             :         }
     151             : 
     152           7 :         return FontFamilyName(genericType);
     153             :     }
     154             : 
     155             :     // memory reporting
     156           0 :     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     157           0 :         return mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
     158             :     }
     159             : 
     160             :     FontFamilyType mType;
     161             :     nsString       mName; // empty if mType != eFamily_named
     162             : };
     163             : 
     164             : inline bool
     165         445 : operator==(const FontFamilyName& a, const FontFamilyName& b) {
     166         445 :     return a.mType == b.mType && a.mName == b.mName;
     167             : }
     168             : 
     169             : /**
     170             :  * font family list, array of font families and a default font type.
     171             :  * font family names are either named strings or generics. the default
     172             :  * font type is used to preserve the variable font fallback behavior
     173             :  */ 
     174             : 
     175         135 : class FontFamilyList {
     176             : public:
     177          16 :     FontFamilyList()
     178          16 :         : mDefaultFontType(eFamily_none)
     179             :     {
     180          16 :     }
     181             : 
     182         224 :     explicit FontFamilyList(FontFamilyType aGenericType)
     183         224 :         : mDefaultFontType(eFamily_none)
     184             :     {
     185         224 :         Append(FontFamilyName(aGenericType));
     186         224 :     }
     187             : 
     188           6 :     FontFamilyList(const nsAString& aFamilyName,
     189             :                    QuotedName aQuoted)
     190           6 :         : mDefaultFontType(eFamily_none)
     191             :     {
     192           6 :         Append(FontFamilyName(aFamilyName, aQuoted));
     193           6 :     }
     194             : 
     195         117 :     FontFamilyList(const FontFamilyList& aOther)
     196         117 :         : mFontlist(aOther.mFontlist)
     197         117 :         , mDefaultFontType(aOther.mDefaultFontType)
     198             :     {
     199         117 :     }
     200             : 
     201         249 :     void Append(const FontFamilyName& aFamilyName) {
     202         249 :         mFontlist.AppendElement(aFamilyName);
     203         249 :     }
     204             : 
     205           0 :     void Append(const nsTArray<nsString>& aFamilyNameList) {
     206           0 :         uint32_t len = aFamilyNameList.Length();
     207           0 :         for (uint32_t i = 0; i < len; i++) {
     208           0 :             mFontlist.AppendElement(FontFamilyName(aFamilyNameList[i],
     209           0 :                                                    eUnquotedName));
     210             :         }
     211           0 :     }
     212             : 
     213           0 :     void Clear() {
     214           0 :         mFontlist.Clear();
     215           0 :     }
     216             : 
     217           0 :     uint32_t Length() const {
     218           0 :         return mFontlist.Length();
     219             :     }
     220             : 
     221          16 :     bool IsEmpty() const {
     222          16 :       return mFontlist.IsEmpty();
     223             :     }
     224             : 
     225           6 :     const nsTArray<FontFamilyName>& GetFontlist() const {
     226           6 :         return mFontlist;
     227             :     }
     228             : 
     229         445 :     bool Equals(const FontFamilyList& aFontlist) const {
     230         890 :         return mFontlist == aFontlist.mFontlist &&
     231         890 :                mDefaultFontType == aFontlist.mDefaultFontType;
     232             :     }
     233             : 
     234           0 :     FontFamilyType FirstGeneric() const {
     235           0 :         uint32_t len = mFontlist.Length();
     236           0 :         for (uint32_t i = 0; i < len; i++) {
     237           0 :             const FontFamilyName& name = mFontlist[i];
     238           0 :             if (name.IsGeneric()) {
     239           0 :                 return name.mType;
     240             :             }
     241             :         }
     242           0 :         return eFamily_none;
     243             :     }
     244             : 
     245           0 :     bool HasGeneric() const {
     246           0 :         return FirstGeneric() != eFamily_none;
     247             :     }
     248             : 
     249           0 :     bool HasDefaultGeneric() const {
     250           0 :         uint32_t len = mFontlist.Length();
     251           0 :         for (uint32_t i = 0; i < len; i++) {
     252           0 :             const FontFamilyName& name = mFontlist[i];
     253           0 :             if (name.mType == mDefaultFontType) {
     254           0 :                 return true;
     255             :             }
     256             :         }
     257           0 :         return false;
     258             :     }
     259             : 
     260             :     // Find the first generic (but ignoring cursive and fantasy, as they are
     261             :     // rarely configured in any useful way) in the list.
     262             :     // If found, move it to the start and return true; else return false.
     263           0 :     bool PrioritizeFirstGeneric() {
     264           0 :         uint32_t len = mFontlist.Length();
     265           0 :         for (uint32_t i = 0; i < len; i++) {
     266           0 :             const FontFamilyName name = mFontlist[i];
     267           0 :             if (name.IsGeneric()) {
     268           0 :                 if (name.mType == eFamily_cursive ||
     269           0 :                     name.mType == eFamily_fantasy) {
     270           0 :                     continue;
     271             :                 }
     272           0 :                 if (i > 0) {
     273           0 :                     mFontlist.RemoveElementAt(i);
     274           0 :                     mFontlist.InsertElementAt(0, name);
     275             :                 }
     276           0 :                 return true;
     277             :             }
     278             :         }
     279           0 :         return false;
     280             :     }
     281             : 
     282           0 :     void PrependGeneric(FontFamilyType aType) {
     283           0 :         mFontlist.InsertElementAt(0, FontFamilyName(aType));
     284           0 :     }
     285             : 
     286           0 :     void ToString(nsAString& aFamilyList,
     287             :                   bool aQuotes = true,
     288             :                   bool aIncludeDefault = false) const {
     289           0 :         aFamilyList.Truncate();
     290           0 :         uint32_t len = mFontlist.Length();
     291           0 :         for (uint32_t i = 0; i < len; i++) {
     292           0 :             if (i != 0) {
     293           0 :                 aFamilyList.Append(',');
     294             :             }
     295           0 :             const FontFamilyName& name = mFontlist[i];
     296           0 :             name.AppendToString(aFamilyList, aQuotes);
     297             :         }
     298           0 :         if (aIncludeDefault && mDefaultFontType != eFamily_none) {
     299           0 :             if (!aFamilyList.IsEmpty()) {
     300           0 :                 aFamilyList.Append(',');
     301             :             }
     302           0 :             if (mDefaultFontType == eFamily_serif) {
     303           0 :                 aFamilyList.AppendLiteral("serif");
     304             :             } else {
     305           0 :                 aFamilyList.AppendLiteral("sans-serif");
     306             :             }
     307             :         }
     308           0 :     }
     309             : 
     310             :     // searches for a specific non-generic name, lowercase comparison
     311           0 :     bool Contains(const nsAString& aFamilyName) const {
     312           0 :         uint32_t len = mFontlist.Length();
     313           0 :         nsAutoString fam(aFamilyName);
     314           0 :         ToLowerCase(fam);
     315           0 :         for (uint32_t i = 0; i < len; i++) {
     316           0 :             const FontFamilyName& name = mFontlist[i];
     317           0 :             if (name.mType != eFamily_named &&
     318           0 :                 name.mType != eFamily_named_quoted) {
     319           0 :                 continue;
     320             :             }
     321           0 :             nsAutoString listname(name.mName);
     322           0 :             ToLowerCase(listname);
     323           0 :             if (listname.Equals(fam)) {
     324           0 :                 return true;
     325             :             }
     326             :         }
     327           0 :         return false;
     328             :     }
     329             : 
     330           6 :     FontFamilyType GetDefaultFontType() const { return mDefaultFontType; }
     331           6 :     void SetDefaultFontType(FontFamilyType aType) {
     332           6 :         NS_ASSERTION(aType == eFamily_none || aType == eFamily_serif ||
     333             :                      aType == eFamily_sans_serif,
     334             :                      "default font type must be either serif or sans-serif");
     335           6 :         mDefaultFontType = aType;
     336           6 :     }
     337             : 
     338             :     // memory reporting
     339           0 :     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     340           0 :         size_t n = 0;
     341           0 :         n += mFontlist.ShallowSizeOfExcludingThis(aMallocSizeOf);
     342           0 :         for (size_t i = 0; i < mFontlist.Length(); i++) {
     343           0 :             n += mFontlist[i].SizeOfExcludingThis(aMallocSizeOf);
     344             :         }
     345           0 :         return n;
     346             :     }
     347             : 
     348           0 :     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     349           0 :         return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     350             :     }
     351             : 
     352             : private:
     353             :     nsTArray<FontFamilyName>   mFontlist;
     354             :     FontFamilyType             mDefaultFontType; // none, serif or sans-serif
     355             : };
     356             : 
     357             : inline bool
     358         445 : operator==(const FontFamilyList& a, const FontFamilyList& b) {
     359         445 :     return a.Equals(b);
     360             : }
     361             : 
     362             : } // namespace mozilla
     363             : 
     364             : #endif /* GFX_FONT_FAMILY_LIST_H */

Generated by: LCOV version 1.13