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
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/
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
15 * The Original Code is Mozilla Japan code.
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.
22 * Masayuki Nakano <masayuki@d-toybox.com>
23 * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
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.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef GFX_FONTCONFIG_UTILS_H
40 #define GFX_FONTCONFIG_UTILS_H
42 #include "gfxPlatform.h"
44 #include "nsAutoRef.h"
46 #include "nsTHashtable.h"
48 #include <fontconfig/fontconfig.h>
51 NS_SPECIALIZE_TEMPLATE
52 class nsAutoRefTraits
<FcPattern
> : public nsPointerRefTraits
<FcPattern
>
55 static void Release(FcPattern
*ptr
) { FcPatternDestroy(ptr
); }
56 static void AddRef(FcPattern
*ptr
) { FcPatternReference(ptr
); }
59 NS_SPECIALIZE_TEMPLATE
60 class nsAutoRefTraits
<FcFontSet
> : public nsPointerRefTraits
<FcFontSet
>
63 static void Release(FcFontSet
*ptr
) { FcFontSetDestroy(ptr
); }
66 NS_SPECIALIZE_TEMPLATE
67 class nsAutoRefTraits
<FcCharSet
> : public nsPointerRefTraits
<FcCharSet
>
70 static void Release(FcCharSet
*ptr
) { FcCharSetDestroy(ptr
); }
74 class gfxFontNameList
: public nsTArray
<nsString
>
77 THEBES_INLINE_DECL_REFCOUNTING(gfxFontNameList
)
78 PRBool
Exists(nsAString
& aName
);
81 class gfxFontconfigUtils
{
85 static gfxFontconfigUtils
* GetFontconfigUtils() {
87 sUtils
= new gfxFontconfigUtils();
91 static void Shutdown();
93 nsresult
GetFontList(const nsACString
& aLangGroup
,
94 const nsACString
& aGenericFamily
,
95 nsStringArray
& aListOfFonts
);
97 nsresult
UpdateFontList();
99 nsresult
ResolveFontName(const nsAString
& aFontName
,
100 gfxPlatform::FontResolverCallback aCallback
,
101 void *aClosure
, PRBool
& aAborted
);
103 nsresult
GetStandardFamilyName(const nsAString
& aFontName
, nsAString
& aFamilyName
);
105 const nsTArray
< nsCountedRef
<FcPattern
> >&
106 GetFontsForFamily(const FcChar8
*aFamilyName
);
108 // Returns the best support that any font offers for |aLang|.
109 FcLangResult
GetBestLangSupport(const FcChar8
*aLang
);
110 // Returns the fonts offering this best level of support.
111 const nsTArray
< nsCountedRef
<FcPattern
> >&
112 GetFontsForLang(const FcChar8
*aLang
);
114 // Retuns the language support for a fontconfig font pattern
115 static FcLangResult
GetLangSupport(FcPattern
*aFont
, const FcChar8
*aLang
);
117 // Conversions between FcChar8*, which is unsigned char*,
118 // and (signed) char*, that check the type of the argument.
119 static const FcChar8
*ToFcChar8(const char *aCharPtr
)
121 return reinterpret_cast<const FcChar8
*>(aCharPtr
);
123 static const char *ToCString(const FcChar8
*aChar8Ptr
)
125 return reinterpret_cast<const char*>(aChar8Ptr
);
128 static PRUint8
FcSlantToThebesStyle(int aFcSlant
);
129 static PRUint8
GetThebesStyle(FcPattern
*aPattern
); // slant
130 static PRUint16
GetThebesWeight(FcPattern
*aPattern
);
132 static int GetFcSlant(const gfxFontStyle
& aFontStyle
);
133 // Returns a precise FC_WEIGHT from CSS weight |aBaseWeight|.
134 static int FcWeightForBaseWeight(PRInt8 aBaseWeight
);
136 // This doesn't consider which faces exist, and so initializes the pattern
137 // using a guessed weight, and doesn't consider sizeAdjust.
138 static nsReturnRef
<FcPattern
>
139 NewPattern(const nsTArray
<nsString
>& aFamilies
,
140 const gfxFontStyle
& aFontStyle
, const char *aLang
);
143 * @param aLangGroup [in] a Mozilla langGroup.
144 * @param aFcLang [out] returns a language suitable for fontconfig
145 * matching |aLangGroup| or an empty string if no match is found.
147 static void GetSampleLangForGroup(const nsACString
& aLangGroup
,
148 nsACString
*aFcLang
);
151 // Base class for hash table entries with case-insensitive FcChar8
153 class FcStrEntryBase
: public PLDHashEntryHdr
{
155 typedef const FcChar8
*KeyType
;
156 typedef const FcChar8
*KeyTypePointer
;
158 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return aKey
; }
159 // Case-insensitive hash.
161 // fontconfig always ignores case of ASCII characters in family
162 // names and languages, but treatment of whitespace in families is
163 // not consistent. FcFontSort and FcFontMatch ignore whitespace
164 // except for whitespace in the first character, while FcFontList
165 // and config subsitution tests require whitespace to match
166 // exactly. CSS 2.1 implies that whitespace is important in the
167 // font-family property. FcStrCmpIgnoreCase considers whitespace
169 static PLDHashNumber
HashKey(const FcChar8
*aKey
) {
171 for (const FcChar8
*c
= aKey
; *c
!= '\0'; ++c
) {
172 hash
= PR_ROTATE_LEFT32(hash
, 3) ^ FcToLower(*c
);
176 enum { ALLOW_MEMMOVE
= PR_TRUE
};
180 // Hash entry with a dependent const FcChar8* pointer to an external
181 // string for a key (and no data). The user must ensure that the string
182 // associated with the pointer is not destroyed. This entry type is
183 // useful for family name keys as the family name string is held in the
185 class DepFcStrEntry
: public FcStrEntryBase
{
187 // When constructing a new entry in the hashtable, the key is left
188 // blank. The caller of PutEntry() must fill in mKey when NULL. This
189 // provides a mechanism for the caller of PutEntry() to determine
190 // whether the entry has been initialized.
191 DepFcStrEntry(KeyTypePointer aName
)
194 DepFcStrEntry(const DepFcStrEntry
& toCopy
)
195 : mKey(toCopy
.mKey
) { }
197 PRBool
KeyEquals(KeyTypePointer aKey
) const {
198 return FcStrCmpIgnoreCase(aKey
, mKey
) == 0;
204 // Hash entry that uses a copy of an FcChar8 string to store the key.
205 // This entry type is useful for language keys, as languages are usually
206 // not stored as strings in font patterns.
207 class CopiedFcStrEntry
: public FcStrEntryBase
{
209 // When constructing a new entry in the hashtable, the key is void.
210 // The caller of PutEntry() must call InitKey() when IsKeyInitialized()
211 // returns false. This provides a mechanism for the caller of
212 // PutEntry() to determine whether the entry has been initialized.
213 CopiedFcStrEntry(KeyTypePointer aName
) {
214 mKey
.SetIsVoid(PR_TRUE
);
217 CopiedFcStrEntry(const CopiedFcStrEntry
& toCopy
)
218 : mKey(toCopy
.mKey
) { }
220 PRBool
KeyEquals(KeyTypePointer aKey
) const {
221 return FcStrCmpIgnoreCase(aKey
, ToFcChar8(mKey
.get())) == 0;
224 PRBool
IsKeyInitialized() { return !mKey
.IsVoid(); }
225 void InitKey(const FcChar8
* aKey
) { mKey
.Assign(ToCString(aKey
)); }
232 class FontsByFcStrEntry
: public DepFcStrEntry
{
234 FontsByFcStrEntry(KeyTypePointer aName
)
235 : DepFcStrEntry(aName
) { }
237 FontsByFcStrEntry(const FontsByFcStrEntry
& toCopy
)
238 : DepFcStrEntry(toCopy
), mFonts(toCopy
.mFonts
) { }
240 PRBool
AddFont(FcPattern
*aFont
) {
241 return mFonts
.AppendElement(aFont
) != nsnull
;
243 const nsTArray
< nsCountedRef
<FcPattern
> >& GetFonts() {
247 nsTArray
< nsCountedRef
<FcPattern
> > mFonts
;
250 class LangSupportEntry
: public CopiedFcStrEntry
{
252 LangSupportEntry(KeyTypePointer aName
)
253 : CopiedFcStrEntry(aName
) { }
255 LangSupportEntry(const LangSupportEntry
& toCopy
)
256 : CopiedFcStrEntry(toCopy
), mSupport(toCopy
.mSupport
) { }
258 FcLangResult mSupport
;
259 nsTArray
< nsCountedRef
<FcPattern
> > mFonts
;
262 static gfxFontconfigUtils
* sUtils
;
264 PRBool
IsExistingFamily(const nsCString
& aFamilyName
);
266 nsresult
GetFontListInternal(nsCStringArray
& aListOfFonts
,
267 const nsACString
& aLangGroup
);
268 nsresult
UpdateFontListInternal(PRBool aForce
= PR_FALSE
);
270 LangSupportEntry
*GetLangSupportEntry(const FcChar8
*aLang
,
273 nsTHashtable
<FontsByFcStrEntry
> mFontsByFamily
;
274 nsTHashtable
<LangSupportEntry
> mLangSupportTable
;
275 const nsTArray
< nsCountedRef
<FcPattern
> > mEmptyPatternArray
;
277 nsCStringArray mAliasForMultiFonts
;
279 FcConfig
*mLastConfig
;
282 #endif /* GFX_FONTCONFIG_UTILS_H */