mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 502906 part 1: eliminate backend-specific gfxFontGroup subclasses on Mac OS X. r=jdaggett
This commit is contained in:
parent
2de2187247
commit
04d2aac3f3
@ -51,8 +51,6 @@
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
class gfxAtsuiFontGroup;
|
||||
|
||||
class MacOSFontEntry;
|
||||
|
||||
#define kLiGothicBadCharUnicode 0x775B // ATSUI failure on 10.6 (bug 532346)
|
||||
@ -87,11 +85,6 @@ public:
|
||||
virtual void SetupGlyphExtents(gfxContext *aContext, PRUint32 aGlyphID,
|
||||
PRBool aNeedTight, gfxGlyphExtents *aExtents);
|
||||
|
||||
PRBool TestCharacterMap(PRUint32 aCh);
|
||||
|
||||
MacOSFontEntry* GetFontEntry();
|
||||
PRBool Valid() { return mIsValid; }
|
||||
|
||||
protected:
|
||||
const gfxFontStyle *mFontStyle;
|
||||
|
||||
@ -112,107 +105,14 @@ protected:
|
||||
|
||||
void InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef);
|
||||
|
||||
virtual void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
|
||||
virtual PRBool SetupCairoFont(gfxContext *aContext);
|
||||
};
|
||||
|
||||
class THEBES_API gfxAtsuiFontGroup : public gfxFontGroup {
|
||||
public:
|
||||
gfxAtsuiFontGroup(const nsAString& families,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet);
|
||||
virtual ~gfxAtsuiFontGroup() {};
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
||||
virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength,
|
||||
const Parameters* aParams, PRUint32 aFlags);
|
||||
virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength,
|
||||
const Parameters* aParams, PRUint32 aFlags);
|
||||
// When aWrapped is true, the string includes bidi control
|
||||
// characters. The first character will be LRO or LRO to force setting the
|
||||
// direction for all characters, the last character is PDF, and the
|
||||
// second to last character is a non-whitespace character --- to ensure
|
||||
// that there is no "trailing whitespace" in the string, see
|
||||
// http://weblogs.mozillazine.org/roc/archives/2007/02/superlaser_targ.html#comments
|
||||
void MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
||||
PRBool aWrapped, gfxTextRun *aTextRun);
|
||||
|
||||
gfxAtsuiFont* GetFontAt(PRInt32 aFontIndex) {
|
||||
// If it turns out to be hard for all clients that cache font
|
||||
// groups to call UpdateFontList at appropriate times, we could
|
||||
// instead consider just calling UpdateFontList from someplace
|
||||
// more central (such as here).
|
||||
NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
|
||||
"Whoever was caching this font group should have "
|
||||
"called UpdateFontList on it");
|
||||
|
||||
return static_cast<gfxAtsuiFont*>(static_cast<gfxFont*>(mFonts[aFontIndex]));
|
||||
}
|
||||
|
||||
PRBool HasFont(ATSFontRef aFontRef);
|
||||
|
||||
inline gfxAtsuiFont* WhichFontSupportsChar(nsTArray< nsRefPtr<gfxFont> >& aFontList,
|
||||
PRUint32 aCh)
|
||||
{
|
||||
PRUint32 len = aFontList.Length();
|
||||
for (PRUint32 i = 0; i < len; i++) {
|
||||
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(aFontList.ElementAt(i).get());
|
||||
if (font->TestCharacterMap(aCh))
|
||||
return font;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// search through pref fonts for a character, return nsnull if no matching pref font
|
||||
already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
void UpdateFontList();
|
||||
|
||||
protected:
|
||||
static PRBool FindATSFont(const nsAString& aName,
|
||||
const nsACString& aGenericName,
|
||||
void *closure);
|
||||
|
||||
PRUint32 GuessMaximumStringLength();
|
||||
|
||||
/**
|
||||
* @param aRun the text run to fill in
|
||||
* @param aString the complete text including all wrapper characters
|
||||
* @param aLength the length of aString
|
||||
* @param aLayoutStart the first character of aString that should be
|
||||
* at the start of the ATSUI layout; this skips any wrapper character
|
||||
* used to override direction
|
||||
* @param aLayoutLength the length of the characters that should be
|
||||
* in the ATSUI layout; this excludes any trailing wrapper character
|
||||
* used to override direction
|
||||
* @param aTrailingCharsToIgnore the number of trailing characters
|
||||
* in the ATSUI layout that are not part of the text run
|
||||
* (characters added to ensure correct RTL and kerning behaviour)
|
||||
* @param aTextRunOffset the character offset in the textrun where
|
||||
* the glyph data from the ATSUI layout should be copied
|
||||
* @return true for success
|
||||
*/
|
||||
PRBool InitTextRun(gfxTextRun *aRun,
|
||||
const PRUnichar *aString, PRUint32 aLength,
|
||||
PRUint32 aLayoutStart, PRUint32 aLayoutLength,
|
||||
PRUint32 aOffsetInTextRun, PRUint32 aLengthInTextRun);
|
||||
|
||||
/**
|
||||
* Function to reinitialize our mFonts array and any other data
|
||||
* that depends on mFonts.
|
||||
*/
|
||||
void InitFontList();
|
||||
|
||||
// cache the most recent pref font to avoid general pref font lookup
|
||||
nsRefPtr<gfxFontFamily> mLastPrefFamily;
|
||||
nsRefPtr<gfxAtsuiFont> mLastPrefFont;
|
||||
eFontPrefLang mLastPrefLang; // lang group for last pref font
|
||||
PRBool mLastPrefFirstFont; // is this the first font in the list of pref fonts for this lang group?
|
||||
eFontPrefLang mPageLang;
|
||||
};
|
||||
|
||||
#endif /* not __LP64__ */
|
||||
|
||||
#endif /* GFX_ATSUIFONTS_H */
|
||||
|
@ -49,8 +49,6 @@
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
class gfxCoreTextFontGroup;
|
||||
|
||||
class MacOSFontEntry;
|
||||
|
||||
class gfxCoreTextFont : public gfxFont {
|
||||
@ -101,14 +99,10 @@ public:
|
||||
|
||||
MacOSFontEntry* GetFontEntry();
|
||||
|
||||
PRBool Valid() {
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
// clean up static objects that may have been cached
|
||||
static void Shutdown();
|
||||
|
||||
static CTFontRef CreateCTFontWithDisabledLigatures(ATSFontRef aFont, CGFloat aSize);
|
||||
static CTFontRef CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize);
|
||||
|
||||
protected:
|
||||
const gfxFontStyle *mFontStyle;
|
||||
@ -131,6 +125,17 @@ protected:
|
||||
|
||||
void InitMetrics();
|
||||
|
||||
virtual void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
|
||||
nsresult SetGlyphsFromRun(gfxTextRun *aTextRun,
|
||||
CTRunRef aCTRun,
|
||||
PRInt32 aStringOffset,
|
||||
PRInt32 aLayoutStart,
|
||||
PRInt32 aLayoutLength);
|
||||
|
||||
virtual PRBool SetupCairoFont(gfxContext *aContext);
|
||||
|
||||
static void CreateDefaultFeaturesDescriptor();
|
||||
@ -147,83 +152,4 @@ protected:
|
||||
static CTFontDescriptorRef sDisableLigaturesDescriptor;
|
||||
};
|
||||
|
||||
class THEBES_API gfxCoreTextFontGroup : public gfxFontGroup {
|
||||
public:
|
||||
gfxCoreTextFontGroup(const nsAString& families,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet);
|
||||
virtual ~gfxCoreTextFontGroup() {};
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
||||
virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength,
|
||||
const Parameters* aParams, PRUint32 aFlags);
|
||||
virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength,
|
||||
const Parameters* aParams, PRUint32 aFlags);
|
||||
// When aWrapped is true, the string includes bidi control
|
||||
// characters. The first character will be LRO or LRO to force setting the
|
||||
// direction for all characters, the last character is PDF, and the
|
||||
// second to last character is a non-whitespace character --- to ensure
|
||||
// that there is no "trailing whitespace" in the string, see
|
||||
// http://weblogs.mozillazine.org/roc/archives/2007/02/superlaser_targ.html#comments
|
||||
void MakeTextRunInternal(const PRUnichar *aString, PRUint32 aLength,
|
||||
PRBool aWrapped, gfxTextRun *aTextRun);
|
||||
|
||||
gfxCoreTextFont* GetFontAt(PRInt32 aFontIndex) {
|
||||
return static_cast<gfxCoreTextFont*>(static_cast<gfxFont*>(mFonts[aFontIndex]));
|
||||
}
|
||||
|
||||
PRBool HasFont(ATSFontRef aFontRef);
|
||||
|
||||
inline gfxCoreTextFont* WhichFontSupportsChar(nsTArray< nsRefPtr<gfxFont> >& aFontList,
|
||||
PRUint32 aCh)
|
||||
{
|
||||
PRUint32 len = aFontList.Length();
|
||||
for (PRUint32 i = 0; i < len; i++) {
|
||||
gfxCoreTextFont* font = static_cast<gfxCoreTextFont*>(aFontList.ElementAt(i).get());
|
||||
if (font->TestCharacterMap(aCh))
|
||||
return font;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// search through pref fonts for a character, return nsnull if no matching pref font
|
||||
already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
void UpdateFontList();
|
||||
|
||||
protected:
|
||||
static PRBool FindCTFont(const nsAString& aName,
|
||||
const nsACString& aGenericName,
|
||||
void *closure);
|
||||
|
||||
/**
|
||||
* @param aTextRun the text run to fill in
|
||||
* @param aString the complete text including all wrapper characters
|
||||
* @param aTotalLength the length of aString
|
||||
* @param aLayoutStart the first "real" character of aString, skipping any dir override
|
||||
* @param aLayoutLength the length of the characters that should be actually used
|
||||
*/
|
||||
void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aTotalLength,
|
||||
PRUint32 aLayoutStart,
|
||||
PRUint32 aLayoutLength);
|
||||
|
||||
nsresult SetGlyphsFromRun(gfxTextRun *aTextRun,
|
||||
CTRunRef aCTRun,
|
||||
const PRPackedBool *aUnmatched,
|
||||
PRInt32 aLayoutStart,
|
||||
PRInt32 aLayoutLength);
|
||||
|
||||
// cache the most recent pref font to avoid general pref font lookup
|
||||
nsRefPtr<gfxFontFamily> mLastPrefFamily;
|
||||
nsRefPtr<gfxCoreTextFont> mLastPrefFont;
|
||||
eFontPrefLang mLastPrefLang; // lang group for last pref font
|
||||
PRBool mLastPrefFirstFont; // is this the first font in the list of pref fonts for this lang group?
|
||||
eFontPrefLang mPageLang;
|
||||
};
|
||||
|
||||
#endif /* GFX_CORETEXTFONTS_H */
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "gfxRect.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "gfxFontConstants.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
@ -220,6 +221,8 @@ public:
|
||||
|
||||
const nsString& FamilyName();
|
||||
|
||||
already_AddRefed<gfxFont> GetOrMakeFont(const gfxFontStyle *aStyle, PRBool aNeedsBold);
|
||||
|
||||
nsString mName;
|
||||
|
||||
PRPackedBool mItalic : 1;
|
||||
@ -261,6 +264,11 @@ protected:
|
||||
return NS_ERROR_FAILURE; // all platform subclasses should reimplement this!
|
||||
}
|
||||
|
||||
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold) {
|
||||
NS_NOTREACHED("oops, somebody didn't override CreateFontInstance");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxFontFamily *mFamily;
|
||||
};
|
||||
|
||||
@ -663,6 +671,10 @@ protected:
|
||||
public:
|
||||
virtual ~gfxFont();
|
||||
|
||||
PRBool Valid() {
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
// options for the kind of bounding box to return from measurement
|
||||
typedef enum {
|
||||
LOOSE_INK_EXTENTS,
|
||||
@ -852,6 +864,13 @@ public:
|
||||
return mFontEntry->HasCharacter(ch);
|
||||
}
|
||||
|
||||
virtual void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength) {
|
||||
NS_NOTREACHED("oops, somebody didn't override InitTextRun");
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
|
||||
@ -1685,10 +1704,9 @@ private:
|
||||
};
|
||||
|
||||
class THEBES_API gfxFontGroup : public gfxTextRunFactory {
|
||||
protected:
|
||||
public:
|
||||
gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet *aUserFontSet = nsnull);
|
||||
|
||||
public:
|
||||
virtual ~gfxFontGroup();
|
||||
|
||||
virtual gfxFont *GetFontAt(PRInt32 i) {
|
||||
@ -1715,7 +1733,7 @@ public:
|
||||
|
||||
const gfxFontStyle *GetStyle() const { return &mStyle; }
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle) = 0;
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
||||
/**
|
||||
* The listed characters should not be passed in to MakeTextRun and should
|
||||
@ -1741,7 +1759,7 @@ public:
|
||||
* This calls FetchGlyphExtents on the textrun.
|
||||
*/
|
||||
virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags) = 0;
|
||||
const Parameters *aParams, PRUint32 aFlags);
|
||||
/**
|
||||
* Make a textrun for a given string.
|
||||
* If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the
|
||||
@ -1749,7 +1767,7 @@ public:
|
||||
* This calls FetchGlyphExtents on the textrun.
|
||||
*/
|
||||
virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags) = 0;
|
||||
const Parameters *aParams, PRUint32 aFlags);
|
||||
|
||||
/* helper function for splitting font families on commas and
|
||||
* calling a function for each family to fill the mFonts array
|
||||
@ -1763,6 +1781,12 @@ public:
|
||||
void *closure);
|
||||
PRBool ForEachFont(FontCreationCallback fc, void *closure);
|
||||
|
||||
/**
|
||||
* Check whether a given font (specified by its gfxFontEntry)
|
||||
* is already in the fontgroup's list of actual fonts
|
||||
*/
|
||||
PRBool HasFont(const gfxFontEntry *aFontEntry);
|
||||
|
||||
const nsString& GetFamilies() { return mFamilies; }
|
||||
|
||||
// This returns the preferred underline for this font group.
|
||||
@ -1779,9 +1803,10 @@ public:
|
||||
|
||||
already_AddRefed<gfxFont> FindFontForChar(PRUint32 ch, PRUint32 prevCh, PRUint32 nextCh, gfxFont *aPrevMatchedFont);
|
||||
|
||||
virtual already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh) { return nsnull; }
|
||||
// search through pref fonts for a character, return nsnull if no matching pref font
|
||||
virtual already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
virtual already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh) { return nsnull; }
|
||||
virtual already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
|
||||
|
||||
void ComputeRanges(nsTArray<gfxTextRange>& mRanges, const PRUnichar *aString, PRUint32 begin, PRUint32 end);
|
||||
|
||||
@ -1795,7 +1820,7 @@ public:
|
||||
|
||||
// If there is a user font set, check to see whether the font list or any
|
||||
// caches need updating.
|
||||
virtual void UpdateFontList() { }
|
||||
virtual void UpdateFontList();
|
||||
|
||||
protected:
|
||||
nsString mFamilies;
|
||||
@ -1806,6 +1831,13 @@ protected:
|
||||
gfxUserFontSet* mUserFontSet;
|
||||
PRUint64 mCurrGeneration; // track the current user font set generation, rebuild font list if needed
|
||||
|
||||
// cache the most recent pref font to avoid general pref font lookup
|
||||
nsRefPtr<gfxFontFamily> mLastPrefFamily;
|
||||
nsRefPtr<gfxFont> mLastPrefFont;
|
||||
eFontPrefLang mLastPrefLang; // lang group for last pref font
|
||||
PRBool mLastPrefFirstFont; // is this the first font in the list of pref fonts for this lang group?
|
||||
eFontPrefLang mPageLang;
|
||||
|
||||
// Used for construction/destruction. Not intended to change the font set
|
||||
// as invalidation of font lists and caches is not considered.
|
||||
void SetUserFontSet(gfxUserFontSet *aUserFontSet);
|
||||
@ -1815,6 +1847,10 @@ protected:
|
||||
// you should call this with the *first* bad font.
|
||||
void InitMetricsForBadFont(gfxFont* aBadFont);
|
||||
|
||||
void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength);
|
||||
|
||||
/* If aResolveGeneric is true, then CSS/Gecko generic family names are
|
||||
* replaced with preferred fonts.
|
||||
*
|
||||
@ -1832,10 +1868,14 @@ protected:
|
||||
|
||||
static PRBool FontResolverProc(const nsAString& aName, void *aClosure);
|
||||
|
||||
static PRBool FindPlatformFont(const nsAString& aName,
|
||||
const nsACString& aGenericName,
|
||||
void *closure);
|
||||
|
||||
inline gfxFont* WhichFontSupportsChar(nsTArray< nsRefPtr<gfxFont> >& aFontList, PRUint32 aCh) {
|
||||
PRUint32 len = aFontList.Length();
|
||||
for (PRUint32 i = 0; i < len; i++) {
|
||||
gfxFont* font = aFontList.ElementAt(i).get();
|
||||
gfxFont* font = aFontList.ElementAt(i);
|
||||
if (font && font->HasCharacter(aCh))
|
||||
return font;
|
||||
}
|
||||
|
@ -557,6 +557,43 @@ public:
|
||||
return (ch == 0xFFFD);
|
||||
}
|
||||
|
||||
// Font code may want to know if there is the potential for bidi behavior
|
||||
// to be triggered by any of the characters in a text run; this can be
|
||||
// used to test that possibility.
|
||||
enum {
|
||||
kUnicodeBidiScriptsStart = 0x0590,
|
||||
kUnicodeBidiScriptsEnd = 0x08FF,
|
||||
kUnicodeBidiPresentationStart = 0xFB1D,
|
||||
kUnicodeBidiPresentationEnd = 0xFEFC,
|
||||
kUnicodeFirstHighSurrogateBlock = 0xD800,
|
||||
kUnicodeRLM = 0x200F,
|
||||
kUnicodeRLE = 0x202B,
|
||||
kUnicodeRLO = 0x202E
|
||||
};
|
||||
|
||||
static inline PRBool PotentialRTLChar(PRUnichar aCh) {
|
||||
if (aCh >= kUnicodeBidiScriptsStart && aCh <= kUnicodeBidiScriptsEnd)
|
||||
// bidi scripts Hebrew, Arabic, Syriac, Thaana, N'Ko are all encoded together
|
||||
return PR_TRUE;
|
||||
|
||||
if (aCh == kUnicodeRLM || aCh == kUnicodeRLE || aCh == kUnicodeRLO)
|
||||
// directional controls that trigger bidi layout
|
||||
return PR_TRUE;
|
||||
|
||||
if (aCh >= kUnicodeBidiPresentationStart &&
|
||||
aCh <= kUnicodeBidiPresentationEnd)
|
||||
// presentation forms of Arabic and Hebrew letters
|
||||
return PR_TRUE;
|
||||
|
||||
if ((aCh & 0xFF00) == kUnicodeFirstHighSurrogateBlock)
|
||||
// surrogate that could be part of a bidi supplementary char
|
||||
// (Cypriot, Aramaic, Phoenecian, etc)
|
||||
return PR_TRUE;
|
||||
|
||||
// otherwise we know this char cannot trigger bidi reordering
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRUint8 CharRangeBit(PRUint32 ch);
|
||||
|
||||
// for a given font list pref name, set up a list of font names
|
||||
|
@ -61,6 +61,7 @@ class gfxUserFontSet;
|
||||
class gfxFontEntry;
|
||||
class gfxProxyFontEntry;
|
||||
class gfxPlatformFontList;
|
||||
class gfxTextRun;
|
||||
class nsIURI;
|
||||
|
||||
// pref lang id's for font prefs
|
||||
@ -150,6 +151,8 @@ public:
|
||||
* Font bits
|
||||
*/
|
||||
|
||||
virtual void SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString);
|
||||
|
||||
/**
|
||||
* Fill aListOfFonts with the results of querying the list of font names
|
||||
* that correspond to the given language group or generic font family
|
||||
@ -231,6 +234,9 @@ public:
|
||||
|
||||
void GetPrefFonts(const char *aLangGroup, nsString& array, PRBool aAppendUnicode = PR_TRUE);
|
||||
|
||||
// in some situations, need to make decisions about ambiguous characters, may need to look at multiple pref langs
|
||||
void GetLangPrefs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang);
|
||||
|
||||
/**
|
||||
* Iterate over pref fonts given a list of lang groups. For a single lang
|
||||
* group, multiple pref fonts are possible. If error occurs, returns PR_FALSE,
|
||||
@ -248,6 +254,9 @@ public:
|
||||
// convert a enum constant to lang group string (i.e. eFontPrefLang_ChineseTW ==> "zh-TW")
|
||||
static const char* GetPrefLangName(eFontPrefLang aLang);
|
||||
|
||||
// map a Unicode range (based on char code) to a font language for Preferences
|
||||
static eFontPrefLang GetFontPrefLangFor(PRUint8 aUnicodeRange);
|
||||
|
||||
// returns true if a pref lang is CJK
|
||||
static PRBool IsLangCJK(eFontPrefLang aLang);
|
||||
|
||||
@ -318,6 +327,9 @@ protected:
|
||||
gfxPlatform() { }
|
||||
virtual ~gfxPlatform();
|
||||
|
||||
void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen,
|
||||
eFontPrefLang aCharLang, eFontPrefLang aPageLang);
|
||||
|
||||
/**
|
||||
* Initialize any needed display metrics (such as DPI)
|
||||
*/
|
||||
@ -327,6 +339,8 @@ protected:
|
||||
private:
|
||||
virtual qcms_profile* GetPlatformCMSOutputProfile();
|
||||
|
||||
nsTArray<PRUint32> mCJKPrefLangs;
|
||||
|
||||
nsCOMPtr<nsIObserver> overrideObserver;
|
||||
};
|
||||
|
||||
|
@ -91,9 +91,6 @@ public:
|
||||
nsTArray<nsString>& aListOfFonts);
|
||||
nsresult UpdateFontList();
|
||||
|
||||
// in some situations, need to make decisions about ambiguous characters, may need to look at multiple pref langs
|
||||
void GetLangPrefs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang);
|
||||
|
||||
// Returns the OS X version as returned from Gestalt(gestaltSystemVersion, ...)
|
||||
// Ex: Mac OS X 10.4.x ==> 0x104x
|
||||
PRInt32 OSXVersion();
|
||||
@ -110,21 +107,14 @@ public:
|
||||
#endif
|
||||
|
||||
// record Unicode cluster boundaries in the text run
|
||||
static void SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString);
|
||||
|
||||
// map a Unicode range (based on char code) to a font language for Preferences
|
||||
static eFontPrefLang GetFontPrefLangFor(PRUint8 aUnicodeRange);
|
||||
virtual void SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString);
|
||||
|
||||
private:
|
||||
void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen,
|
||||
eFontPrefLang aCharLang, eFontPrefLang aPageLang);
|
||||
|
||||
virtual qcms_profile* GetPlatformCMSOutputProfile();
|
||||
|
||||
// read in the pref value for the lower threshold on font anti-aliasing
|
||||
static PRUint32 ReadAntiAliasingThreshold();
|
||||
|
||||
nsTArray<PRUint32> mCJKPrefLangs;
|
||||
PRInt32 mOSXVersion;
|
||||
PRUint32 mFontAntiAliasingThreshold;
|
||||
|
||||
|
@ -242,6 +242,8 @@ public:
|
||||
|
||||
virtual ~gfxProxyFontEntry();
|
||||
|
||||
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
|
||||
|
||||
PRPackedBool mIsLoading;
|
||||
nsTArray<gfxFontFaceSrc> mSrcList;
|
||||
PRUint32 mSrcIndex; // index of loading src item
|
||||
|
@ -95,6 +95,11 @@ public:
|
||||
PRBool IsValid() { GetMetrics(); return mIsValid; }
|
||||
GDIFontEntry *GetFontEntry();
|
||||
|
||||
virtual void InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength);
|
||||
|
||||
static already_AddRefed<gfxWindowsFont>
|
||||
GetOrMakeFont(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle,
|
||||
PRBool aNeedsBold = PR_FALSE);
|
||||
|
@ -134,6 +134,10 @@ public:
|
||||
*/
|
||||
virtual PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags);
|
||||
|
||||
#ifndef MOZ_FT2_FONTS
|
||||
virtual void SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString);
|
||||
#endif
|
||||
|
||||
/* Find a FontFamily/FontEntry object that represents a font on your system given a name */
|
||||
gfxFontFamily *FindFontFamily(const nsAString& aName);
|
||||
gfxFontEntry *FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@
|
||||
#include "gfxPlatformFontList.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsBidiUtils.h"
|
||||
#include "nsUnicodeRange.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include "gfxFontTest.h"
|
||||
@ -109,6 +110,27 @@ const nsString& gfxFontEntry::FamilyName()
|
||||
return mFamily->Name();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
gfxFontEntry::GetOrMakeFont(const gfxFontStyle *aStyle, PRBool aNeedsBold)
|
||||
{
|
||||
// the font entry name is the psname, not the family name
|
||||
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(Name(), aStyle);
|
||||
if (!font) {
|
||||
gfxFont *newFont = CreateFontInstance(aStyle, aNeedsBold);
|
||||
if (!newFont)
|
||||
return nsnull;
|
||||
if (!newFont->Valid()) {
|
||||
delete newFont;
|
||||
return nsnull;
|
||||
}
|
||||
font = newFont;
|
||||
gfxFontCache::GetCache()->AddNew(font);
|
||||
}
|
||||
gfxFont *f = nsnull;
|
||||
font.swap(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
// we consider faces with mStandardFace == PR_TRUE to be "greater than" those with PR_FALSE,
|
||||
// because during style matching, later entries will replace earlier ones
|
||||
class FontEntryStandardFaceComparator {
|
||||
@ -1327,6 +1349,83 @@ gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyl
|
||||
{
|
||||
mUserFontSet = nsnull;
|
||||
SetUserFontSet(aUserFontSet);
|
||||
|
||||
// "#if" to be removed once all platforms are moved to gfxPlatformFontList interface
|
||||
// and subclasses of gfxFontGroup eliminated
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
ForEachFont(FindPlatformFont, this);
|
||||
|
||||
if (mFonts.Length() == 0) {
|
||||
PRBool needsBold;
|
||||
gfxFontEntry *defaultFont =
|
||||
gfxPlatformFontList::PlatformFontList()->GetDefaultFont(aStyle, needsBold);
|
||||
NS_ASSERTION(defaultFont, "invalid default font returned by GetDefaultFont");
|
||||
|
||||
nsRefPtr<gfxFont> font = defaultFont->GetOrMakeFont(aStyle, needsBold);
|
||||
if (font) {
|
||||
mFonts.AppendElement(font);
|
||||
}
|
||||
}
|
||||
|
||||
mPageLang = gfxPlatform::GetFontPrefLangFor(mStyle.langGroup.get());
|
||||
|
||||
if (!mStyle.systemFont) {
|
||||
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
||||
gfxFont* font = mFonts[i];
|
||||
if (font->GetFontEntry()->mIsBadUnderlineFont) {
|
||||
gfxFloat first = mFonts[0]->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = PR_MIN(first, bad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxFontGroup::FindPlatformFont(const nsAString& aName,
|
||||
const nsACString& aGenericName,
|
||||
void *aClosure)
|
||||
{
|
||||
gfxFontGroup *fontGroup = static_cast<gfxFontGroup*>(aClosure);
|
||||
const gfxFontStyle *fontStyle = fontGroup->GetStyle();
|
||||
|
||||
|
||||
PRBool needsBold;
|
||||
gfxFontEntry *fe = nsnull;
|
||||
|
||||
// first, look up in the user font set
|
||||
gfxUserFontSet *fs = fontGroup->GetUserFontSet();
|
||||
if (fs) {
|
||||
fe = fs->FindFontEntry(aName, *fontStyle, needsBold);
|
||||
}
|
||||
|
||||
// nothing in the user font set ==> check system fonts
|
||||
if (!fe) {
|
||||
fe = gfxPlatformFontList::PlatformFontList()->
|
||||
FindFontForFamily(aName, fontStyle, needsBold);
|
||||
}
|
||||
|
||||
// add to the font group, unless it's already there
|
||||
if (fe && !fontGroup->HasFont(fe)) {
|
||||
nsRefPtr<gfxFont> font = fe->GetOrMakeFont(fontStyle, needsBold);
|
||||
if (font) {
|
||||
fontGroup->mFonts.AppendElement(font);
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxFontGroup::HasFont(const gfxFontEntry *aFontEntry)
|
||||
{
|
||||
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
||||
if (mFonts.ElementAt(i)->GetFontEntry() == aFontEntry)
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
gfxFontGroup::~gfxFontGroup() {
|
||||
@ -1334,6 +1433,11 @@ gfxFontGroup::~gfxFontGroup() {
|
||||
SetUserFontSet(nsnull);
|
||||
}
|
||||
|
||||
gfxFontGroup *
|
||||
gfxFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||
{
|
||||
return new gfxFontGroup(mFamilies, aStyle, mUserFontSet);
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxFontGroup::IsInvalidChar(PRUnichar ch) {
|
||||
@ -1557,6 +1661,151 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, PRUint32 aFlags)
|
||||
return textRun.forget();
|
||||
}
|
||||
|
||||
#define UNICODE_LRO 0x202d
|
||||
#define UNICODE_RLO 0x202e
|
||||
#define UNICODE_PDF 0x202c
|
||||
|
||||
inline void
|
||||
AppendDirectionalIndicatorStart(PRUint32 aFlags, nsAString& aString)
|
||||
{
|
||||
static const PRUnichar overrides[2] = { UNICODE_LRO, UNICODE_RLO };
|
||||
aString.Append(overrides[(aFlags & gfxTextRunFactory::TEXT_IS_RTL) != 0]);
|
||||
aString.Append(' ');
|
||||
}
|
||||
|
||||
inline void
|
||||
AppendDirectionalIndicatorEnd(PRBool aNeedDirection, nsAString& aString)
|
||||
{
|
||||
// append a space (always, for consistent treatment of last char,
|
||||
// and a direction control if required (we skip this for 8-bit text,
|
||||
// which is known to be unidirectional LTR, unless the direction was
|
||||
// forced RTL via overrides)
|
||||
aString.Append(' ');
|
||||
if (!aNeedDirection)
|
||||
return;
|
||||
|
||||
aString.Append('.');
|
||||
aString.Append(UNICODE_PDF);
|
||||
}
|
||||
|
||||
gfxTextRun *
|
||||
gfxFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags)
|
||||
{
|
||||
NS_ASSERTION(aLength > 0, "should use MakeEmptyTextRun for zero-length text");
|
||||
NS_ASSERTION(aFlags & TEXT_IS_8BIT, "should be marked 8bit");
|
||||
gfxTextRun *textRun = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
|
||||
if (!textRun)
|
||||
return nsnull;
|
||||
|
||||
nsDependentCSubstring cString(reinterpret_cast<const char*>(aString),
|
||||
reinterpret_cast<const char*>(aString) + aLength);
|
||||
|
||||
nsAutoString utf16;
|
||||
AppendASCIItoUTF16(cString, utf16);
|
||||
|
||||
InitTextRun(textRun, utf16.get(), utf16.Length());
|
||||
|
||||
textRun->FetchGlyphExtents(aParams->mContext);
|
||||
|
||||
return textRun;
|
||||
}
|
||||
|
||||
gfxTextRun *
|
||||
gfxFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags)
|
||||
{
|
||||
NS_ASSERTION(aLength > 0, "should use MakeEmptyTextRun for zero-length text");
|
||||
gfxTextRun *textRun = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
|
||||
if (!textRun)
|
||||
return nsnull;
|
||||
|
||||
gfxPlatform::GetPlatform()->SetupClusterBoundaries(textRun, aString);
|
||||
|
||||
InitTextRun(textRun, aString, aLength);
|
||||
|
||||
textRun->FetchGlyphExtents(aParams->mContext);
|
||||
|
||||
return textRun;
|
||||
}
|
||||
|
||||
#define SMALL_GLYPH_RUN 128 // preallocated size of our auto arrays for per-glyph data;
|
||||
// some testing indicates that 90%+ of glyph runs will fit
|
||||
// without requiring a separate allocation
|
||||
|
||||
void
|
||||
gfxFontGroup::InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
gfxFont *mainFont = mFonts[0].get();
|
||||
|
||||
PRUint32 runStart = 0;
|
||||
nsAutoTArray<gfxTextRange,3> fontRanges;
|
||||
ComputeRanges(fontRanges, aString, 0, aLength);
|
||||
PRUint32 numRanges = fontRanges.Length();
|
||||
|
||||
nsAutoTArray<PRPackedBool,SMALL_GLYPH_RUN> unmatchedArray;
|
||||
PRPackedBool *unmatched = NULL;
|
||||
|
||||
for (PRUint32 r = 0; r < numRanges; r++) {
|
||||
const gfxTextRange& range = fontRanges[r];
|
||||
PRUint32 matchedLength = range.Length();
|
||||
gfxFont *matchedFont = (range.font ? range.font.get() : nsnull);
|
||||
|
||||
if (matchedFont) {
|
||||
// create the glyph run for this range
|
||||
aTextRun->AddGlyphRun(matchedFont, runStart, (matchedLength > 0));
|
||||
|
||||
// do glyph layout and record the resulting positioned glyphs in the run
|
||||
matchedFont->InitTextRun(aTextRun, aString, runStart, matchedLength);
|
||||
} else {
|
||||
// no font available, so record missing glyph info instead
|
||||
if (unmatched == NULL) {
|
||||
if (unmatchedArray.SetLength(aLength)) {
|
||||
unmatched = unmatchedArray.Elements();
|
||||
::memset(unmatched, PR_FALSE, aLength*sizeof(PRPackedBool));
|
||||
}
|
||||
}
|
||||
|
||||
// create the glyph run before calling SetMissing Glyph
|
||||
aTextRun->AddGlyphRun(mainFont, runStart, matchedLength);
|
||||
|
||||
for (PRUint32 index = runStart; index < runStart + matchedLength; index++) {
|
||||
// Record the char code so we can draw a box with the Unicode value
|
||||
if (NS_IS_HIGH_SURROGATE(aString[index]) &&
|
||||
index + 1 < aLength &&
|
||||
NS_IS_LOW_SURROGATE(aString[index+1])) {
|
||||
aTextRun->SetMissingGlyph(index,
|
||||
SURROGATE_TO_UCS4(aString[index],
|
||||
aString[index+1]));
|
||||
index++;
|
||||
} else {
|
||||
aTextRun->SetMissingGlyph(index, aString[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// We have to remember the indices of unmatched chars to avoid overwriting
|
||||
// their glyph (actually char code) data with the space glyph later,
|
||||
// while we're retrieving actual glyph data from CoreText runs.
|
||||
if (unmatched)
|
||||
::memset(unmatched + runStart, PR_TRUE, matchedLength);
|
||||
}
|
||||
|
||||
runStart += matchedLength;
|
||||
}
|
||||
|
||||
// It's possible for CoreText to omit glyph runs if it decides they contain
|
||||
// only invisibles (e.g., U+FEFF, see reftest 474417-1). In this case, we
|
||||
// need to eliminate them from the glyph run array to avoid drawing "partial
|
||||
// ligatures" with the wrong font.
|
||||
aTextRun->SanitizeGlyphRuns();
|
||||
|
||||
// Is this actually necessary? Without it, gfxTextRun::CopyGlyphDataFrom may assert
|
||||
// "Glyphruns not coalesced", but does that matter?
|
||||
aTextRun->SortGlyphRuns();
|
||||
}
|
||||
|
||||
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
@ -1686,6 +1935,129 @@ gfxFontGroup::GetGeneration()
|
||||
return mUserFontSet->GetGeneration();
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontGroup::UpdateFontList()
|
||||
{
|
||||
// if user font set is set, check to see if font list needs updating
|
||||
if (mUserFontSet && mCurrGeneration != GetGeneration()) {
|
||||
// xxx - can probably improve this to detect when all fonts were found, so no need to update list
|
||||
mFonts.Clear();
|
||||
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
|
||||
ForEachFont(FindPlatformFont, this);
|
||||
mCurrGeneration = GetGeneration();
|
||||
}
|
||||
}
|
||||
|
||||
struct PrefFontCallbackData {
|
||||
PrefFontCallbackData(nsTArray<nsRefPtr<gfxFontFamily> >& aFamiliesArray)
|
||||
: mPrefFamilies(aFamiliesArray)
|
||||
{}
|
||||
|
||||
nsTArray<nsRefPtr<gfxFontFamily> >& mPrefFamilies;
|
||||
|
||||
static PRBool AddFontFamilyEntry(eFontPrefLang aLang, const nsAString& aName, void *aClosure)
|
||||
{
|
||||
PrefFontCallbackData *prefFontData = static_cast<PrefFontCallbackData*>(aClosure);
|
||||
|
||||
gfxFontFamily *family = gfxPlatformFontList::PlatformFontList()->FindFamily(aName);
|
||||
if (family) {
|
||||
prefFontData->mPrefFamilies.AppendElement(family);
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
gfxFontGroup::WhichPrefFontSupportsChar(PRUint32 aCh)
|
||||
{
|
||||
gfxFont *font;
|
||||
|
||||
// FindCharUnicodeRange only supports BMP character points and there are no non-BMP fonts in prefs
|
||||
if (aCh > 0xFFFF)
|
||||
return nsnull;
|
||||
|
||||
// get the pref font list if it hasn't been set up already
|
||||
PRUint32 unicodeRange = FindCharUnicodeRange(aCh);
|
||||
eFontPrefLang charLang = gfxPlatform::GetPlatform()->GetFontPrefLangFor(unicodeRange);
|
||||
|
||||
// if the last pref font was the first family in the pref list, no need to recheck through a list of families
|
||||
if (mLastPrefFont && charLang == mLastPrefLang &&
|
||||
mLastPrefFirstFont && mLastPrefFont->HasCharacter(aCh)) {
|
||||
font = mLastPrefFont;
|
||||
NS_ADDREF(font);
|
||||
return font;
|
||||
}
|
||||
|
||||
// based on char lang and page lang, set up list of pref lang fonts to check
|
||||
eFontPrefLang prefLangs[kMaxLenPrefLangList];
|
||||
PRUint32 i, numLangs = 0;
|
||||
|
||||
gfxPlatform::GetPlatform()->GetLangPrefs(prefLangs, numLangs, charLang, mPageLang);
|
||||
|
||||
for (i = 0; i < numLangs; i++) {
|
||||
nsAutoTArray<nsRefPtr<gfxFontFamily>, 5> families;
|
||||
eFontPrefLang currentLang = prefLangs[i];
|
||||
|
||||
gfxPlatformFontList *fontList = gfxPlatformFontList::PlatformFontList();
|
||||
|
||||
// get the pref families for a single pref lang
|
||||
if (!fontList->GetPrefFontFamilyEntries(currentLang, &families)) {
|
||||
eFontPrefLang prefLangsToSearch[1] = { currentLang };
|
||||
PrefFontCallbackData prefFontData(families);
|
||||
gfxPlatform::ForEachPrefFont(prefLangsToSearch, 1, PrefFontCallbackData::AddFontFamilyEntry,
|
||||
&prefFontData);
|
||||
fontList->SetPrefFontFamilyEntries(currentLang, families);
|
||||
}
|
||||
|
||||
// find the first pref font that includes the character
|
||||
PRUint32 i, numPrefs;
|
||||
numPrefs = families.Length();
|
||||
for (i = 0; i < numPrefs; i++) {
|
||||
// look up the appropriate face
|
||||
gfxFontFamily *family = families[i];
|
||||
if (!family) continue;
|
||||
|
||||
// if a pref font is used, it's likely to be used again in the same text run.
|
||||
// the style doesn't change so the face lookup can be cached rather than calling
|
||||
// GetOrMakeFont repeatedly. speeds up FindFontForChar lookup times for subsequent
|
||||
// pref font lookups
|
||||
if (family == mLastPrefFamily && mLastPrefFont->HasCharacter(aCh)) {
|
||||
font = mLastPrefFont;
|
||||
NS_ADDREF(font);
|
||||
return font;
|
||||
}
|
||||
|
||||
PRBool needsBold;
|
||||
gfxFontEntry *fe = family->FindFontForStyle(mStyle, needsBold);
|
||||
// if ch in cmap, create and return a gfxFont
|
||||
if (fe && fe->TestCharacterMap(aCh)) {
|
||||
nsRefPtr<gfxFont> prefFont = fe->GetOrMakeFont(&mStyle, needsBold);
|
||||
if (!prefFont) continue;
|
||||
mLastPrefFamily = family;
|
||||
mLastPrefFont = prefFont;
|
||||
mLastPrefLang = charLang;
|
||||
mLastPrefFirstFont = (i == 0);
|
||||
return prefFont.forget();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
gfxFontGroup::WhichSystemFontSupportsChar(PRUint32 aCh)
|
||||
{
|
||||
gfxFontEntry *fe =
|
||||
gfxPlatformFontList::PlatformFontList()->FindFontForChar(aCh, GetFontAt(0));
|
||||
if (fe) {
|
||||
nsRefPtr<gfxFont> font = fe->GetOrMakeFont(&mStyle, PR_FALSE); // ignore bolder considerations in system fallback case...
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
|
||||
|
||||
|
@ -218,6 +218,23 @@ GDIFontEntry::ReadCMAP()
|
||||
return rv;
|
||||
}
|
||||
|
||||
gfxFont *
|
||||
GDIFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, PRBool /*aNeedsBold*/)
|
||||
{
|
||||
gfxFont *newFont;
|
||||
newFont = new gfxWindowsFont(this, aFontStyle);
|
||||
if (!newFont) {
|
||||
return nsnull;
|
||||
}
|
||||
if (!newFont->Valid()) {
|
||||
delete newFont;
|
||||
return nsnull;
|
||||
}
|
||||
nsRefPtr<gfxFont> font = newFont;
|
||||
gfxFontCache::GetCache()->AddNew(font);
|
||||
return newFont;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GDIFontEntry::GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer)
|
||||
{
|
||||
|
@ -289,6 +289,8 @@ protected:
|
||||
|
||||
void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType);
|
||||
|
||||
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
|
||||
|
||||
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
||||
|
||||
LOGFONTW mLogFont;
|
||||
|
@ -82,6 +82,8 @@ protected:
|
||||
|
||||
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
|
||||
|
||||
virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
|
||||
|
||||
ATSFontRef mATSFontRef;
|
||||
PRPackedBool mATSFontRefInitialized;
|
||||
#ifndef __LP64__
|
||||
|
@ -321,6 +321,35 @@ MacOSFontEntry::GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxFont*
|
||||
MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
|
||||
{
|
||||
gfxFont *newFont;
|
||||
#ifdef __LP64__
|
||||
newFont = new gfxCoreTextFont(this, aFontStyle, aNeedsBold);
|
||||
#else
|
||||
#ifdef MOZ_CORETEXT
|
||||
if (gfxPlatformMac::GetPlatform()->UsingCoreText()) {
|
||||
newFont = new gfxCoreTextFont(this, aFontStyle, aNeedsBold);
|
||||
} else {
|
||||
#endif
|
||||
newFont = new gfxAtsuiFont(this, aFontStyle, aNeedsBold);
|
||||
#ifdef MOZ_CORETEXT
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (!newFont) {
|
||||
return nsnull;
|
||||
}
|
||||
if (!newFont->Valid()) {
|
||||
delete newFont;
|
||||
return nsnull;
|
||||
}
|
||||
nsRefPtr<gfxFont> font = newFont;
|
||||
gfxFontCache::GetCache()->AddNew(font);
|
||||
return newFont;
|
||||
}
|
||||
|
||||
|
||||
/* gfxMacFontFamily */
|
||||
#pragma mark-
|
||||
|
@ -58,8 +58,12 @@
|
||||
#include "gfxTextRunWordCache.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
|
||||
#include "nsUnicodeRange.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIUGenCategory.h"
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsILocaleService.h"
|
||||
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
@ -70,6 +74,7 @@
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
gfxPlatform *gPlatform = nsnull;
|
||||
@ -488,6 +493,38 @@ gfxPlatform::GetPrefLangName(eFontPrefLang aLang)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
eFontPrefLang
|
||||
gfxPlatform::GetFontPrefLangFor(PRUint8 aUnicodeRange)
|
||||
{
|
||||
switch (aUnicodeRange) {
|
||||
case kRangeSetLatin: return eFontPrefLang_Western;
|
||||
case kRangeCyrillic: return eFontPrefLang_Cyrillic;
|
||||
case kRangeGreek: return eFontPrefLang_Greek;
|
||||
case kRangeTurkish: return eFontPrefLang_Turkish;
|
||||
case kRangeHebrew: return eFontPrefLang_Hebrew;
|
||||
case kRangeArabic: return eFontPrefLang_Arabic;
|
||||
case kRangeBaltic: return eFontPrefLang_Baltic;
|
||||
case kRangeThai: return eFontPrefLang_Thai;
|
||||
case kRangeKorean: return eFontPrefLang_Korean;
|
||||
case kRangeJapanese: return eFontPrefLang_Japanese;
|
||||
case kRangeSChinese: return eFontPrefLang_ChineseCN;
|
||||
case kRangeTChinese: return eFontPrefLang_ChineseTW;
|
||||
case kRangeDevanagari: return eFontPrefLang_Devanagari;
|
||||
case kRangeTamil: return eFontPrefLang_Tamil;
|
||||
case kRangeArmenian: return eFontPrefLang_Armenian;
|
||||
case kRangeBengali: return eFontPrefLang_Bengali;
|
||||
case kRangeCanadian: return eFontPrefLang_Canadian;
|
||||
case kRangeEthiopic: return eFontPrefLang_Ethiopic;
|
||||
case kRangeGeorgian: return eFontPrefLang_Georgian;
|
||||
case kRangeGujarati: return eFontPrefLang_Gujarati;
|
||||
case kRangeGurmukhi: return eFontPrefLang_Gurmukhi;
|
||||
case kRangeKhmer: return eFontPrefLang_Khmer;
|
||||
case kRangeMalayalam: return eFontPrefLang_Malayalam;
|
||||
case kRangeSetCJK: return eFontPrefLang_CJKSet;
|
||||
default: return eFontPrefLang_Others;
|
||||
}
|
||||
}
|
||||
|
||||
const PRUint32 kFontPrefLangCJKMask = (1 << (PRUint32) eFontPrefLang_Japanese) | (1 << (PRUint32) eFontPrefLang_ChineseTW)
|
||||
| (1 << (PRUint32) eFontPrefLang_ChineseCN) | (1 << (PRUint32) eFontPrefLang_ChineseHK)
|
||||
| (1 << (PRUint32) eFontPrefLang_Korean) | (1 << (PRUint32) eFontPrefLang_CJKSet);
|
||||
@ -497,6 +534,139 @@ gfxPlatform::IsLangCJK(eFontPrefLang aLang)
|
||||
return kFontPrefLangCJKMask & (1 << (PRUint32) aLang);
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::GetLangPrefs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang)
|
||||
{
|
||||
if (IsLangCJK(aCharLang)) {
|
||||
AppendCJKPrefLangs(aPrefLangs, aLen, aCharLang, aPageLang);
|
||||
} else {
|
||||
AppendPrefLang(aPrefLangs, aLen, aCharLang);
|
||||
}
|
||||
|
||||
AppendPrefLang(aPrefLangs, aLen, eFontPrefLang_Others);
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang)
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
|
||||
// prefer the lang specified by the page *if* CJK
|
||||
if (IsLangCJK(aPageLang)) {
|
||||
AppendPrefLang(aPrefLangs, aLen, aPageLang);
|
||||
}
|
||||
|
||||
// if not set up, set up the default CJK order, based on accept lang settings and locale
|
||||
if (mCJKPrefLangs.Length() == 0) {
|
||||
|
||||
// temp array
|
||||
eFontPrefLang tempPrefLangs[kMaxLenPrefLangList];
|
||||
PRUint32 tempLen = 0;
|
||||
|
||||
// Add the CJK pref fonts from accept languages, the order should be same order
|
||||
nsCAutoString list;
|
||||
nsresult rv;
|
||||
if (prefs) {
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefString;
|
||||
rv = prefs->GetComplexValue("intl.accept_languages", NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(prefString));
|
||||
if (prefString) {
|
||||
nsAutoString temp;
|
||||
prefString->ToString(getter_Copies(temp));
|
||||
LossyCopyUTF16toASCII(temp, list);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !list.IsEmpty()) {
|
||||
const char kComma = ',';
|
||||
const char *p, *p_end;
|
||||
list.BeginReading(p);
|
||||
list.EndReading(p_end);
|
||||
while (p < p_end) {
|
||||
while (nsCRT::IsAsciiSpace(*p)) {
|
||||
if (++p == p_end)
|
||||
break;
|
||||
}
|
||||
if (p == p_end)
|
||||
break;
|
||||
const char *start = p;
|
||||
while (++p != p_end && *p != kComma)
|
||||
/* nothing */ ;
|
||||
nsCAutoString lang(Substring(start, p));
|
||||
lang.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
eFontPrefLang fpl = gfxPlatform::GetFontPrefLangFor(lang.get());
|
||||
switch (fpl) {
|
||||
case eFontPrefLang_Japanese:
|
||||
case eFontPrefLang_Korean:
|
||||
case eFontPrefLang_ChineseCN:
|
||||
case eFontPrefLang_ChineseHK:
|
||||
case eFontPrefLang_ChineseTW:
|
||||
AppendPrefLang(tempPrefLangs, tempLen, fpl);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
do { // to allow 'break' to abort this block if a call fails
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsILocaleService> ls =
|
||||
do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsILocale> appLocale;
|
||||
rv = ls->GetApplicationLocale(getter_AddRefs(appLocale));
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
nsString localeStr;
|
||||
rv = appLocale->
|
||||
GetCategory(NS_LITERAL_STRING(NSILOCALE_MESSAGE), localeStr);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
const nsAString& lang = Substring(localeStr, 0, 2);
|
||||
if (lang.EqualsLiteral("ja")) {
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese);
|
||||
} else if (lang.EqualsLiteral("zh")) {
|
||||
const nsAString& region = Substring(localeStr, 3, 2);
|
||||
if (region.EqualsLiteral("CN")) {
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN);
|
||||
} else if (region.EqualsLiteral("TW")) {
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW);
|
||||
} else if (region.EqualsLiteral("HK")) {
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK);
|
||||
}
|
||||
} else if (lang.EqualsLiteral("ko")) {
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
// last resort... (the order is same as old gfx.)
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW);
|
||||
|
||||
// copy into the cached array
|
||||
PRUint32 j;
|
||||
for (j = 0; j < tempLen; j++) {
|
||||
mCJKPrefLangs.AppendElement(tempPrefLangs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// append in cached CJK langs
|
||||
PRUint32 i, numCJKlangs = mCJKPrefLangs.Length();
|
||||
|
||||
for (i = 0; i < numCJKlangs; i++) {
|
||||
AppendPrefLang(aPrefLangs, aLen, (eFontPrefLang) (mCJKPrefLangs[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::AppendPrefLang(eFontPrefLang aPrefLangs[], PRUint32& aLen, eFontPrefLang aAddLang)
|
||||
{
|
||||
@ -793,3 +963,58 @@ gfxPlatform::InitDisplayCaps()
|
||||
// Fall back to something sane
|
||||
gfxPlatform::sDPI = 96;
|
||||
}
|
||||
|
||||
// default SetupClusterBoundaries, based on Unicode properties;
|
||||
// platform subclasses may override if they wish
|
||||
static nsIUGenCategory* gGenCategory = nsnull;
|
||||
|
||||
static nsIUGenCategory*
|
||||
GetGenCategory()
|
||||
{
|
||||
if (!gGenCategory) {
|
||||
nsresult rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &gGenCategory);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Failed to get the Unicode character category service!");
|
||||
gGenCategory = nsnull;
|
||||
}
|
||||
}
|
||||
return gGenCategory;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString)
|
||||
{
|
||||
if (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) {
|
||||
// 8-bit text doesn't have clusters.
|
||||
// XXX is this true in all languages???
|
||||
// behdad: don't think so. Czech for example IIRC has a
|
||||
// 'ch' grapheme.
|
||||
return;
|
||||
}
|
||||
|
||||
nsIUGenCategory* gc = GetGenCategory();
|
||||
if (!gc) {
|
||||
NS_WARNING("No Unicode category service: cannot determine clusters");
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 i, length = aTextRun->GetLength();
|
||||
for (i = 0; i < length; ++i) {
|
||||
PRBool surrogatePair = PR_FALSE;
|
||||
PRUint32 ch = aString[i];
|
||||
if (NS_IS_HIGH_SURROGATE(ch) &&
|
||||
i < length - 1 && NS_IS_LOW_SURROGATE(aString[i+1])) {
|
||||
ch = SURROGATE_TO_UCS4(ch, aString[i+1]);
|
||||
surrogatePair = PR_TRUE;
|
||||
}
|
||||
if (i > 0 && gc->Get(aString[i]) == nsIUGenCategory::kMark) {
|
||||
gfxTextRun::CompressedGlyph g;
|
||||
aTextRun->SetGlyphs(i, g.SetComplex(PR_FALSE, PR_TRUE, 0), nsnull);
|
||||
}
|
||||
if (surrogatePair) {
|
||||
++i;
|
||||
gfxTextRun::CompressedGlyph g;
|
||||
aTextRun->SetGlyphs(i, g.SetComplex(PR_FALSE, PR_TRUE, 0), nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "gfxQuartzImageSurface.h"
|
||||
|
||||
#include "gfxMacPlatformFontList.h"
|
||||
#include "gfxAtsuiFonts.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
|
||||
#ifdef MOZ_CORETEXT
|
||||
@ -165,15 +164,7 @@ gfxPlatformMac::CreateFontGroup(const nsAString &aFamilies,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return new gfxCoreTextFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||
#else
|
||||
#ifdef MOZ_CORETEXT
|
||||
if (mUseCoreText)
|
||||
return new gfxCoreTextFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||
#endif
|
||||
return new gfxAtsuiFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||
#endif
|
||||
return new gfxFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||
}
|
||||
|
||||
// these will move to gfxPlatform once all platforms support the fontlist
|
||||
@ -253,115 +244,6 @@ gfxPlatformMac::OSXVersion()
|
||||
return mOSXVersion;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatformMac::GetLangPrefs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang)
|
||||
{
|
||||
if (IsLangCJK(aCharLang)) {
|
||||
AppendCJKPrefLangs(aPrefLangs, aLen, aCharLang, aPageLang);
|
||||
} else {
|
||||
AppendPrefLang(aPrefLangs, aLen, aCharLang);
|
||||
}
|
||||
|
||||
AppendPrefLang(aPrefLangs, aLen, eFontPrefLang_Others);
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatformMac::AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang)
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
|
||||
// prefer the lang specified by the page *if* CJK
|
||||
if (IsLangCJK(aPageLang)) {
|
||||
AppendPrefLang(aPrefLangs, aLen, aPageLang);
|
||||
}
|
||||
|
||||
// if not set up, set up the default CJK order, based on accept lang settings and system script
|
||||
if (mCJKPrefLangs.Length() == 0) {
|
||||
|
||||
// temp array
|
||||
eFontPrefLang tempPrefLangs[kMaxLenPrefLangList];
|
||||
PRUint32 tempLen = 0;
|
||||
|
||||
// Add the CJK pref fonts from accept languages, the order should be same order
|
||||
nsCAutoString list;
|
||||
nsresult rv;
|
||||
if (prefs) {
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefString;
|
||||
rv = prefs->GetComplexValue("intl.accept_languages", NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(prefString));
|
||||
if (prefString) {
|
||||
nsAutoString temp;
|
||||
prefString->ToString(getter_Copies(temp));
|
||||
LossyCopyUTF16toASCII(temp, list);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !list.IsEmpty()) {
|
||||
const char kComma = ',';
|
||||
const char *p, *p_end;
|
||||
list.BeginReading(p);
|
||||
list.EndReading(p_end);
|
||||
while (p < p_end) {
|
||||
while (nsCRT::IsAsciiSpace(*p)) {
|
||||
if (++p == p_end)
|
||||
break;
|
||||
}
|
||||
if (p == p_end)
|
||||
break;
|
||||
const char *start = p;
|
||||
while (++p != p_end && *p != kComma)
|
||||
/* nothing */ ;
|
||||
nsCAutoString lang(Substring(start, p));
|
||||
lang.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
eFontPrefLang fpl = gfxPlatform::GetFontPrefLangFor(lang.get());
|
||||
switch (fpl) {
|
||||
case eFontPrefLang_Japanese:
|
||||
case eFontPrefLang_Korean:
|
||||
case eFontPrefLang_ChineseCN:
|
||||
case eFontPrefLang_ChineseHK:
|
||||
case eFontPrefLang_ChineseTW:
|
||||
AppendPrefLang(tempPrefLangs, tempLen, fpl);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer the system locale if it is CJK.
|
||||
TextEncoding sysScript = ::GetApplicationTextEncoding();
|
||||
// XXX Is not there the HK locale?
|
||||
switch (sysScript) {
|
||||
case kTextEncodingMacJapanese: AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese); break;
|
||||
case kTextEncodingMacChineseTrad: AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW); break;
|
||||
case kTextEncodingMacKorean: AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean); break;
|
||||
case kTextEncodingMacChineseSimp: AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// last resort... (the order is same as old gfx.)
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Japanese);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_Korean);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseCN);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseHK);
|
||||
AppendPrefLang(tempPrefLangs, tempLen, eFontPrefLang_ChineseTW);
|
||||
|
||||
// copy into the cached array
|
||||
PRUint32 j;
|
||||
for (j = 0; j < tempLen; j++) {
|
||||
mCJKPrefLangs.AppendElement(tempPrefLangs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// append in cached CJK langs
|
||||
PRUint32 i, numCJKlangs = mCJKPrefLangs.Length();
|
||||
|
||||
for (i = 0; i < numCJKlangs; i++) {
|
||||
AppendPrefLang(aPrefLangs, aLen, (eFontPrefLang) (mCJKPrefLangs[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PRUint32
|
||||
gfxPlatformMac::ReadAntiAliasingThreshold()
|
||||
{
|
||||
@ -509,35 +391,3 @@ gfxPlatformMac::SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aS
|
||||
UCDisposeTextBreakLocator(&locator);
|
||||
}
|
||||
|
||||
|
||||
eFontPrefLang
|
||||
gfxPlatformMac::GetFontPrefLangFor(PRUint8 aUnicodeRange)
|
||||
{
|
||||
switch (aUnicodeRange) {
|
||||
case kRangeSetLatin: return eFontPrefLang_Western;
|
||||
case kRangeCyrillic: return eFontPrefLang_Cyrillic;
|
||||
case kRangeGreek: return eFontPrefLang_Greek;
|
||||
case kRangeTurkish: return eFontPrefLang_Turkish;
|
||||
case kRangeHebrew: return eFontPrefLang_Hebrew;
|
||||
case kRangeArabic: return eFontPrefLang_Arabic;
|
||||
case kRangeBaltic: return eFontPrefLang_Baltic;
|
||||
case kRangeThai: return eFontPrefLang_Thai;
|
||||
case kRangeKorean: return eFontPrefLang_Korean;
|
||||
case kRangeJapanese: return eFontPrefLang_Japanese;
|
||||
case kRangeSChinese: return eFontPrefLang_ChineseCN;
|
||||
case kRangeTChinese: return eFontPrefLang_ChineseTW;
|
||||
case kRangeDevanagari: return eFontPrefLang_Devanagari;
|
||||
case kRangeTamil: return eFontPrefLang_Tamil;
|
||||
case kRangeArmenian: return eFontPrefLang_Armenian;
|
||||
case kRangeBengali: return eFontPrefLang_Bengali;
|
||||
case kRangeCanadian: return eFontPrefLang_Canadian;
|
||||
case kRangeEthiopic: return eFontPrefLang_Ethiopic;
|
||||
case kRangeGeorgian: return eFontPrefLang_Georgian;
|
||||
case kRangeGujarati: return eFontPrefLang_Gujarati;
|
||||
case kRangeGurmukhi: return eFontPrefLang_Gurmukhi;
|
||||
case kRangeKhmer: return eFontPrefLang_Khmer;
|
||||
case kRangeMalayalam: return eFontPrefLang_Malayalam;
|
||||
case kRangeSetCJK: return eFontPrefLang_CJKSet;
|
||||
default: return eFontPrefLang_Others;
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,13 @@ gfxProxyFontEntry::gfxProxyFontEntry(const nsTArray<gfxFontFaceSrc>& aFontFaceSr
|
||||
|
||||
gfxProxyFontEntry::~gfxProxyFontEntry()
|
||||
{
|
||||
}
|
||||
|
||||
gfxFont*
|
||||
gfxProxyFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
|
||||
{
|
||||
// cannot create an actual font for a proxy entry
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
|
@ -395,6 +395,15 @@ gfxWindowsFont::GetUniqueName()
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsFont::InitTextRun(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart,
|
||||
PRUint32 aRunLength)
|
||||
{
|
||||
NS_NOTREACHED("oops");
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd,
|
||||
gfxContext *aContext, PRBool aDrawToPath, gfxPoint *aBaselineOrigin,
|
||||
|
@ -350,6 +350,67 @@ gfxWindowsPlatform::GetFTLibrary()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_FT2_FONTS
|
||||
void
|
||||
gfxWindowsPlatform::SetupClusterBoundaries(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(sizeof(WCHAR) == sizeof(PRUnichar),
|
||||
"WCHAR/PRUnichar not compatible");
|
||||
|
||||
PRUint32 length = aTextRun->GetLength();
|
||||
|
||||
nsAutoTArray<SCRIPT_ITEM,4> items;
|
||||
PRUint32 maxItems = 4;
|
||||
int numItems;
|
||||
HRESULT result;
|
||||
PRUint32 i, j;
|
||||
|
||||
do {
|
||||
items.SetLength(maxItems);
|
||||
result = ::ScriptItemize(aString, length,
|
||||
maxItems - 1,
|
||||
NULL,
|
||||
NULL,
|
||||
items.Elements(),
|
||||
&numItems);
|
||||
maxItems <<= 1;
|
||||
if (maxItems > INT_MAX)
|
||||
break;
|
||||
} while (result == E_OUTOFMEMORY);
|
||||
|
||||
if (result != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<SCRIPT_LOGATTR> attrs;
|
||||
for (i = 0; i < PRUint32(numItems); ++i) {
|
||||
PRUint32 offset = items[i].iCharPos;
|
||||
length = items[i + 1].iCharPos - offset;
|
||||
if (attrs.Length() < length) {
|
||||
attrs.SetLength(length);
|
||||
}
|
||||
result = ::ScriptBreak(aString + offset, length,
|
||||
&items[i].a,
|
||||
attrs.Elements());
|
||||
if (result != 0) {
|
||||
break;
|
||||
}
|
||||
for (j = 1; j < length; ++j) {
|
||||
if (!attrs[j].fCharStop) {
|
||||
gfxTextRun::CompressedGlyph g;
|
||||
// Remember that this character is not the start of a cluster
|
||||
// by setting its glyph data to "not a cluster start",
|
||||
// "is a ligature start", with no glyphs.
|
||||
aTextRun->SetGlyphs(offset + j,
|
||||
g.SetComplex(PR_FALSE, PR_TRUE, 0),
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::InitDisplayCaps()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user