Bug 460926 A11y hierachy is broken on Ubuntu 8.10 (GNOME 2.24), r=Evan.Yan sr=roc
[wine-gecko.git] / gfx / thebes / src / gfxFontconfigUtils.h
blob029548fc9a094bc2ff9b03eefb42791e519b681e
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
13 * License.
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.
21 * Contributor(s):
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"
45 #include "nsTArray.h"
46 #include "nsTHashtable.h"
48 #include <fontconfig/fontconfig.h>
51 NS_SPECIALIZE_TEMPLATE
52 class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
54 public:
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>
62 public:
63 static void Release(FcFontSet *ptr) { FcFontSetDestroy(ptr); }
66 NS_SPECIALIZE_TEMPLATE
67 class nsAutoRefTraits<FcCharSet> : public nsPointerRefTraits<FcCharSet>
69 public:
70 static void Release(FcCharSet *ptr) { FcCharSetDestroy(ptr); }
74 class gfxFontNameList : public nsTArray<nsString>
76 public:
77 THEBES_INLINE_DECL_REFCOUNTING(gfxFontNameList)
78 PRBool Exists(nsAString& aName);
81 class gfxFontconfigUtils {
82 public:
83 gfxFontconfigUtils();
85 static gfxFontconfigUtils* GetFontconfigUtils() {
86 if (!sUtils)
87 sUtils = new gfxFontconfigUtils();
88 return sUtils;
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);
150 protected:
151 // Base class for hash table entries with case-insensitive FcChar8
152 // string keys.
153 class FcStrEntryBase : public PLDHashEntryHdr {
154 public:
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
168 // important.
169 static PLDHashNumber HashKey(const FcChar8 *aKey) {
170 PRUint32 hash = 0;
171 for (const FcChar8 *c = aKey; *c != '\0'; ++c) {
172 hash = PR_ROTATE_LEFT32(hash, 3) ^ FcToLower(*c);
174 return hash;
176 enum { ALLOW_MEMMOVE = PR_TRUE };
179 public:
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
184 // font pattern.
185 class DepFcStrEntry : public FcStrEntryBase {
186 public:
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)
192 : mKey(NULL) { }
194 DepFcStrEntry(const DepFcStrEntry& toCopy)
195 : mKey(toCopy.mKey) { }
197 PRBool KeyEquals(KeyTypePointer aKey) const {
198 return FcStrCmpIgnoreCase(aKey, mKey) == 0;
201 const FcChar8 *mKey;
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 {
208 public:
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)); }
227 private:
228 nsCString mKey;
231 protected:
232 class FontsByFcStrEntry : public DepFcStrEntry {
233 public:
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() {
244 return mFonts;
246 private:
247 nsTArray< nsCountedRef<FcPattern> > mFonts;
250 class LangSupportEntry : public CopiedFcStrEntry {
251 public:
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,
271 PRBool aWithFonts);
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 */