Bug 463806 - [PATCH][@font-face] Downloaded font activation on Mac may fail due to...
[wine-gecko.git] / gfx / thebes / src / gfxQuartzFontCache.h
blob0be3a16b5f37fb882b3bfef2b9cf94be6e2f8acd
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 Corporation code.
17 * The Initial Developer of the Original Code is Mozilla Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2006
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Vladimir Vukicevic <vladimir@pobox.com>
23 * Masayuki Nakano <masayuki@d-toybox.com>
24 * John Daggett <jdaggett@mozilla.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef GFXQUARTZFONTCACHE_H_
41 #define GFXQUARTZFONTCACHE_H_
43 #include "nsDataHashtable.h"
44 #include "nsRefPtrHashtable.h"
46 #include "gfxFontUtils.h"
47 #include "gfxAtsuiFonts.h"
48 #include "gfxPlatform.h"
50 #include <Carbon/Carbon.h>
52 #include "nsUnicharUtils.h"
53 #include "nsVoidArray.h"
55 // used when picking fallback font
56 struct FontSearch {
57 FontSearch(const PRUint32 aCharacter, gfxFont *aFont) :
58 ch(aCharacter), fontToMatch(aFont), matchRank(0) {
60 const PRUint32 ch;
61 gfxFont *fontToMatch;
62 PRInt32 matchRank;
63 nsRefPtr<MacOSFontEntry> bestMatch;
66 class MacOSFamilyEntry;
67 class gfxQuartzFontCache;
69 // a single member of a font family (i.e. a single face, such as Times Italic)
70 class MacOSFontEntry : public gfxFontEntry
72 public:
73 friend class gfxQuartzFontCache;
75 // initialize with Apple-type weight [1..14]
76 MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aAppleWeight, PRUint32 aTraits,
77 MacOSFamilyEntry *aFamily);
79 const nsString& FamilyName();
81 PRUint32 Traits() { return mTraits; }
83 ATSUFontID GetFontID();
84 nsresult ReadCMAP();
86 protected:
87 // for use with data fonts
88 MacOSFontEntry(const nsAString& aPostscriptName, ATSUFontID aFontID,
89 PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
90 gfxUserFontData *aUserFontData);
92 PRUint32 mTraits;
93 MacOSFamilyEntry *mFamily;
95 ATSUFontID mATSUFontID;
96 PRPackedBool mATSUIDInitialized;
99 // helper class for adding other family names back into font cache
100 class AddOtherFamilyNameFunctor;
102 // a single font family, referencing one or more faces
103 class MacOSFamilyEntry : public gfxFontFamily
105 public:
107 friend class gfxQuartzFontCache;
109 // name is canonical font family name returned from NSFontManager
110 MacOSFamilyEntry(nsAString &aName) :
111 gfxFontFamily(aName), mOtherFamilyNamesInitialized(PR_FALSE), mHasOtherFamilyNames(PR_FALSE)
114 virtual ~MacOSFamilyEntry() {}
116 virtual void LocalizedName(nsAString& aLocalizedName);
117 virtual PRBool HasOtherFamilyNames();
119 nsTArray<nsRefPtr<MacOSFontEntry> >& GetFontList() { return mAvailableFonts; }
121 void AddFontEntry(nsRefPtr<MacOSFontEntry> aFontEntry) {
122 mAvailableFonts.AppendElement(aFontEntry);
125 // decides the right face for a given style, never fails
126 // may return a face that doesn't precisely match (e.g. normal face when no italic face exists)
127 // aNeedsBold is set to true when bolder face couldn't be found, false otherwise
128 MacOSFontEntry* FindFont(const gfxFontStyle* aStyle, PRBool& aNeedsBold);
130 // iterates over faces looking for a match with a given characters
131 // used as part of the font fallback process
132 void FindFontForChar(FontSearch *aMatchData);
134 // read in other family names, if any, and use functor to add each into cache
135 virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor);
137 // search for a specific face using the Postscript name
138 MacOSFontEntry* FindFont(const nsAString& aPostscriptName);
140 // read in cmaps for all the faces
141 void ReadCMAP() {
142 PRUint32 i, numFonts = mAvailableFonts.Length();
143 for (i = 0; i < numFonts; i++)
144 mAvailableFonts[i]->ReadCMAP();
147 // set whether this font family is in "bad" underline offset blacklist.
148 void SetBadUnderlineFont(PRBool aIsBadUnderlineFont) {
149 PRUint32 i, numFonts = mAvailableFonts.Length();
150 for (i = 0; i < numFonts; i++)
151 mAvailableFonts[i]->mIsBadUnderlineFont = aIsBadUnderlineFont;
154 protected:
156 // add font entries into array that match specified traits, returned in array listed by weight
157 // i.e. aFontsForWeights[4] ==> pointer to the font entry for a 400-weight face on return
158 // returns true if one or more faces found
159 PRBool FindFontsWithTraits(gfxFontEntry* aFontsForWeights[], PRUint32 aPosTraitsMask,
160 PRUint32 aNegTraitsMask);
162 PRBool FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gfxFontStyle& aFontStyle);
164 nsTArray<nsRefPtr<MacOSFontEntry> > mAvailableFonts;
165 PRPackedBool mOtherFamilyNamesInitialized;
166 PRPackedBool mHasOtherFamilyNames;
169 // special-case situation where specific faces need to be treated as separate font family
170 class SingleFaceFamily : public MacOSFamilyEntry
172 public:
173 SingleFaceFamily(nsAString &aName) :
174 MacOSFamilyEntry(aName)
177 virtual ~SingleFaceFamily() {}
179 virtual void LocalizedName(nsAString& aLocalizedName);
181 // read in other family names, if any, and use functor to add each into cache
182 virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor);
185 class gfxQuartzFontCache : private gfxFontInfoLoader {
186 public:
187 static gfxQuartzFontCache* SharedFontCache() {
188 return sSharedFontCache;
191 static nsresult Init() {
192 NS_ASSERTION(!sSharedFontCache, "What's this doing here?");
193 sSharedFontCache = new gfxQuartzFontCache();
194 return sSharedFontCache ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
196 // It's OK to call Shutdown if we never actually started or if
197 // we already shut down.
198 static void Shutdown() {
199 delete sSharedFontCache;
200 sSharedFontCache = nsnull;
203 // methods used by gfxPlatformMac
205 void GetFontList (const nsACString& aLangGroup,
206 const nsACString& aGenericFamily,
207 nsStringArray& aListOfFonts);
208 PRBool ResolveFontName(const nsAString& aFontName,
209 nsAString& aResolvedFontName);
210 PRBool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
211 void UpdateFontList() { InitFontList(); }
213 void GetFontFamilyList(nsTArray<nsRefPtr<MacOSFamilyEntry> >& aFamilyArray);
215 MacOSFontEntry* FindFontForChar(const PRUint32 aCh, gfxFont *aPrevFont);
217 MacOSFamilyEntry* FindFamily(const nsAString& aFamily);
219 MacOSFontEntry* FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, PRBool& aNeedsBold);
221 MacOSFontEntry* GetDefaultFont(const gfxFontStyle* aStyle, PRBool& aNeedsBold);
223 static PRInt32 AppleWeightToCSSWeight(PRInt32 aAppleWeight);
225 PRBool GetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<MacOSFamilyEntry> > *array);
226 void SetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<MacOSFamilyEntry> >& array);
228 void AddOtherFamilyName(MacOSFamilyEntry *aFamilyEntry, nsAString& aOtherFamilyName);
230 gfxFontEntry* LookupLocalFont(const nsAString& aFontName);
232 gfxFontEntry* MakePlatformFont(const gfxFontEntry *aProxyEntry, const PRUint8 *aFontData, PRUint32 aLength);
234 private:
235 static PLDHashOperator FindFontForCharProc(nsStringHashKey::KeyType aKey,
236 nsRefPtr<MacOSFamilyEntry>& aFamilyEntry,
237 void* userArg);
239 static gfxQuartzFontCache *sSharedFontCache;
241 gfxQuartzFontCache();
243 // initialize font lists
244 void InitFontList();
245 void ReadOtherFamilyNamesForFamily(const nsAString& aFamilyName);
247 // separate initialization for reading in name tables, since this is expensive
248 void InitOtherFamilyNames();
250 // special case font faces treated as font families (set via prefs)
251 void InitSingleFaceList();
253 // commonly used fonts for which the name table should be loaded at startup
254 void PreloadNamesList();
256 // initialize the bad underline blacklist from pref.
257 void InitBadUnderlineList();
259 // eliminate faces which have the same ATSUI id
260 void EliminateDuplicateFaces(const nsAString& aFamilyName);
262 // explicitly set font traits for all faces to fixed-pitch
263 void SetFixedPitch(const nsAString& aFamilyName);
265 static PLDHashOperator InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
266 nsRefPtr<MacOSFamilyEntry>& aFamilyEntry,
267 void* userArg);
269 void GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult);
270 static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg);
271 static int PrefChangedCallback(const char *aPrefName, void *closure);
273 static PLDHashOperator
274 HashEnumFuncForFamilies(nsStringHashKey::KeyType aKey,
275 nsRefPtr<MacOSFamilyEntry>& aFamilyEntry,
276 void* aUserArg);
278 // gfxFontInfoLoader overrides, used to load in font cmaps
279 virtual void InitLoader();
280 virtual PRBool RunLoader();
281 virtual void FinishLoader();
283 // canonical family name ==> family entry (unique, one name per family entry)
284 nsRefPtrHashtable<nsStringHashKey, MacOSFamilyEntry> mFontFamilies;
286 // other family name ==> family entry (not unique, can have multiple names per
287 // family entry, only names *other* than the canonical names are stored here)
288 nsRefPtrHashtable<nsStringHashKey, MacOSFamilyEntry> mOtherFamilyNames;
290 // cached pref font lists
291 // maps list of family names ==> array of family entries, one per lang group
292 nsDataHashtable<nsUint32HashKey, nsTArray<nsRefPtr<MacOSFamilyEntry> > > mPrefFonts;
294 // when system-wide font lookup fails for a character, cache it to skip future searches
295 gfxSparseBitSet mCodepointsWithNoFonts;
297 // flag set after InitOtherFamilyNames is called upon first name lookup miss
298 PRPackedBool mOtherFamilyNamesInitialized;
300 // data used as part of the font cmap loading process
301 nsTArray<nsRefPtr<MacOSFamilyEntry> > mFontFamiliesToLoad;
302 PRUint32 mStartIndex;
303 PRUint32 mIncrement;
304 PRUint32 mNumFamilies;
306 // keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
307 PRUint32 mATSGeneration;
309 enum {
310 kATSGenerationInitial = -1
314 #endif /* GFXQUARTZFONTCACHE_H_ */