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 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.
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
57 FontSearch(const PRUint32 aCharacter
, gfxFont
*aFont
) :
58 ch(aCharacter
), fontToMatch(aFont
), matchRank(0) {
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
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();
87 // for use with data fonts
88 MacOSFontEntry(const nsAString
& aPostscriptName
, ATSUFontID aFontID
,
89 PRUint16 aWeight
, PRUint16 aStretch
, PRUint32 aItalicStyle
,
90 gfxUserFontData
*aUserFontData
);
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
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
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
;
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
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
{
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
);
235 static PLDHashOperator
FindFontForCharProc(nsStringHashKey::KeyType aKey
,
236 nsRefPtr
<MacOSFamilyEntry
>& aFamilyEntry
,
239 static gfxQuartzFontCache
*sSharedFontCache
;
241 gfxQuartzFontCache();
243 // initialize font lists
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
,
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
,
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
;
304 PRUint32 mNumFamilies
;
306 // keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
307 PRUint32 mATSGeneration
;
310 kATSGenerationInitial
= -1
314 #endif /* GFXQUARTZFONTCACHE_H_ */