зеркало из https://github.com/mozilla/gecko-dev.git
Bug 441473. Implement user font set object. r+sr=roc
This commit is contained in:
Родитель
1d2fd423b4
Коммит
37c61248d6
|
@ -1975,7 +1975,7 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font)
|
||||||
fontStyle->mFont.systemFont,
|
fontStyle->mFont.systemFont,
|
||||||
fontStyle->mFont.familyNameQuirks);
|
fontStyle->mFont.familyNameQuirks);
|
||||||
|
|
||||||
CurrentState().fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.name, &style);
|
CurrentState().fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.name, &style, presShell->GetPresContext()->GetUserFontSet());
|
||||||
NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
|
NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
|
||||||
CurrentState().font = font;
|
CurrentState().font = font;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
virtual nsresult Init(nsIDeviceContext* aContext);
|
virtual nsresult Init(nsIDeviceContext* aContext);
|
||||||
virtual nsresult GetDeviceContext(nsIDeviceContext *&aContext) const;
|
virtual nsresult GetDeviceContext(nsIDeviceContext *&aContext) const;
|
||||||
virtual nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
virtual nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIFontMetrics *&aMetrics);
|
nsIFontMetrics *&aMetrics, gfxUserFontSet *aUserFontSet = nsnull);
|
||||||
|
|
||||||
nsresult FontMetricsDeleted(const nsIFontMetrics* aFontMetrics);
|
nsresult FontMetricsDeleted(const nsIFontMetrics* aFontMetrics);
|
||||||
nsresult Compact();
|
nsresult Compact();
|
||||||
|
@ -100,8 +100,9 @@ public:
|
||||||
NS_IMETHOD CreateRenderingContextInstance(nsIRenderingContext *&aContext);
|
NS_IMETHOD CreateRenderingContextInstance(nsIRenderingContext *&aContext);
|
||||||
|
|
||||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIFontMetrics*& aMetrics);
|
nsIFontMetrics*& aMetrics, gfxUserFontSet *aUserFontSet = nsnull);
|
||||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics);
|
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics,
|
||||||
|
gfxUserFontSet *aUserFontSet = nsnull);
|
||||||
|
|
||||||
NS_IMETHOD FirstExistingFont(const nsFont& aFont, nsString& aFaceName);
|
NS_IMETHOD FirstExistingFont(const nsFont& aFont, nsString& aFaceName);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class nsIFontMetrics;
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
class nsIDeviceContextSpec;
|
class nsIDeviceContextSpec;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
class gfxUserFontSet;
|
||||||
|
|
||||||
struct nsFont;
|
struct nsFont;
|
||||||
|
|
||||||
|
@ -330,19 +331,23 @@ public:
|
||||||
* @param aFont font description to obtain metrics for
|
* @param aFont font description to obtain metrics for
|
||||||
* @param aLangGroup the language group of the document
|
* @param aLangGroup the language group of the document
|
||||||
* @param aMetrics out parameter for font metrics
|
* @param aMetrics out parameter for font metrics
|
||||||
|
* @param aUserFontSet user font set
|
||||||
* @return error status
|
* @return error status
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIFontMetrics*& aMetrics) = 0;
|
nsIFontMetrics*& aMetrics,
|
||||||
|
gfxUserFontSet *aUserFontSet = nsnull) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nsIFontMetrics that describe the properties of
|
* Get the nsIFontMetrics that describe the properties of
|
||||||
* an nsFont.
|
* an nsFont.
|
||||||
* @param aFont font description to obtain metrics for
|
* @param aFont font description to obtain metrics for
|
||||||
* @param aMetrics out parameter for font metrics
|
* @param aMetrics out parameter for font metrics
|
||||||
|
* @param aUserFontSet user font set
|
||||||
* @return error status
|
* @return error status
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics) = 0;
|
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics,
|
||||||
|
gfxUserFontSet *aUserFontSet = nsnull) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if a particular named font exists.
|
* Check to see if a particular named font exists.
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
class nsString;
|
class nsString;
|
||||||
class nsIDeviceContext;
|
class nsIDeviceContext;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
class gfxUserFontSet;
|
||||||
|
|
||||||
// IID for the nsIFontMetrics interface
|
// IID for the nsIFontMetrics interface
|
||||||
#define NS_IFONT_METRICS_IID \
|
#define NS_IFONT_METRICS_IID \
|
||||||
|
@ -87,7 +88,7 @@ public:
|
||||||
* @see nsIDeviceContext#GetMetricsFor()
|
* @see nsIDeviceContext#GetMetricsFor()
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIDeviceContext *aContext) = 0;
|
nsIDeviceContext *aContext, gfxUserFontSet *aUserFontSet = nsnull) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy this font metrics. This breaks the association between
|
* Destroy this font metrics. This breaks the association between
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsIRenderingContext.h"
|
#include "nsIRenderingContext.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS3(DeviceContextImpl, nsIDeviceContext, nsIObserver, nsISupportsWeakReference)
|
NS_IMPL_ISUPPORTS3(DeviceContextImpl, nsIDeviceContext, nsIObserver, nsISupportsWeakReference)
|
||||||
|
|
||||||
|
@ -213,7 +214,7 @@ DeviceContextImpl::GetLocaleLangGroup(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont,
|
NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont,
|
||||||
nsIAtom* aLangGroup, nsIFontMetrics*& aMetrics)
|
nsIAtom* aLangGroup, nsIFontMetrics*& aMetrics, gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
if (nsnull == mFontCache) {
|
if (nsnull == mFontCache) {
|
||||||
nsresult rv = CreateFontCache();
|
nsresult rv = CreateFontCache();
|
||||||
|
@ -230,10 +231,12 @@ NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont,
|
||||||
aLangGroup = mLocaleLangGroup;
|
aLangGroup = mLocaleLangGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mFontCache->GetMetricsFor(aFont, aLangGroup, aMetrics);
|
return mFontCache->GetMetricsFor(aFont, aLangGroup, aMetrics, aUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics)
|
NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont,
|
||||||
|
nsIFontMetrics*& aMetrics,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
if (nsnull == mFontCache) {
|
if (nsnull == mFontCache) {
|
||||||
nsresult rv = CreateFontCache();
|
nsresult rv = CreateFontCache();
|
||||||
|
@ -244,7 +247,8 @@ NS_IMETHODIMP DeviceContextImpl::GetMetricsFor(const nsFont& aFont, nsIFontMetri
|
||||||
// XXX temporary fix for performance problem -- erik
|
// XXX temporary fix for performance problem -- erik
|
||||||
GetLocaleLangGroup();
|
GetLocaleLangGroup();
|
||||||
}
|
}
|
||||||
return mFontCache->GetMetricsFor(aFont, mLocaleLangGroup, aMetrics);
|
return mFontCache->GetMetricsFor(aFont, mLocaleLangGroup,
|
||||||
|
aMetrics, aUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP DeviceContextImpl::GetDepth(PRUint32& aDepth)
|
NS_IMETHODIMP DeviceContextImpl::GetDepth(PRUint32& aDepth)
|
||||||
|
@ -469,7 +473,7 @@ nsFontCache::GetDeviceContext(nsIDeviceContext *&aContext) const
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIFontMetrics *&aMetrics)
|
nsIFontMetrics *&aMetrics, gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
// First check our cache
|
// First check our cache
|
||||||
// start from the end, which is where we put the most-recent-used element
|
// start from the end, which is where we put the most-recent-used element
|
||||||
|
@ -497,7 +501,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
aMetrics = nsnull;
|
aMetrics = nsnull;
|
||||||
nsresult rv = CreateFontMetricsInstance(&fm);
|
nsresult rv = CreateFontMetricsInstance(&fm);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
rv = fm->Init(aFont, aLangGroup, mContext);
|
rv = fm->Init(aFont, aLangGroup, mContext, aUserFontSet);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
// the mFontMetrics list has the "head" at the end, because append is
|
// the mFontMetrics list has the "head" at the end, because append is
|
||||||
// cheaper than insert
|
// cheaper than insert
|
||||||
|
@ -516,7 +520,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
Compact();
|
Compact();
|
||||||
rv = CreateFontMetricsInstance(&fm);
|
rv = CreateFontMetricsInstance(&fm);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
rv = fm->Init(aFont, aLangGroup, mContext);
|
rv = fm->Init(aFont, aLangGroup, mContext, aUserFontSet);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
mFontMetrics.AppendElement(fm);
|
mFontMetrics.AppendElement(fm);
|
||||||
aMetrics = fm;
|
aMetrics = fm;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#include "gfxTextRunCache.h"
|
#include "gfxTextRunCache.h"
|
||||||
#include "gfxPlatform.h"
|
#include "gfxPlatform.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsThebesFontMetrics, nsIFontMetrics)
|
NS_IMPL_ISUPPORTS1(nsThebesFontMetrics, nsIFontMetrics)
|
||||||
|
|
||||||
|
@ -63,7 +64,8 @@ nsThebesFontMetrics::~nsThebesFontMetrics()
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsThebesFontMetrics::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
nsThebesFontMetrics::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIDeviceContext *aContext)
|
nsIDeviceContext *aContext,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
mFont = aFont;
|
mFont = aFont;
|
||||||
mLangGroup = aLangGroup;
|
mLangGroup = aLangGroup;
|
||||||
|
@ -86,7 +88,8 @@ nsThebesFontMetrics::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
aFont.familyNameQuirks);
|
aFont.familyNameQuirks);
|
||||||
|
|
||||||
mFontGroup =
|
mFontGroup =
|
||||||
gfxPlatform::GetPlatform()->CreateFontGroup(aFont.name, mFontStyle);
|
gfxPlatform::GetPlatform()->CreateFontGroup(aFont.name, mFontStyle,
|
||||||
|
aUserFontSet);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||||
nsIDeviceContext *aContext);
|
nsIDeviceContext *aContext,
|
||||||
|
gfxUserFontSet *aUserFontSet = nsnull);
|
||||||
NS_IMETHOD Destroy();
|
NS_IMETHOD Destroy();
|
||||||
NS_IMETHOD GetXHeight(nscoord& aResult);
|
NS_IMETHOD GetXHeight(nscoord& aResult);
|
||||||
NS_IMETHOD GetSuperscriptOffset(nscoord& aResult);
|
NS_IMETHOD GetSuperscriptOffset(nscoord& aResult);
|
||||||
|
|
|
@ -31,6 +31,7 @@ EXPORTS = gfxASurface.h \
|
||||||
gfxTextRunCache.h \
|
gfxTextRunCache.h \
|
||||||
gfxTextRunWordCache.h \
|
gfxTextRunWordCache.h \
|
||||||
gfxUtils.h \
|
gfxUtils.h \
|
||||||
|
gfxUserFontSet.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXPORTS += gfxFontTest.h
|
EXPORTS += gfxFontTest.h
|
||||||
|
|
|
@ -113,7 +113,8 @@ protected:
|
||||||
class THEBES_API gfxAtsuiFontGroup : public gfxFontGroup {
|
class THEBES_API gfxAtsuiFontGroup : public gfxFontGroup {
|
||||||
public:
|
public:
|
||||||
gfxAtsuiFontGroup(const nsAString& families,
|
gfxAtsuiFontGroup(const nsAString& families,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
virtual ~gfxAtsuiFontGroup() {};
|
virtual ~gfxAtsuiFontGroup() {};
|
||||||
|
|
||||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||||
|
@ -137,7 +138,9 @@ public:
|
||||||
|
|
||||||
PRBool HasFont(ATSUFontID fid);
|
PRBool HasFont(ATSUFontID fid);
|
||||||
|
|
||||||
inline gfxAtsuiFont* WhichFontSupportsChar(nsTArray< nsRefPtr<gfxFont> >& aFontList, PRUint32 aCh) {
|
inline gfxAtsuiFont* WhichFontSupportsChar(nsTArray< nsRefPtr<gfxFont> >& aFontList,
|
||||||
|
PRUint32 aCh)
|
||||||
|
{
|
||||||
PRUint32 len = aFontList.Length();
|
PRUint32 len = aFontList.Length();
|
||||||
for (PRUint32 i = 0; i < len; i++) {
|
for (PRUint32 i = 0; i < len; i++) {
|
||||||
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(aFontList.ElementAt(i).get());
|
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(aFontList.ElementAt(i).get());
|
||||||
|
@ -147,10 +150,12 @@ public:
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
// search through pref fonts for a character, return nsnull if no matching pref font
|
// search through pref fonts for a character, return nsnull if no matching pref font
|
||||||
already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
|
already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
|
||||||
|
|
||||||
already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
|
already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
|
||||||
|
|
||||||
|
void UpdateFontList();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static PRBool FindATSUFont(const nsAString& aName,
|
static PRBool FindATSUFont(const nsAString& aName,
|
||||||
|
|
|
@ -51,8 +51,6 @@
|
||||||
#include "gfxSkipChars.h"
|
#include "gfxSkipChars.h"
|
||||||
#include "gfxRect.h"
|
#include "gfxRect.h"
|
||||||
#include "nsExpirationTracker.h"
|
#include "nsExpirationTracker.h"
|
||||||
#include "nsMathUtils.h"
|
|
||||||
#include "nsBidiUtils.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -63,6 +61,8 @@ class gfxTextRun;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
class gfxFont;
|
class gfxFont;
|
||||||
class gfxFontGroup;
|
class gfxFontGroup;
|
||||||
|
class gfxUserFontSet;
|
||||||
|
class gfxUserFontData;
|
||||||
|
|
||||||
#define FONT_STYLE_NORMAL 0
|
#define FONT_STYLE_NORMAL 0
|
||||||
#define FONT_STYLE_ITALIC 1
|
#define FONT_STYLE_ITALIC 1
|
||||||
|
@ -140,20 +140,24 @@ struct THEBES_API gfxFontStyle {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class gfxFontEntry {
|
class gfxFontEntry {
|
||||||
public:
|
public:
|
||||||
THEBES_INLINE_DECL_REFCOUNTING(gfxFontEntry)
|
THEBES_INLINE_DECL_REFCOUNTING(gfxFontEntry)
|
||||||
|
|
||||||
gfxFontEntry(const nsAString& aName) :
|
gfxFontEntry(const nsAString& aName) :
|
||||||
mName(aName), mCmapInitialized(PR_FALSE)
|
mName(aName), mIsProxy(PR_FALSE), mIsValid(PR_TRUE),
|
||||||
|
mIsBadUnderlineFont(PR_FALSE),
|
||||||
|
mCmapInitialized(PR_FALSE), mUserFontData(nsnull)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
gfxFontEntry(const gfxFontEntry& aEntry) :
|
gfxFontEntry(const gfxFontEntry& aEntry) :
|
||||||
mName(aEntry.mName), mItalic(aEntry.mItalic), mFixedPitch(aEntry.mFixedPitch),
|
mName(aEntry.mName), mItalic(aEntry.mItalic),
|
||||||
mUnicodeFont(aEntry.mUnicodeFont), mSymbolFont(aEntry.mSymbolFont), mTrueType(aEntry.mTrueType),
|
mFixedPitch(aEntry.mFixedPitch), mUnicodeFont(aEntry.mUnicodeFont),
|
||||||
mIsType1(aEntry.mIsType1), mWeight(aEntry.mWeight), mCmapInitialized(aEntry.mCmapInitialized),
|
mSymbolFont(aEntry.mSymbolFont), mTrueType(aEntry.mTrueType),
|
||||||
mCharacterMap(aEntry.mCharacterMap)
|
mIsType1(aEntry.mIsType1), mIsProxy(aEntry.mIsProxy),
|
||||||
|
mIsValid(aEntry.mIsValid), mIsBadUnderlineFont(aEntry.mIsBadUnderlineFont),
|
||||||
|
mWeight(aEntry.mWeight), mCmapInitialized(aEntry.mCmapInitialized),
|
||||||
|
mCharacterMap(aEntry.mCharacterMap), mUserFontData(aEntry.mUserFontData)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~gfxFontEntry();
|
virtual ~gfxFontEntry();
|
||||||
|
@ -165,7 +169,7 @@ public:
|
||||||
|
|
||||||
PRBool IsFixedPitch() { return mFixedPitch; }
|
PRBool IsFixedPitch() { return mFixedPitch; }
|
||||||
PRBool IsItalic() { return mItalic; }
|
PRBool IsItalic() { return mItalic; }
|
||||||
PRBool IsBold() { return mWeight >= 6; } // bold == weights 600 and above
|
PRBool IsBold() { return mWeight >= 600; } // bold == weights 600 and above
|
||||||
|
|
||||||
inline PRBool HasCharacter(PRUint32 ch) {
|
inline PRBool HasCharacter(PRUint32 ch) {
|
||||||
if (mCharacterMap.test(ch))
|
if (mCharacterMap.test(ch))
|
||||||
|
@ -177,7 +181,7 @@ public:
|
||||||
virtual PRBool TestCharacterMap(PRUint32 aCh);
|
virtual PRBool TestCharacterMap(PRUint32 aCh);
|
||||||
virtual nsresult ReadCMAP() { return 0; }
|
virtual nsresult ReadCMAP() { return 0; }
|
||||||
|
|
||||||
nsString mName;
|
nsString mName;
|
||||||
|
|
||||||
PRPackedBool mItalic : 1;
|
PRPackedBool mItalic : 1;
|
||||||
PRPackedBool mFixedPitch : 1;
|
PRPackedBool mFixedPitch : 1;
|
||||||
|
@ -186,11 +190,23 @@ public:
|
||||||
PRPackedBool mSymbolFont : 1;
|
PRPackedBool mSymbolFont : 1;
|
||||||
PRPackedBool mTrueType : 1;
|
PRPackedBool mTrueType : 1;
|
||||||
PRPackedBool mIsType1 : 1;
|
PRPackedBool mIsType1 : 1;
|
||||||
|
PRPackedBool mIsProxy : 1;
|
||||||
|
PRPackedBool mIsValid : 1;
|
||||||
|
|
||||||
|
PRPackedBool mIsBadUnderlineFont : 1;
|
||||||
|
|
||||||
PRUint16 mWeight;
|
PRUint16 mWeight;
|
||||||
|
PRUint16 mStretch;
|
||||||
|
|
||||||
PRPackedBool mCmapInitialized;
|
PRPackedBool mCmapInitialized;
|
||||||
gfxSparseBitSet mCharacterMap;
|
gfxSparseBitSet mCharacterMap;
|
||||||
|
gfxUserFontData* mUserFontData;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gfxFontEntry() :
|
||||||
|
mIsProxy(PR_FALSE), mIsValid(PR_TRUE),
|
||||||
|
mCmapInitialized(PR_FALSE), mUserFontData(nsnull)
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,12 +221,17 @@ public:
|
||||||
|
|
||||||
const nsString& Name() { return mName; }
|
const nsString& Name() { return mName; }
|
||||||
|
|
||||||
// choose a specific face to match a style using CSS font matching rules (weight matching occurs here)
|
// choose a specific face to match a style using CSS font matching
|
||||||
gfxFontEntry *FindFontForStyle(const gfxFontStyle& aFontStyle, PRBool& aNeedsBold);
|
// rules (weight matching occurs here)
|
||||||
|
gfxFontEntry *FindFontForStyle(const gfxFontStyle& aFontStyle,
|
||||||
|
PRBool& aNeedsBold);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// fills in an array with weights of faces that match style, returns number of weights in array
|
// fills in an array with weights of faces that match style, returns
|
||||||
virtual PRBool FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gfxFontStyle& aFontStyle) { return PR_FALSE; }
|
// number of weights in array
|
||||||
|
virtual PRBool FindWeightsForStyle(gfxFontEntry* aFontsForWeights[],
|
||||||
|
const gfxFontStyle& aFontStyle)
|
||||||
|
{ return PR_FALSE; }
|
||||||
|
|
||||||
nsString mName;
|
nsString mName;
|
||||||
};
|
};
|
||||||
|
@ -351,7 +372,7 @@ public:
|
||||||
PRUint16 GetContainedGlyphWidthAppUnits(PRUint32 aGlyphID) const {
|
PRUint16 GetContainedGlyphWidthAppUnits(PRUint32 aGlyphID) const {
|
||||||
return mContainedGlyphWidths.Get(aGlyphID);
|
return mContainedGlyphWidths.Get(aGlyphID);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool IsGlyphKnown(PRUint32 aGlyphID) const {
|
PRBool IsGlyphKnown(PRUint32 aGlyphID) const {
|
||||||
return mContainedGlyphWidths.Get(aGlyphID) != INVALID_WIDTH ||
|
return mContainedGlyphWidths.Get(aGlyphID) != INVALID_WIDTH ||
|
||||||
mTightGlyphExtents.GetEntry(aGlyphID) != nsnull;
|
mTightGlyphExtents.GetEntry(aGlyphID) != nsnull;
|
||||||
|
@ -638,7 +659,7 @@ public:
|
||||||
|
|
||||||
PRBool IsSyntheticBold() { return mSyntheticBoldOffset != 0; }
|
PRBool IsSyntheticBold() { return mSyntheticBoldOffset != 0; }
|
||||||
PRUint32 GetSyntheticBoldOffset() { return mSyntheticBoldOffset; }
|
PRUint32 GetSyntheticBoldOffset() { return mSyntheticBoldOffset; }
|
||||||
|
|
||||||
gfxFontEntry *GetFontEntry() { return mFontEntry.get(); }
|
gfxFontEntry *GetFontEntry() { return mFontEntry.get(); }
|
||||||
PRBool HasCharacter(PRUint32 ch) {
|
PRBool HasCharacter(PRUint32 ch) {
|
||||||
if (!mIsValid)
|
if (!mIsValid)
|
||||||
|
@ -675,7 +696,7 @@ public:
|
||||||
PLATFORM_TEXT_FLAGS = 0x0000F000,
|
PLATFORM_TEXT_FLAGS = 0x0000F000,
|
||||||
TEXTRUN_TEXT_FLAGS = 0x00000FFF,
|
TEXTRUN_TEXT_FLAGS = 0x00000FFF,
|
||||||
SETTABLE_FLAGS = CACHE_TEXT_FLAGS | USER_TEXT_FLAGS,
|
SETTABLE_FLAGS = CACHE_TEXT_FLAGS | USER_TEXT_FLAGS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When set, the text string pointer used to create the text run
|
* When set, the text string pointer used to create the text run
|
||||||
* is guaranteed to be available during the lifetime of the text run.
|
* is guaranteed to be available during the lifetime of the text run.
|
||||||
|
@ -1385,6 +1406,9 @@ public:
|
||||||
PRPackedBool mClipBeforePart;
|
PRPackedBool mClipBeforePart;
|
||||||
PRPackedBool mClipAfterPart;
|
PRPackedBool mClipAfterPart;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// user font set generation when text run was created
|
||||||
|
PRUint64 GetUserFontSetGeneration() { return mUserFontSetGeneration; }
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// number of entries referencing this textrun in the gfxTextRunWordCache
|
// number of entries referencing this textrun in the gfxTextRunWordCache
|
||||||
|
@ -1488,16 +1512,15 @@ private:
|
||||||
PRUint32 mFlags;
|
PRUint32 mFlags;
|
||||||
PRUint32 mCharacterCount;
|
PRUint32 mCharacterCount;
|
||||||
PRUint32 mHashCode;
|
PRUint32 mHashCode;
|
||||||
|
PRUint64 mUserFontSetGeneration; // user font set generation when text run created
|
||||||
};
|
};
|
||||||
|
|
||||||
class THEBES_API gfxFontGroup : public gfxTextRunFactory {
|
class THEBES_API gfxFontGroup : public gfxTextRunFactory {
|
||||||
protected:
|
protected:
|
||||||
gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle);
|
gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet *aUserFontSet = nsnull);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~gfxFontGroup() {
|
virtual ~gfxFontGroup();
|
||||||
mFonts.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual gfxFont *GetFontAt(PRInt32 i) {
|
virtual gfxFont *GetFontAt(PRInt32 i) {
|
||||||
return static_cast<gfxFont*>(mFonts[i]);
|
return static_cast<gfxFont*>(mFonts[i]);
|
||||||
|
@ -1519,20 +1542,8 @@ public:
|
||||||
* The listed characters should not be passed in to MakeTextRun and should
|
* The listed characters should not be passed in to MakeTextRun and should
|
||||||
* be treated as invisible and zero-width.
|
* be treated as invisible and zero-width.
|
||||||
*/
|
*/
|
||||||
static PRBool IsInvalidChar(PRUnichar ch) {
|
static PRBool IsInvalidChar(PRUnichar ch);
|
||||||
if (ch >= 32) {
|
|
||||||
return ch == 0x0085/*NEL*/ ||
|
|
||||||
((ch & 0xFF00) == 0x2000 /* Unicode control character */ &&
|
|
||||||
(ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/ ||
|
|
||||||
IS_BIDI_CONTROL_CHAR(ch)));
|
|
||||||
}
|
|
||||||
// We could just blacklist all control characters, but it seems better
|
|
||||||
// to only blacklist the ones we know cause problems for native font
|
|
||||||
// engines.
|
|
||||||
return ch == 0x0B || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' ||
|
|
||||||
(ch >= 0x1c && ch <= 0x1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a textrun for an empty string. This is fast; if you call it,
|
* Make a textrun for an empty string. This is fast; if you call it,
|
||||||
* don't bother caching the result.
|
* don't bother caching the result.
|
||||||
|
@ -1567,7 +1578,7 @@ public:
|
||||||
typedef PRBool (*FontCreationCallback) (const nsAString& aName,
|
typedef PRBool (*FontCreationCallback) (const nsAString& aName,
|
||||||
const nsACString& aGenericName,
|
const nsACString& aGenericName,
|
||||||
void *closure);
|
void *closure);
|
||||||
static PRBool ForEachFont(const nsAString& aFamilies,
|
/*static*/ PRBool ForEachFont(const nsAString& aFamilies,
|
||||||
const nsACString& aLangGroup,
|
const nsACString& aLangGroup,
|
||||||
FontCreationCallback fc,
|
FontCreationCallback fc,
|
||||||
void *closure);
|
void *closure);
|
||||||
|
@ -1595,6 +1606,16 @@ public:
|
||||||
|
|
||||||
void ComputeRanges(nsTArray<gfxTextRange>& mRanges, const PRUnichar *aString, PRUint32 begin, PRUint32 end);
|
void ComputeRanges(nsTArray<gfxTextRange>& mRanges, const PRUnichar *aString, PRUint32 begin, PRUint32 end);
|
||||||
|
|
||||||
|
gfxUserFontSet* GetUserFontSet();
|
||||||
|
void SetUserFontSet(gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
|
// With downloadable fonts, the composition of the font group can change as fonts are downloaded
|
||||||
|
// for each change in state of the user font set, the generation value is bumped to avoid picking up
|
||||||
|
// previously created text runs in the text run word cache. For font groups based on stylesheets
|
||||||
|
// with no @font-face rule, this always returns 0.
|
||||||
|
PRUint64 GetGeneration();
|
||||||
|
|
||||||
|
virtual void UpdateFontList() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsString mFamilies;
|
nsString mFamilies;
|
||||||
|
@ -1602,6 +1623,9 @@ protected:
|
||||||
nsTArray< nsRefPtr<gfxFont> > mFonts;
|
nsTArray< nsRefPtr<gfxFont> > mFonts;
|
||||||
gfxFloat mUnderlineOffset;
|
gfxFloat mUnderlineOffset;
|
||||||
|
|
||||||
|
gfxUserFontSet* mUserFontSet;
|
||||||
|
PRUint64 mCurrGeneration; // track the current user font set generation, rebuild font list if needed
|
||||||
|
|
||||||
// Init this font group's font metrics. If there no bad fonts, you don't need to call this.
|
// Init this font group's font metrics. If there no bad fonts, you don't need to call this.
|
||||||
// But if there are one or more bad fonts which have bad underline offset,
|
// But if there are one or more bad fonts which have bad underline offset,
|
||||||
// you should call this with the *first* bad font.
|
// you should call this with the *first* bad font.
|
||||||
|
@ -1615,7 +1639,7 @@ protected:
|
||||||
* family name in aFamilies (after resolving CSS/Gecko generic family names
|
* family name in aFamilies (after resolving CSS/Gecko generic family names
|
||||||
* if aResolveGeneric).
|
* if aResolveGeneric).
|
||||||
*/
|
*/
|
||||||
static PRBool ForEachFontInternal(const nsAString& aFamilies,
|
/*static*/ PRBool ForEachFontInternal(const nsAString& aFamilies,
|
||||||
const nsACString& aLangGroup,
|
const nsACString& aLangGroup,
|
||||||
PRBool aResolveGeneric,
|
PRBool aResolveGeneric,
|
||||||
PRBool aResolveFontName,
|
PRBool aResolveFontName,
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
|
|
||||||
#include "gfxFont.h"
|
#include "gfxFont.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
struct THEBES_API gfxFontTestItem {
|
struct THEBES_API gfxFontTestItem {
|
||||||
gfxFontTestItem(const nsCString& fontName,
|
gfxFontTestItem(const nsCString& fontName,
|
||||||
|
|
|
@ -312,18 +312,32 @@ public:
|
||||||
static inline PRUint32
|
static inline PRUint32
|
||||||
ReadLongAt(const PRUint8 *aBuf, PRUint32 aIndex)
|
ReadLongAt(const PRUint8 *aBuf, PRUint32 aIndex)
|
||||||
{
|
{
|
||||||
return ((aBuf[aIndex] << 24) | (aBuf[aIndex + 1] << 16) | (aBuf[aIndex + 2] << 8) | (aBuf[aIndex + 3]));
|
return ((aBuf[aIndex] << 24) | (aBuf[aIndex + 1] << 16) |
|
||||||
|
(aBuf[aIndex + 2] << 8) | (aBuf[aIndex + 3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
ReadCMAPTableFormat12(PRUint8 *aBuf, PRInt32 aLength, gfxSparseBitSet& aCharacterMap);
|
ReadCMAPTableFormat12(PRUint8 *aBuf, PRInt32 aLength,
|
||||||
|
gfxSparseBitSet& aCharacterMap);
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
ReadCMAPTableFormat4(PRUint8 *aBuf, PRInt32 aLength, gfxSparseBitSet& aCharacterMap);
|
ReadCMAPTableFormat4(PRUint8 *aBuf, PRInt32 aLength,
|
||||||
|
gfxSparseBitSet& aCharacterMap);
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
||||||
PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont);
|
PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont);
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
// given a TrueType/OpenType data file, produce a EOT-format header
|
||||||
|
// for use with Windows T2Embed API AddFontResource type API's
|
||||||
|
// effectively hide existing fonts with matching names aHeaderLen is
|
||||||
|
// the size of the header buffer on input, the actual size of the
|
||||||
|
// EOT header on output aIsCFF returns whether the font has PS style
|
||||||
|
// glyphs or not (as opposed to TrueType glyphs)
|
||||||
|
static nsresult
|
||||||
|
MakeEOTHeader(nsIFile *aFontData, nsTArray<PRUint8> *aHeader, PRBool *aIsCFF);
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline bool IsJoiner(PRUint32 ch) {
|
static inline bool IsJoiner(PRUint32 ch) {
|
||||||
return (ch == 0x200C ||
|
return (ch == 0x200C ||
|
||||||
|
@ -338,7 +352,8 @@ public:
|
||||||
static PRUint8 CharRangeBit(PRUint32 ch);
|
static PRUint8 CharRangeBit(PRUint32 ch);
|
||||||
|
|
||||||
// for a given font list pref name, set up a list of font names
|
// for a given font list pref name, set up a list of font names
|
||||||
static void GetPrefsFontList(const char *aPrefName, nsTArray<nsString>& aFontList);
|
static void GetPrefsFontList(const char *aPrefName,
|
||||||
|
nsTArray<nsString>& aFontList);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -400,7 +415,8 @@ public:
|
||||||
InitLoader();
|
InitLoader();
|
||||||
|
|
||||||
// start timer
|
// start timer
|
||||||
mTimer->InitWithFuncCallback(LoaderTimerCallback, this, aDelay, nsITimer::TYPE_REPEATING_SLACK);
|
mTimer->InitWithFuncCallback(LoaderTimerCallback, this, aDelay,
|
||||||
|
nsITimer::TYPE_REPEATING_SLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel the timer and cleanup
|
// cancel the timer and cleanup
|
||||||
|
|
|
@ -95,7 +95,7 @@ private:
|
||||||
|
|
||||||
class THEBES_API gfxOS2FontGroup : public gfxFontGroup {
|
class THEBES_API gfxOS2FontGroup : public gfxFontGroup {
|
||||||
public:
|
public:
|
||||||
gfxOS2FontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle);
|
gfxOS2FontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle, gfxUserFontSet *aUserFontSet);
|
||||||
virtual ~gfxOS2FontGroup();
|
virtual ~gfxOS2FontGroup();
|
||||||
|
|
||||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||||
|
|
|
@ -71,7 +71,8 @@ public:
|
||||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||||
|
|
||||||
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
// Given a string and a font we already have, find the font that
|
// Given a string and a font we already have, find the font that
|
||||||
// supports the most code points and most closely resembles aFont.
|
// supports the most code points and most closely resembles aFont.
|
||||||
|
|
|
@ -73,7 +73,8 @@ public:
|
||||||
class THEBES_API gfxPangoFontGroup : public gfxFontGroup {
|
class THEBES_API gfxPangoFontGroup : public gfxFontGroup {
|
||||||
public:
|
public:
|
||||||
gfxPangoFontGroup (const nsAString& families,
|
gfxPangoFontGroup (const nsAString& families,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
virtual ~gfxPangoFontGroup ();
|
virtual ~gfxPangoFontGroup ();
|
||||||
|
|
||||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||||
|
|
|
@ -59,6 +59,10 @@ class gfxImageSurface;
|
||||||
class gfxFont;
|
class gfxFont;
|
||||||
class gfxFontGroup;
|
class gfxFontGroup;
|
||||||
struct gfxFontStyle;
|
struct gfxFontStyle;
|
||||||
|
class gfxUserFontSet;
|
||||||
|
struct gfxDownloadedFontData;
|
||||||
|
class gfxFontEntry;
|
||||||
|
class nsIURI;
|
||||||
|
|
||||||
// pref lang id's for font prefs
|
// pref lang id's for font prefs
|
||||||
// !!! needs to match the list of pref font.default.xx entries listed in all.js !!!
|
// !!! needs to match the list of pref font.default.xx entries listed in all.js !!!
|
||||||
|
@ -184,7 +188,30 @@ public:
|
||||||
* Create the appropriate platform font group
|
* Create the appropriate platform font group
|
||||||
*/
|
*/
|
||||||
virtual gfxFontGroup *CreateFontGroup(const nsAString& aFamilies,
|
virtual gfxFontGroup *CreateFontGroup(const nsAString& aFamilies,
|
||||||
const gfxFontStyle *aStyle) = 0;
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a local platform font using the full font face name (needed to support @font-face src local() )
|
||||||
|
*/
|
||||||
|
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName) { return nsnull; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate a platform font (needed to support @font-face src url() )
|
||||||
|
*
|
||||||
|
* Note: MakePlatformFont implementation is responsible for removing font file data, since data may need to
|
||||||
|
* persist beyond this call.
|
||||||
|
*/
|
||||||
|
virtual gfxFontEntry* MakePlatformFont(const gfxFontEntry *aProxyEntry, const gfxDownloadedFontData* aFontData) { return nsnull; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to allow downloadable fonts via @font-face rules
|
||||||
|
*/
|
||||||
|
virtual PRBool DownloadableFontsEnabled();
|
||||||
|
|
||||||
|
// check whether format is supported on a platform or not (if unclear, returns true)
|
||||||
|
virtual PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags) { return PR_FALSE; }
|
||||||
|
|
||||||
void GetPrefFonts(const char *aLangGroup, nsString& array, PRBool aAppendUnicode = PR_TRUE);
|
void GetPrefFonts(const char *aLangGroup, nsString& array, PRBool aAppendUnicode = PR_TRUE);
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,8 @@ public:
|
||||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||||
|
|
||||||
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
#ifndef MOZ_PANGO
|
||||||
FontFamily *FindFontFamily(const nsAString& aName);
|
FontFamily *FindFontFamily(const nsAString& aName);
|
||||||
|
|
|
@ -66,7 +66,14 @@ public:
|
||||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||||
|
|
||||||
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
|
gfxFontEntry* LookupLocalFont(const nsAString& aFontName);
|
||||||
|
|
||||||
|
gfxFontEntry* MakePlatformFont(const gfxFontEntry *aProxyEntry, const gfxDownloadedFontData* aFontData);
|
||||||
|
|
||||||
|
PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags);
|
||||||
|
|
||||||
nsresult GetFontList(const nsACString& aLangGroup,
|
nsresult GetFontList(const nsACString& aLangGroup,
|
||||||
const nsACString& aGenericFamily,
|
const nsACString& aGenericFamily,
|
||||||
|
|
|
@ -83,7 +83,7 @@ class FontFamily : public gfxFontFamily
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FontFamily(const nsAString& aName) :
|
FontFamily(const nsAString& aName) :
|
||||||
gfxFontFamily(aName), mHasStyles(PR_FALSE), mIsBadUnderlineFont(PR_FALSE) { }
|
gfxFontFamily(aName), mIsBadUnderlineFontFamily(PR_FALSE), mHasStyles(PR_FALSE) { }
|
||||||
|
|
||||||
FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
|
FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
|
||||||
|
|
||||||
|
@ -101,18 +101,18 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsTArray<nsRefPtr<FontEntry> > mVariations;
|
nsTArray<nsRefPtr<FontEntry> > mVariations;
|
||||||
PRPackedBool mIsBadUnderlineFont;
|
PRPackedBool mIsBadUnderlineFontFamily;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PRBool mHasStyles;
|
PRPackedBool mHasStyles;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontEntry : public gfxFontEntry
|
class FontEntry : public gfxFontEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FontEntry(const nsString& aFaceName) :
|
FontEntry(const nsAString& aFaceName) :
|
||||||
gfxFontEntry(aFaceName), mFontType(GFX_FONT_TYPE_UNKNOWN),
|
gfxFontEntry(aFaceName), mFontType(GFX_FONT_TYPE_UNKNOWN),
|
||||||
mIsBadUnderlineFont(PR_FALSE), mForceGDI(PR_FALSE), mUnknownCMAP(PR_FALSE),
|
mForceGDI(PR_FALSE), mUnknownCMAP(PR_FALSE),
|
||||||
mCharset(0), mUnicodeRanges(0)
|
mCharset(0), mUnicodeRanges(0)
|
||||||
{
|
{
|
||||||
mUnicodeFont = PR_FALSE;
|
mUnicodeFont = PR_FALSE;
|
||||||
|
@ -124,7 +124,6 @@ public:
|
||||||
mWindowsFamily(aFontEntry.mWindowsFamily),
|
mWindowsFamily(aFontEntry.mWindowsFamily),
|
||||||
mWindowsPitch(aFontEntry.mWindowsPitch),
|
mWindowsPitch(aFontEntry.mWindowsPitch),
|
||||||
mFontType(aFontEntry.mFontType),
|
mFontType(aFontEntry.mFontType),
|
||||||
mIsBadUnderlineFont(aFontEntry.mIsBadUnderlineFont),
|
|
||||||
mForceGDI(aFontEntry.mForceGDI),
|
mForceGDI(aFontEntry.mForceGDI),
|
||||||
mUnknownCMAP(aFontEntry.mUnknownCMAP),
|
mUnknownCMAP(aFontEntry.mUnknownCMAP),
|
||||||
mCharset(aFontEntry.mCharset),
|
mCharset(aFontEntry.mCharset),
|
||||||
|
@ -133,6 +132,31 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FontEntry* CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc = 0, LOGFONTW *aLogFont = nsnull);
|
||||||
|
|
||||||
|
static void FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize, PRBool aItalic);
|
||||||
|
|
||||||
|
static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics, DWORD fontType)
|
||||||
|
{
|
||||||
|
gfxWindowsFontType feType;
|
||||||
|
if (metrics.ntmFlags & NTM_TYPE1)
|
||||||
|
feType = GFX_FONT_TYPE_TYPE1;
|
||||||
|
else if (metrics.ntmFlags & NTM_PS_OPENTYPE)
|
||||||
|
feType = GFX_FONT_TYPE_PS_OPENTYPE;
|
||||||
|
else if (metrics.ntmFlags & NTM_TT_OPENTYPE)
|
||||||
|
feType = GFX_FONT_TYPE_TT_OPENTYPE;
|
||||||
|
else if (fontType == TRUETYPE_FONTTYPE)
|
||||||
|
feType = GFX_FONT_TYPE_TRUETYPE;
|
||||||
|
else if (fontType == RASTER_FONTTYPE)
|
||||||
|
feType = GFX_FONT_TYPE_RASTER;
|
||||||
|
else if (fontType == DEVICE_FONTTYPE)
|
||||||
|
feType = GFX_FONT_TYPE_DEVICE;
|
||||||
|
else
|
||||||
|
feType = GFX_FONT_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
return feType;
|
||||||
|
}
|
||||||
|
|
||||||
PRBool IsType1() const {
|
PRBool IsType1() const {
|
||||||
return (mFontType == GFX_FONT_TYPE_TYPE1);
|
return (mFontType == GFX_FONT_TYPE_TYPE1);
|
||||||
}
|
}
|
||||||
|
@ -232,16 +256,12 @@ public:
|
||||||
return mUnicodeRanges[range];
|
return mUnicodeRanges[range];
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether this font family is in "bad" underline offset blacklist.
|
|
||||||
PRBool IsBadUnderlineFont() { return mIsBadUnderlineFont != 0; }
|
|
||||||
|
|
||||||
PRBool TestCharacterMap(PRUint32 aCh);
|
PRBool TestCharacterMap(PRUint32 aCh);
|
||||||
|
|
||||||
PRUint8 mWindowsFamily;
|
PRUint8 mWindowsFamily;
|
||||||
PRUint8 mWindowsPitch;
|
PRUint8 mWindowsPitch;
|
||||||
|
|
||||||
gfxWindowsFontType mFontType;
|
gfxWindowsFontType mFontType;
|
||||||
PRPackedBool mIsBadUnderlineFont : 1;
|
|
||||||
PRPackedBool mForceGDI : 1;
|
PRPackedBool mForceGDI : 1;
|
||||||
PRPackedBool mUnknownCMAP : 1;
|
PRPackedBool mUnknownCMAP : 1;
|
||||||
|
|
||||||
|
@ -317,7 +337,7 @@ private:
|
||||||
class THEBES_API gfxWindowsFontGroup : public gfxFontGroup {
|
class THEBES_API gfxWindowsFontGroup : public gfxFontGroup {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle);
|
gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle, gfxUserFontSet *aUserFontSet);
|
||||||
virtual ~gfxWindowsFontGroup();
|
virtual ~gfxWindowsFontGroup();
|
||||||
|
|
||||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||||
|
@ -349,8 +369,10 @@ public:
|
||||||
const nsCString& aLangGroup,
|
const nsCString& aLangGroup,
|
||||||
nsTArray<nsRefPtr<FontEntry> > *list);
|
nsTArray<nsRefPtr<FontEntry> > *list);
|
||||||
|
|
||||||
|
void UpdateFontList();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void InitFontList();
|
||||||
void InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, const char *aString, PRUint32 aLength);
|
void InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, const char *aString, PRUint32 aLength);
|
||||||
void InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, const PRUnichar *aString, PRUint32 aLength);
|
void InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, const PRUnichar *aString, PRUint32 aLength);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,23 @@ public:
|
||||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||||
|
|
||||||
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle);
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a local platform font using the full font face name (needed to support @font-face src local() )
|
||||||
|
*/
|
||||||
|
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate a platform font (needed to support @font-face src url() )
|
||||||
|
*/
|
||||||
|
virtual gfxFontEntry* MakePlatformFont(const gfxFontEntry *aProxyEntry, const gfxDownloadedFontData* aFontData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether format is supported on a platform or not (if unclear, returns true)
|
||||||
|
*/
|
||||||
|
virtual PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags);
|
||||||
|
|
||||||
/* Given a string and a font we already have find the font that
|
/* Given a string and a font we already have find the font that
|
||||||
* supports the most code points and most closely resembles aFont
|
* supports the most code points and most closely resembles aFont
|
||||||
|
|
|
@ -38,6 +38,7 @@ CPPSRCS = \
|
||||||
gfxSkipChars.cpp \
|
gfxSkipChars.cpp \
|
||||||
gfxTextRunCache.cpp \
|
gfxTextRunCache.cpp \
|
||||||
gfxTextRunWordCache.cpp \
|
gfxTextRunWordCache.cpp \
|
||||||
|
gfxUserFontSet.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXTRA_DSO_LDOPTS += \
|
EXTRA_DSO_LDOPTS += \
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
|
|
||||||
#include "gfxQuartzSurface.h"
|
#include "gfxQuartzSurface.h"
|
||||||
#include "gfxQuartzFontCache.h"
|
#include "gfxQuartzFontCache.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#include "nsUnicodeRange.h"
|
#include "nsUnicodeRange.h"
|
||||||
|
|
||||||
|
@ -322,7 +323,7 @@ gfxAtsuiFont::InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef)
|
||||||
if (glyphID == 0) // no zero in this font
|
if (glyphID == 0) // no zero in this font
|
||||||
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
||||||
|
|
||||||
SanitizeMetrics(&mMetrics, GetFontEntry()->FamilyEntry()->IsBadUnderlineFontFamily());
|
SanitizeMetrics(&mMetrics, GetFontEntry()->mIsBadUnderlineFont);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf (stderr, "Font: %p size: %f (fixed: %d)", this, size, gfxQuartzFontCache::SharedFontCache()->IsFixedPitch(aFontID));
|
fprintf (stderr, "Font: %p size: %f (fixed: %d)", this, size, gfxQuartzFontCache::SharedFontCache()->IsFixedPitch(aFontID));
|
||||||
|
@ -501,9 +502,11 @@ GetOrMakeFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aStyle, PRBool aNe
|
||||||
return static_cast<gfxAtsuiFont *>(f);
|
return static_cast<gfxAtsuiFont *>(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
|
gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
: gfxFontGroup(families, aStyle)
|
gfxUserFontSet *aUserFontSet)
|
||||||
|
: gfxFontGroup(families, aStyle, aUserFontSet)
|
||||||
{
|
{
|
||||||
ForEachFont(FindATSUFont, this);
|
ForEachFont(FindATSUFont, this);
|
||||||
|
|
||||||
|
@ -536,7 +539,7 @@ gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
|
||||||
if (!mStyle.systemFont) {
|
if (!mStyle.systemFont) {
|
||||||
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
||||||
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(mFonts[i].get());
|
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(mFonts[i].get());
|
||||||
if (font->GetFontEntry()->FamilyEntry()->IsBadUnderlineFontFamily()) {
|
if (font->GetFontEntry()->mIsBadUnderlineFont) {
|
||||||
gfxFloat first = mFonts[0]->GetMetrics().underlineOffset;
|
gfxFloat first = mFonts[0]->GetMetrics().underlineOffset;
|
||||||
gfxFloat bad = font->GetMetrics().underlineOffset;
|
gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||||
mUnderlineOffset = PR_MIN(first, bad);
|
mUnderlineOffset = PR_MIN(first, bad);
|
||||||
|
@ -554,10 +557,23 @@ gfxAtsuiFontGroup::FindATSUFont(const nsAString& aName,
|
||||||
gfxAtsuiFontGroup *fontGroup = (gfxAtsuiFontGroup*) closure;
|
gfxAtsuiFontGroup *fontGroup = (gfxAtsuiFontGroup*) closure;
|
||||||
const gfxFontStyle *fontStyle = fontGroup->GetStyle();
|
const gfxFontStyle *fontStyle = fontGroup->GetStyle();
|
||||||
|
|
||||||
gfxQuartzFontCache *fc = gfxQuartzFontCache::SharedFontCache();
|
|
||||||
|
|
||||||
PRBool needsBold;
|
PRBool needsBold;
|
||||||
MacOSFontEntry *fe = fc->FindFontForFamily(aName, fontStyle, needsBold);
|
MacOSFontEntry *fe = nsnull;
|
||||||
|
|
||||||
|
// first, look up in the user font set
|
||||||
|
gfxUserFontSet *fs = fontGroup->GetUserFontSet();
|
||||||
|
gfxFontEntry *gfe;
|
||||||
|
if (fs && (gfe = fs->FindFontEntry(aName, *fontStyle, needsBold))) {
|
||||||
|
// assume for now platform font if not SVG
|
||||||
|
fe = static_cast<MacOSFontEntry*> (gfe);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing in the user font set ==> check system fonts
|
||||||
|
if (!fe) {
|
||||||
|
gfxQuartzFontCache *fc = gfxQuartzFontCache::SharedFontCache();
|
||||||
|
fe = fc->FindFontForFamily(aName, fontStyle, needsBold);
|
||||||
|
}
|
||||||
|
|
||||||
if (fe && !fontGroup->HasFont(fe->GetFontID())) {
|
if (fe && !fontGroup->HasFont(fe->GetFontID())) {
|
||||||
nsRefPtr<gfxAtsuiFont> font = GetOrMakeFont(fe, fontStyle, needsBold);
|
nsRefPtr<gfxAtsuiFont> font = GetOrMakeFont(fe, fontStyle, needsBold);
|
||||||
|
@ -572,7 +588,7 @@ gfxAtsuiFontGroup::FindATSUFont(const nsAString& aName,
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxAtsuiFontGroup::Copy(const gfxFontStyle *aStyle)
|
gfxAtsuiFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
{
|
{
|
||||||
return new gfxAtsuiFontGroup(mFamilies, aStyle);
|
return new gfxAtsuiFontGroup(mFamilies, aStyle, mUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -933,6 +949,19 @@ gfxAtsuiFontGroup::WhichSystemFontSupportsChar(PRUint32 aCh)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gfxAtsuiFontGroup::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();
|
||||||
|
ForEachFont(FindATSUFont, this);
|
||||||
|
mCurrGeneration = GetGeneration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper for ATSU "direct data arrays"
|
* Simple wrapper for ATSU "direct data arrays"
|
||||||
*/
|
*/
|
||||||
|
@ -1392,8 +1421,8 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun,
|
||||||
("InitTextRun %p fontgroup %p (%s) lang: %s len %d TEXTRUN \"%s\" ENDTEXTRUN\n",
|
("InitTextRun %p fontgroup %p (%s) lang: %s len %d TEXTRUN \"%s\" ENDTEXTRUN\n",
|
||||||
aRun, this, families.get(), mStyle.langGroup.get(), aLengthInTextRun, str.get()) );
|
aRun, this, families.get(), mStyle.langGroup.get(), aLengthInTextRun, str.get()) );
|
||||||
PR_LOG(gAtsuiTextRunLog, PR_LOG_DEBUG,
|
PR_LOG(gAtsuiTextRunLog, PR_LOG_DEBUG,
|
||||||
("InitTextRun font: %s\n",
|
("InitTextRun font: %s user font set: %p (%8.8x)\n",
|
||||||
NS_ConvertUTF16toUTF8(firstFont->GetUniqueName()).get()) );
|
NS_ConvertUTF16toUTF8(firstFont->GetUniqueName()).get(), mUserFontSet, PRUint32(mCurrGeneration)) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (aRun->GetFlags() & TEXT_DISABLE_OPTIONAL_LIGATURES) {
|
if (aRun->GetFlags() & TEXT_DISABLE_OPTIONAL_LIGATURES) {
|
||||||
|
|
|
@ -49,7 +49,9 @@
|
||||||
#include "gfxTypes.h"
|
#include "gfxTypes.h"
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxFontMissingGlyphs.h"
|
#include "gfxFontMissingGlyphs.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
#include "nsMathUtils.h"
|
#include "nsMathUtils.h"
|
||||||
|
#include "nsBidiUtils.h"
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "gfxFontTest.h"
|
#include "gfxFontTest.h"
|
||||||
|
@ -74,8 +76,10 @@ static PRUint32 gGlyphExtentsSetupLazyTight = 0;
|
||||||
static PRUint32 gGlyphExtentsSetupFallBackToTight = 0;
|
static PRUint32 gGlyphExtentsSetupFallBackToTight = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gfxFontEntry::~gfxFontEntry() {
|
gfxFontEntry::~gfxFontEntry()
|
||||||
|
{
|
||||||
|
if (mUserFontData)
|
||||||
|
delete mUserFontData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +95,9 @@ gfxFontEntry *gfxFontFamily::FindFontForStyle(const gfxFontStyle& aFontStyle, PR
|
||||||
|
|
||||||
aNeedsBold = PR_FALSE;
|
aNeedsBold = PR_FALSE;
|
||||||
|
|
||||||
FindWeightsForStyle(weightList, aFontStyle);
|
PRBool foundWeights = FindWeightsForStyle(weightList, aFontStyle);
|
||||||
|
if (!foundWeights)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
PRInt8 baseWeight, weightDistance;
|
PRInt8 baseWeight, weightDistance;
|
||||||
aFontStyle.ComputeWeightAndOffset(&baseWeight, &weightDistance);
|
aFontStyle.ComputeWeightAndOffset(&baseWeight, &weightDistance);
|
||||||
|
@ -856,10 +862,32 @@ gfxGlyphExtents::SetTightGlyphExtents(PRUint32 aGlyphID, const gfxRect& aExtents
|
||||||
entry->height = aExtentsAppUnits.size.height;
|
entry->height = aExtentsAppUnits.size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle)
|
gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet *aUserFontSet)
|
||||||
: mFamilies(aFamilies), mStyle(*aStyle), mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET)
|
: mFamilies(aFamilies), mStyle(*aStyle), mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET)
|
||||||
{
|
{
|
||||||
|
mUserFontSet = nsnull;
|
||||||
|
SetUserFontSet(aUserFontSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontGroup::~gfxFontGroup() {
|
||||||
|
mFonts.Clear();
|
||||||
|
SetUserFontSet(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
gfxFontGroup::IsInvalidChar(PRUnichar ch) {
|
||||||
|
if (ch >= 32) {
|
||||||
|
return ch == 0x0085/*NEL*/ ||
|
||||||
|
((ch & 0xFF00) == 0x2000 /* Unicode control character */ &&
|
||||||
|
(ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/ ||
|
||||||
|
IS_BIDI_CONTROL_CHAR(ch)));
|
||||||
|
}
|
||||||
|
// We could just blacklist all control characters, but it seems better
|
||||||
|
// to only blacklist the ones we know cause problems for native font
|
||||||
|
// engines.
|
||||||
|
return ch == 0x0B || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' ||
|
||||||
|
(ch >= 0x1c && ch <= 0x1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -989,11 +1017,18 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
|
||||||
NS_LossyConvertUTF16toASCII gf(genericFamily);
|
NS_LossyConvertUTF16toASCII gf(genericFamily);
|
||||||
if (aResolveFontName) {
|
if (aResolveFontName) {
|
||||||
ResolveData data(fc, gf, closure);
|
ResolveData data(fc, gf, closure);
|
||||||
PRBool aborted;
|
PRBool aborted, needsBold;
|
||||||
gfxPlatform *pf = gfxPlatform::GetPlatform();
|
nsresult rv;
|
||||||
nsresult rv = pf->ResolveFontName(family,
|
|
||||||
|
if (mUserFontSet && mUserFontSet->FindFontEntry(family, mStyle, needsBold)) {
|
||||||
|
gfxFontGroup::FontResolverProc(family, &data);
|
||||||
|
rv = NS_OK;
|
||||||
|
} else {
|
||||||
|
gfxPlatform *pf = gfxPlatform::GetPlatform();
|
||||||
|
rv = pf->ResolveFontName(family,
|
||||||
gfxFontGroup::FontResolverProc,
|
gfxFontGroup::FontResolverProc,
|
||||||
&data, aborted);
|
&data, aborted);
|
||||||
|
}
|
||||||
if (NS_FAILED(rv) || aborted)
|
if (NS_FAILED(rv) || aborted)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1089,7 +1124,7 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh, PRUint32 aNextCh,
|
||||||
// if match, return
|
// if match, return
|
||||||
if (selectedFont)
|
if (selectedFont)
|
||||||
return selectedFont.forget();
|
return selectedFont.forget();
|
||||||
|
|
||||||
// if character is in Private Use Area, don't do matching against pref or system fonts
|
// if character is in Private Use Area, don't do matching against pref or system fonts
|
||||||
if ((aCh >= 0xE000 && aCh <= 0xF8FF) || (aCh >= 0xF0000 && aCh <= 0x10FFFD))
|
if ((aCh >= 0xE000 && aCh <= 0xF8FF) || (aCh >= 0xF0000 && aCh <= 0x10FFFD))
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -1169,6 +1204,29 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges, const PRUnicha
|
||||||
aRanges[aRanges.Length()-1].end = len;
|
aRanges[aRanges.Length()-1].end = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfxUserFontSet*
|
||||||
|
gfxFontGroup::GetUserFontSet()
|
||||||
|
{
|
||||||
|
return mUserFontSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gfxFontGroup::SetUserFontSet(gfxUserFontSet *aUserFontSet)
|
||||||
|
{
|
||||||
|
NS_IF_RELEASE(mUserFontSet);
|
||||||
|
mUserFontSet = aUserFontSet;
|
||||||
|
NS_IF_ADDREF(mUserFontSet);
|
||||||
|
mCurrGeneration = GetGeneration();
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint64
|
||||||
|
gfxFontGroup::GetGeneration()
|
||||||
|
{
|
||||||
|
if (!mUserFontSet)
|
||||||
|
return 0;
|
||||||
|
return mUserFontSet->GetGeneration();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
|
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
|
||||||
|
|
||||||
|
@ -1331,6 +1389,8 @@ gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams, const void
|
||||||
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
|
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
|
||||||
AccountStorageForTextRun(this, 1);
|
AccountStorageForTextRun(this, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mUserFontSetGeneration = mFontGroup->GetGeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxTextRun::~gfxTextRun()
|
gfxTextRun::~gfxTextRun()
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "nsIPrefLocalizedString.h"
|
#include "nsIPrefLocalizedString.h"
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
|
#include "nsIStreamBufferAccess.h"
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
|
||||||
#define NO_RANGE_FOUND 126 // bit 126 in the font unicode ranges is required to be 0
|
#define NO_RANGE_FOUND 126 // bit 126 in the font unicode ranges is required to be 0
|
||||||
|
|
||||||
|
@ -469,4 +471,558 @@ void gfxFontUtils::GetPrefsFontList(const char *aPrefName, nsTArray<nsString>& a
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for now, this is only needed on Windows
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
|
||||||
|
// TrueType/OpenType table handling code
|
||||||
|
|
||||||
|
// need byte aligned structs
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
struct AutoSwap_PRUint16 {
|
||||||
|
operator PRUint16() { return NS_SWAP16(value); }
|
||||||
|
operator PRUint32() { return NS_SWAP16(value); }
|
||||||
|
PRUint16 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AutoSwap_PRInt16 {
|
||||||
|
operator PRInt16() { return NS_SWAP16(value); }
|
||||||
|
operator PRUint32() { return NS_SWAP16(value); }
|
||||||
|
PRInt16 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AutoSwap_PRUint32 {
|
||||||
|
operator PRUint32() { return NS_SWAP32(value); }
|
||||||
|
PRUint32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AutoSwap_PRUint64 {
|
||||||
|
operator PRUint64() { return NS_SWAP64(value); }
|
||||||
|
PRUint64 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SFNTHeader {
|
||||||
|
AutoSwap_PRUint32 sfntVersion; // Fixed, 0x00010000 for version 1.0.
|
||||||
|
AutoSwap_PRUint16 numTables; // Number of tables.
|
||||||
|
AutoSwap_PRUint16 searchRange; // (Maximum power of 2 <= numTables) x 16.
|
||||||
|
AutoSwap_PRUint16 entrySelector; // Log2(maximum power of 2 <= numTables).
|
||||||
|
AutoSwap_PRUint16 rangeShift; // NumTables x 16-searchRange.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TableDirEntry {
|
||||||
|
AutoSwap_PRUint32 tag; // 4 -byte identifier.
|
||||||
|
AutoSwap_PRUint32 checkSum; // CheckSum for this table.
|
||||||
|
AutoSwap_PRUint32 offset; // Offset from beginning of TrueType font file.
|
||||||
|
AutoSwap_PRUint32 length; // Length of this table.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HeadTable {
|
||||||
|
enum {
|
||||||
|
HEAD_MAGIC_NUMBER = 0x5F0F3CF5
|
||||||
|
};
|
||||||
|
|
||||||
|
AutoSwap_PRUint32 tableVersionNumber; // Fixed, 0x00010000 for version 1.0.
|
||||||
|
AutoSwap_PRUint32 fontRevision; // Set by font manufacturer.
|
||||||
|
AutoSwap_PRUint32 checkSumAdjustment; // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
|
||||||
|
AutoSwap_PRUint32 magicNumber; // Set to 0x5F0F3CF5.
|
||||||
|
AutoSwap_PRUint16 flags;
|
||||||
|
AutoSwap_PRUint16 unitsPerEm; // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
|
||||||
|
AutoSwap_PRUint64 created; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
|
||||||
|
AutoSwap_PRUint64 modified; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
|
||||||
|
AutoSwap_PRInt16 xMin; // For all glyph bounding boxes.
|
||||||
|
AutoSwap_PRInt16 yMin; // For all glyph bounding boxes.
|
||||||
|
AutoSwap_PRInt16 xMax; // For all glyph bounding boxes.
|
||||||
|
AutoSwap_PRInt16 yMax; // For all glyph bounding boxes.
|
||||||
|
AutoSwap_PRUint16 macStyle; // Bit 0: Bold (if set to 1);
|
||||||
|
AutoSwap_PRUint16 lowestRecPPEM; // Smallest readable size in pixels.
|
||||||
|
AutoSwap_PRInt16 fontDirectionHint;
|
||||||
|
AutoSwap_PRInt16 indexToLocFormat;
|
||||||
|
AutoSwap_PRInt16 glyphDataFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
// name table has a header, followed by name records, followed by string data
|
||||||
|
struct NameHeader {
|
||||||
|
AutoSwap_PRUint16 format; // Format selector (=0).
|
||||||
|
AutoSwap_PRUint16 count; // Number of name records.
|
||||||
|
AutoSwap_PRUint16 stringOffset; // Offset to start of string storage (from start of table)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NameRecord {
|
||||||
|
AutoSwap_PRUint16 platformID; // Platform ID
|
||||||
|
AutoSwap_PRUint16 encodingID; // Platform-specific encoding ID
|
||||||
|
AutoSwap_PRUint16 languageID; // Language ID
|
||||||
|
AutoSwap_PRUint16 nameID; // Name ID.
|
||||||
|
AutoSwap_PRUint16 length; // String length (in bytes).
|
||||||
|
AutoSwap_PRUint16 offset; // String offset from start of storage area (in bytes).
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NAME_ID_FAMILY = 1,
|
||||||
|
NAME_ID_STYLE = 2,
|
||||||
|
NAME_ID_FULL = 4,
|
||||||
|
NAME_ID_VERSION = 5,
|
||||||
|
PLATFORM_ID_UNICODE = 0, // Mac OS uses this typically
|
||||||
|
PLATFORM_ID_MICROSOFT = 3,
|
||||||
|
ENCODING_ID_MICROSOFT_UNICODEBMP = 1, // with Microsoft platformID, BMP-only Unicode encoding
|
||||||
|
LANG_ID_MICROSOFT_EN_US = 0x0409 // with Microsoft platformID, EN US lang code
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OS2Table {
|
||||||
|
AutoSwap_PRUint16 version; // 0004 = OpenType 1.5
|
||||||
|
AutoSwap_PRInt16 xAvgCharWidth;
|
||||||
|
AutoSwap_PRUint16 usWeightClass;
|
||||||
|
AutoSwap_PRUint16 usWidthClass;
|
||||||
|
AutoSwap_PRUint16 fsType;
|
||||||
|
AutoSwap_PRInt16 ySubscriptXSize;
|
||||||
|
AutoSwap_PRInt16 ySubscriptYSize;
|
||||||
|
AutoSwap_PRInt16 ySubscriptXOffset;
|
||||||
|
AutoSwap_PRInt16 ySubscriptYOffset;
|
||||||
|
AutoSwap_PRInt16 ySuperscriptXSize;
|
||||||
|
AutoSwap_PRInt16 ySuperscriptYSize;
|
||||||
|
AutoSwap_PRInt16 ySuperscriptXOffset;
|
||||||
|
AutoSwap_PRInt16 ySuperscriptYOffset;
|
||||||
|
AutoSwap_PRInt16 yStrikeoutSize;
|
||||||
|
AutoSwap_PRInt16 yStrikeoutPosition;
|
||||||
|
AutoSwap_PRInt16 sFamilyClass;
|
||||||
|
PRUint8 panose[10];
|
||||||
|
AutoSwap_PRUint32 unicodeRange1;
|
||||||
|
AutoSwap_PRUint32 unicodeRange2;
|
||||||
|
AutoSwap_PRUint32 unicodeRange3;
|
||||||
|
AutoSwap_PRUint32 unicodeRange4;
|
||||||
|
PRUint8 achVendID[4];
|
||||||
|
AutoSwap_PRUint16 fsSelection;
|
||||||
|
AutoSwap_PRUint16 usFirstCharIndex;
|
||||||
|
AutoSwap_PRUint16 usLastCharIndex;
|
||||||
|
AutoSwap_PRInt16 sTypoAscender;
|
||||||
|
AutoSwap_PRInt16 sTypoDescender;
|
||||||
|
AutoSwap_PRInt16 sTypoLineGap;
|
||||||
|
AutoSwap_PRUint16 usWinAscent;
|
||||||
|
AutoSwap_PRUint16 usWinDescent;
|
||||||
|
AutoSwap_PRUint32 codePageRange1;
|
||||||
|
AutoSwap_PRUint32 codePageRange2;
|
||||||
|
AutoSwap_PRInt16 sxHeight;
|
||||||
|
AutoSwap_PRInt16 sCapHeight;
|
||||||
|
AutoSwap_PRUint16 usDefaultChar;
|
||||||
|
AutoSwap_PRUint16 usBreakChar;
|
||||||
|
AutoSwap_PRUint16 usMaxContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Embedded OpenType (EOT) handling
|
||||||
|
// needed for dealing with downloadable fonts on Windows
|
||||||
|
//
|
||||||
|
// EOT version 0x00020001
|
||||||
|
// based on http://www.w3.org/Submission/2008/SUBM-EOT-20080305/
|
||||||
|
//
|
||||||
|
// EOT header consists of a fixed-size portion containing general font
|
||||||
|
// info, followed by a variable-sized portion containing name data,
|
||||||
|
// followed by the actual TT/OT font data (non-byte values are always
|
||||||
|
// stored in big-endian format)
|
||||||
|
//
|
||||||
|
// EOT header is stored in *little* endian order!!
|
||||||
|
|
||||||
|
struct EOTFixedHeader {
|
||||||
|
|
||||||
|
PRUint32 eotSize; // Total structure length in PRUint8s (including string and font data)
|
||||||
|
PRUint32 fontDataSize; // Length of the OpenType font (FontData) in PRUint8s
|
||||||
|
PRUint32 version; // Version number of this format - 0x00010000
|
||||||
|
PRUint32 flags; // Processing Flags
|
||||||
|
PRUint8 panose[10]; // The PANOSE value for this font - See http://www.microsoft.com/typography/otspec/os2.htm#pan
|
||||||
|
PRUint8 charset; // In Windows this is derived from TEXTMETRIC.tmCharSet. This value specifies the character set of the font. DEFAULT_CHARSET (0x01) indicates no preference. - See http://msdn2.microsoft.com/en-us/library/ms534202.aspx
|
||||||
|
PRUint8 italic; // If the bit for ITALIC is set in OS/2.fsSelection, the value will be 0x01 - See http://www.microsoft.com/typography/otspec/os2.htm#fss
|
||||||
|
PRUint32 weight; // The weight value for this font - See http://www.microsoft.com/typography/otspec/os2.htm#wtc
|
||||||
|
PRUint16 fsType; // Type flags that provide information about embedding permissions - See http://www.microsoft.com/typography/otspec/os2.htm#fst
|
||||||
|
PRUint16 magicNumber; // Magic number for EOT file - 0x504C. Used to check for data corruption.
|
||||||
|
PRUint32 unicodeRange1; // OS/2.UnicodeRange1 (bits 0-31) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
|
||||||
|
PRUint32 unicodeRange2; // OS/2.UnicodeRange2 (bits 32-63) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
|
||||||
|
PRUint32 unicodeRange3; // OS/2.UnicodeRange3 (bits 64-95) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
|
||||||
|
PRUint32 unicodeRange4; // OS/2.UnicodeRange4 (bits 96-127) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
|
||||||
|
PRUint32 codePageRange1; // CodePageRange1 (bits 0-31) - See http://www.microsoft.com/typography/otspec/os2.htm#cpr
|
||||||
|
PRUint32 codePageRange2; // CodePageRange2 (bits 32-63) - See http://www.microsoft.com/typography/otspec/os2.htm#cpr
|
||||||
|
PRUint32 checkSumAdjustment; // head.CheckSumAdjustment - See http://www.microsoft.com/typography/otspec/head.htm
|
||||||
|
PRUint32 reserved[4]; // Reserved - must be 0
|
||||||
|
PRUint16 padding1; // Padding to maintain long alignment. Padding value must always be set to 0x0000.
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EOT_VERSION = 0x00020001,
|
||||||
|
EOT_MAGIC_NUMBER = 0x504c,
|
||||||
|
EOT_DEFAULT_CHARSET = 0x01,
|
||||||
|
EOT_EMBED_PRINT_PREVIEW = 0x0004,
|
||||||
|
EOT_FAMILY_NAME_INDEX = 0, // order of names in variable portion of EOT header
|
||||||
|
EOT_STYLE_NAME_INDEX = 1,
|
||||||
|
EOT_VERSION_NAME_INDEX = 2,
|
||||||
|
EOT_FULL_NAME_INDEX = 3,
|
||||||
|
EOT_NUM_NAMES = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// EOT variable-sized header (version 0x00020001 - contains 4 name
|
||||||
|
// fields, each with the structure):
|
||||||
|
//
|
||||||
|
// // number of bytes in the name array
|
||||||
|
// PRUint16 size;
|
||||||
|
// // array of UTF-16 chars, total length = <size> bytes
|
||||||
|
// // note: english version of name record string
|
||||||
|
// PRUint8 name[size];
|
||||||
|
//
|
||||||
|
// This structure is used for the following names, each separated by two
|
||||||
|
// bytes of padding (always 0 with no padding after the rootString):
|
||||||
|
//
|
||||||
|
// familyName - based on name ID = 1
|
||||||
|
// styleName - based on name ID = 2
|
||||||
|
// versionName - based on name ID = 5
|
||||||
|
// fullName - based on name ID = 4
|
||||||
|
// rootString - used to restrict font usage to a specific domain
|
||||||
|
//
|
||||||
|
|
||||||
|
class AutoCloseFile {
|
||||||
|
public:
|
||||||
|
AutoCloseFile(PRFileDesc *aFileDesc)
|
||||||
|
: mFile(aFileDesc) { }
|
||||||
|
~AutoCloseFile() { PR_Close(mFile); }
|
||||||
|
PRFileDesc *mFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
static PRFileDesc *
|
||||||
|
OpenFontFile(nsIFile *aFontData)
|
||||||
|
{
|
||||||
|
// open up the font file
|
||||||
|
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFontData);
|
||||||
|
if (!localFile)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
PRFileDesc *fd;
|
||||||
|
nsresult rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
|
||||||
|
if (NS_FAILED(rv) || !fd)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
IsValidVersion(PRUint32 version)
|
||||||
|
{
|
||||||
|
// normally 0x00010000, CFF-style OT fonts == 'OTTO' and Apple TT fonts = 'true'
|
||||||
|
return version == 0x10000 || version == 'OTTO' || version == 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy and swap UTF-16 values, assume no surrogate pairs, can be in place
|
||||||
|
static void
|
||||||
|
CopySwapUTF16(PRUint16 *aInBuf, PRUint16 *aOutBuf, PRUint32 aLen)
|
||||||
|
{
|
||||||
|
PRUint16 *end = aInBuf + aLen;
|
||||||
|
while (aInBuf < end) {
|
||||||
|
PRUint16 value = *aInBuf;
|
||||||
|
*aOutBuf = (value >> 8) | (value & 0xff) << 8;
|
||||||
|
aOutBuf++;
|
||||||
|
aInBuf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// name table stores set of name record structures, followed by
|
||||||
|
// large block containing all the strings. name record offset and length
|
||||||
|
// indicates the offset and length within that block.
|
||||||
|
// http://www.microsoft.com/typography/otspec/name.htm
|
||||||
|
struct NameRecordData {
|
||||||
|
PRUint32 offset;
|
||||||
|
PRUint32 length;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
static void DumpEOTHeader(PRUint8 *aHeader, PRUint32 aHeaderLen)
|
||||||
|
{
|
||||||
|
PRUint32 offset = 0;
|
||||||
|
PRUint8 *ch = aHeader;
|
||||||
|
|
||||||
|
printf("\n\nlen == %d\n\n", aHeaderLen);
|
||||||
|
while (offset < aHeaderLen) {
|
||||||
|
printf("%7.7x ", offset);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
printf("%2.2x ", *ch++);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
offset += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
gfxFontUtils::MakeEOTHeader(nsIFile *aFontData, nsTArray<PRUint8> *aHeader,
|
||||||
|
PRBool *aIsCFF)
|
||||||
|
{
|
||||||
|
PRInt32 bytesRead;
|
||||||
|
|
||||||
|
// assume TrueType
|
||||||
|
*aIsCFF = PR_FALSE;
|
||||||
|
|
||||||
|
NS_ASSERTION(aHeader, "null header");
|
||||||
|
NS_ASSERTION(aHeader->Length() == 0, "non-empty header passed in");
|
||||||
|
NS_ASSERTION(aIsCFF, "null boolean ptr");
|
||||||
|
|
||||||
|
if (!aHeader->AppendElements(sizeof(EOTFixedHeader)))
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
EOTFixedHeader *eotHeader = reinterpret_cast<EOTFixedHeader*> (aHeader->Elements());
|
||||||
|
memset(eotHeader, 0, sizeof(EOTFixedHeader));
|
||||||
|
|
||||||
|
// open the font file
|
||||||
|
PRFileDesc *fd = OpenFontFile(aFontData);
|
||||||
|
if (!fd)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
AutoCloseFile autoCloseFile(fd);
|
||||||
|
|
||||||
|
PRFileInfo64 fileInfo;
|
||||||
|
if (PR_GetOpenFileInfo64(fd, &fileInfo) != PR_SUCCESS
|
||||||
|
|| fileInfo.size > PRInt64(0xFFFFFFFF))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRUint32 fontDataSize = PRUint32(fileInfo.size);
|
||||||
|
|
||||||
|
// set up header fields
|
||||||
|
eotHeader->fontDataSize = fontDataSize;
|
||||||
|
eotHeader->version = EOTFixedHeader::EOT_VERSION;
|
||||||
|
eotHeader->flags = 0; // don't specify any special processing
|
||||||
|
eotHeader->charset = EOTFixedHeader::EOT_DEFAULT_CHARSET;
|
||||||
|
eotHeader->fsType = EOTFixedHeader::EOT_EMBED_PRINT_PREVIEW;
|
||||||
|
eotHeader->magicNumber = EOTFixedHeader::EOT_MAGIC_NUMBER;
|
||||||
|
|
||||||
|
// read in the sfnt header
|
||||||
|
SFNTHeader sfntHeader;
|
||||||
|
bytesRead = PR_Read(fd, &sfntHeader, sizeof(SFNTHeader));
|
||||||
|
if (bytesRead != sizeof(SFNTHeader) || !IsValidVersion(sfntHeader.sfntVersion))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// iterate through the table headers to find the head, name and OS/2 tables
|
||||||
|
PRBool foundHead = PR_FALSE, foundOS2 = PR_FALSE, foundName = PR_FALSE, foundGlyphs = PR_FALSE;
|
||||||
|
PRUint32 headOffset, headLen, nameOffset, nameLen, os2Offset, os2Len;
|
||||||
|
PRUint32 i, numTables;
|
||||||
|
|
||||||
|
numTables = sfntHeader.numTables;
|
||||||
|
for (i = 0; i < numTables; i++) {
|
||||||
|
TableDirEntry dirEntry;
|
||||||
|
bytesRead = PR_Read(fd, &dirEntry, sizeof(TableDirEntry));
|
||||||
|
if (bytesRead != sizeof(TableDirEntry))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
switch (dirEntry.tag) {
|
||||||
|
|
||||||
|
case 'head':
|
||||||
|
foundHead = PR_TRUE;
|
||||||
|
headOffset = dirEntry.offset;
|
||||||
|
headLen = dirEntry.length;
|
||||||
|
if (headLen < sizeof(HeadTable))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'name':
|
||||||
|
foundName = PR_TRUE;
|
||||||
|
nameOffset = dirEntry.offset;
|
||||||
|
nameLen = dirEntry.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'OS/2':
|
||||||
|
foundOS2 = PR_TRUE;
|
||||||
|
os2Offset = dirEntry.offset;
|
||||||
|
os2Len = dirEntry.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'glyf': // TrueType-style quadratic glyph table
|
||||||
|
foundGlyphs = PR_TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CFF ': // PS-style cubic glyph table
|
||||||
|
foundGlyphs = PR_TRUE;
|
||||||
|
*aIsCFF = PR_TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundHead && foundName && foundOS2 && foundGlyphs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// require these three tables on Windows
|
||||||
|
if (!foundHead || !foundName || !foundOS2)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// read in the data from those tables
|
||||||
|
PROffset64 offset;
|
||||||
|
|
||||||
|
// -- head table data
|
||||||
|
HeadTable headData;
|
||||||
|
offset = PR_Seek64(fd, PROffset64(headOffset), PR_SEEK_SET);
|
||||||
|
if (offset == -1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
bytesRead = PR_Read(fd, &headData, sizeof(HeadTable));
|
||||||
|
if (bytesRead != sizeof(HeadTable) || headData.magicNumber != HeadTable::HEAD_MAGIC_NUMBER)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
eotHeader->checkSumAdjustment = headData.checkSumAdjustment;
|
||||||
|
|
||||||
|
// -- name table data
|
||||||
|
|
||||||
|
// -- first, read name table header
|
||||||
|
NameHeader nameHeader;
|
||||||
|
|
||||||
|
offset = PR_Seek64(fd, PROffset64(nameOffset), PR_SEEK_SET);
|
||||||
|
if (offset == -1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
bytesRead = PR_Read(fd, &nameHeader, sizeof(NameHeader));
|
||||||
|
if (bytesRead != sizeof(NameHeader))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// -- seek point is now at the start of name records
|
||||||
|
|
||||||
|
// -- iterate through name records, look for specific name ids with
|
||||||
|
// matching platform/encoding/etc. and store offset/lengths
|
||||||
|
NameRecordData names[EOTFixedHeader::EOT_NUM_NAMES] = {0};
|
||||||
|
PRUint32 nameCount = nameHeader.count;
|
||||||
|
|
||||||
|
for (i = 0; i < nameCount; i++) {
|
||||||
|
NameRecord nameRecord;
|
||||||
|
|
||||||
|
bytesRead = PR_Read(fd, &nameRecord, sizeof(NameRecord));
|
||||||
|
if (bytesRead != sizeof(NameRecord))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// looking for Microsoft English US name strings, skip others
|
||||||
|
if (PRUint32(nameRecord.platformID) != NameRecord::PLATFORM_ID_MICROSOFT ||
|
||||||
|
PRUint32(nameRecord.encodingID) != NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP ||
|
||||||
|
PRUint32(nameRecord.languageID) != NameRecord::LANG_ID_MICROSOFT_EN_US)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch ((PRUint32)nameRecord.nameID) {
|
||||||
|
|
||||||
|
case NameRecord::NAME_ID_FAMILY:
|
||||||
|
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].offset = nameRecord.offset;
|
||||||
|
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length = nameRecord.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NameRecord::NAME_ID_STYLE:
|
||||||
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].offset = nameRecord.offset;
|
||||||
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length = nameRecord.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NameRecord::NAME_ID_FULL:
|
||||||
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].offset = nameRecord.offset;
|
||||||
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length = nameRecord.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NameRecord::NAME_ID_VERSION:
|
||||||
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].offset = nameRecord.offset;
|
||||||
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length = nameRecord.length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length &&
|
||||||
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length))
|
||||||
|
{
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- expand buffer if needed to include variable-length portion
|
||||||
|
PRUint32 eotVariableLength = 0;
|
||||||
|
eotVariableLength = (names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length & (~1)) +
|
||||||
|
(names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length & (~1)) +
|
||||||
|
(names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length & (~1)) +
|
||||||
|
(names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length & (~1)) +
|
||||||
|
EOTFixedHeader::EOT_NUM_NAMES * (2 /* size */
|
||||||
|
+ 2 /* padding */) +
|
||||||
|
2 /* null root string size */;
|
||||||
|
|
||||||
|
if (!aHeader->AppendElements(eotVariableLength))
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
// append the string data to the end of the EOT header
|
||||||
|
PRUint8 *eotEnd = aHeader->Elements() + sizeof(EOTFixedHeader);
|
||||||
|
PROffset64 strOffset;
|
||||||
|
PRUint32 strLen;
|
||||||
|
|
||||||
|
for (i = 0; i < EOTFixedHeader::EOT_NUM_NAMES; i++) {
|
||||||
|
PRUint32 namelen = names[i].length;
|
||||||
|
PRUint32 nameoff = names[i].offset; // offset from base of string storage
|
||||||
|
|
||||||
|
strOffset = nameOffset + PRUint32(nameHeader.stringOffset) + nameoff;
|
||||||
|
offset = PR_Seek64(fd, strOffset, PR_SEEK_SET);
|
||||||
|
if (offset == -1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// output 2-byte str size
|
||||||
|
strLen = namelen & (~1); // UTF-16 string len must be even
|
||||||
|
*((PRUint16*) eotEnd) = PRUint16(strLen);
|
||||||
|
eotEnd += 2;
|
||||||
|
|
||||||
|
// read in actual string and swap bytes from big-endian
|
||||||
|
// (TrueType/OpenType) to little-endian (EOT)
|
||||||
|
bytesRead = PR_Read(fd, eotEnd, strLen);
|
||||||
|
if (PRUint32(bytesRead) != strLen)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// length is number of UTF-16 chars, not bytes
|
||||||
|
CopySwapUTF16(reinterpret_cast<PRUint16*>(eotEnd),
|
||||||
|
reinterpret_cast<PRUint16*>(eotEnd),
|
||||||
|
(strLen >> 1));
|
||||||
|
eotEnd += strLen;
|
||||||
|
|
||||||
|
// add 2-byte zero padding to the end of each string
|
||||||
|
*eotEnd++ = 0;
|
||||||
|
*eotEnd++ = 0;
|
||||||
|
|
||||||
|
// Note: Microsoft's WEFT tool produces name strings which
|
||||||
|
// include an extra null at the end of each string, in addition
|
||||||
|
// to the 2-byte zero padding that separates the string fields.
|
||||||
|
// Don't think this is important to imitate...
|
||||||
|
}
|
||||||
|
|
||||||
|
// append null root string size
|
||||||
|
*eotEnd++ = 0;
|
||||||
|
*eotEnd++ = 0;
|
||||||
|
|
||||||
|
NS_ASSERTION(eotEnd == aHeader->Elements() + aHeader->Length(),
|
||||||
|
"header length calculation incorrect");
|
||||||
|
|
||||||
|
// -- OS/2 table data
|
||||||
|
OS2Table os2Data;
|
||||||
|
offset = PR_Seek64(fd, PROffset64(os2Offset), PR_SEEK_SET);
|
||||||
|
if (offset == -1)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
bytesRead = PR_Read(fd, &os2Data, sizeof(OS2Table));
|
||||||
|
if (bytesRead != sizeof(OS2Table))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
memcpy(eotHeader->panose, os2Data.panose, sizeof(eotHeader->panose));
|
||||||
|
|
||||||
|
eotHeader->italic = (PRUint16) os2Data.fsSelection & 0x01;
|
||||||
|
eotHeader->weight = os2Data.usWeightClass;
|
||||||
|
eotHeader->unicodeRange1 = os2Data.unicodeRange1;
|
||||||
|
eotHeader->unicodeRange2 = os2Data.unicodeRange2;
|
||||||
|
eotHeader->unicodeRange3 = os2Data.unicodeRange3;
|
||||||
|
eotHeader->unicodeRange4 = os2Data.unicodeRange4;
|
||||||
|
eotHeader->codePageRange1 = os2Data.codePageRange1;
|
||||||
|
eotHeader->codePageRange2 = os2Data.codePageRange2;
|
||||||
|
|
||||||
|
eotHeader->eotSize = aHeader->Length() + fontDataSize;
|
||||||
|
|
||||||
|
// DumpEOTHeader(aHeader->Elements(), aHeader->Length());
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -457,8 +457,9 @@ already_AddRefed<gfxOS2Font> gfxOS2Font::GetOrMakeFont(const nsAString& aName,
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
gfxOS2FontGroup::gfxOS2FontGroup(const nsAString& aFamilies,
|
gfxOS2FontGroup::gfxOS2FontGroup(const nsAString& aFamilies,
|
||||||
const gfxFontStyle* aStyle)
|
const gfxFontStyle* aStyle,
|
||||||
: gfxFontGroup(aFamilies, aStyle)
|
gfxUserFontSet *aUserFontSet)
|
||||||
|
: gfxFontGroup(aFamilies, aStyle, aUserFontSet)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_thebes_2
|
#ifdef DEBUG_thebes_2
|
||||||
printf("gfxOS2FontGroup[%#x]::gfxOS2FontGroup(\"%s\", %#x)\n",
|
printf("gfxOS2FontGroup[%#x]::gfxOS2FontGroup(\"%s\", %#x)\n",
|
||||||
|
@ -510,7 +511,7 @@ gfxOS2FontGroup::~gfxOS2FontGroup()
|
||||||
|
|
||||||
gfxFontGroup *gfxOS2FontGroup::Copy(const gfxFontStyle *aStyle)
|
gfxFontGroup *gfxOS2FontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
{
|
{
|
||||||
return new gfxOS2FontGroup(mFamilies, aStyle);
|
return new gfxOS2FontGroup(mFamilies, aStyle, mUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -164,9 +164,10 @@ gfxOS2Platform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFa
|
||||||
|
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxOS2Platform::CreateFontGroup(const nsAString &aFamilies,
|
gfxOS2Platform::CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
return new gfxOS2FontGroup(aFamilies, aStyle);
|
return new gfxOS2FontGroup(aFamilies, aStyle, aUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<gfxOS2Font>
|
already_AddRefed<gfxOS2Font>
|
||||||
|
|
|
@ -784,8 +784,9 @@ FontCallback (const nsAString& fontName, const nsACString& genericName,
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxPangoFontGroup::gfxPangoFontGroup (const nsAString& families,
|
gfxPangoFontGroup::gfxPangoFontGroup (const nsAString& families,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
: gfxFontGroup(families, aStyle),
|
gfxUserFontSet *aUserFontSet)
|
||||||
|
: gfxFontGroup(families, aStyle, aUserFontSet),
|
||||||
mBasePangoFont(nsnull), mAdjustedSize(0)
|
mBasePangoFont(nsnull), mAdjustedSize(0)
|
||||||
{
|
{
|
||||||
mFonts.AppendElements(1);
|
mFonts.AppendElements(1);
|
||||||
|
@ -800,7 +801,7 @@ gfxPangoFontGroup::~gfxPangoFontGroup()
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxPangoFontGroup::Copy(const gfxFontStyle *aStyle)
|
gfxPangoFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
{
|
{
|
||||||
return new gfxPangoFontGroup(mFamilies, aStyle);
|
return new gfxPangoFontGroup(mFamilies, aStyle, mUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A string of family names suitable for fontconfig
|
// A string of family names suitable for fontconfig
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "gfxImageSurface.h"
|
#include "gfxImageSurface.h"
|
||||||
#include "gfxTextRunCache.h"
|
#include "gfxTextRunCache.h"
|
||||||
#include "gfxTextRunWordCache.h"
|
#include "gfxTextRunWordCache.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#include "nsIPref.h"
|
#include "nsIPref.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
@ -304,6 +305,29 @@ gfxPlatform::UpdateFontList()
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GFX_DOWNLOADABLE_FONTS_ENABLED "gfx.downloadable_fonts.enabled"
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
gfxPlatform::DownloadableFontsEnabled()
|
||||||
|
{
|
||||||
|
static PRBool initialized = PR_FALSE;
|
||||||
|
static PRBool allowDownloadableFonts = PR_FALSE;
|
||||||
|
|
||||||
|
if (initialized == PR_FALSE) {
|
||||||
|
initialized = PR_TRUE;
|
||||||
|
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||||
|
if (prefs) {
|
||||||
|
PRBool allow;
|
||||||
|
nsresult rv = prefs->GetBoolPref(GFX_DOWNLOADABLE_FONTS_ENABLED, &allow);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
allowDownloadableFonts = allow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allowDownloadableFonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AppendGenericFontFromPref(nsString& aFonts, const char *aLangGroup, const char *aGenericName)
|
AppendGenericFontFromPref(nsString& aFonts, const char *aLangGroup, const char *aGenericName)
|
||||||
{
|
{
|
||||||
|
|
|
@ -267,9 +267,10 @@ gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFa
|
||||||
|
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
|
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
return new gfxPangoFontGroup(aFamilies, aStyle);
|
return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#include "gfxQuartzFontCache.h"
|
#include "gfxQuartzFontCache.h"
|
||||||
#include "gfxAtsuiFonts.h"
|
#include "gfxAtsuiFonts.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
|
@ -115,9 +116,36 @@ gfxPlatformMac::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFa
|
||||||
|
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxPlatformMac::CreateFontGroup(const nsAString &aFamilies,
|
gfxPlatformMac::CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
return new gfxAtsuiFontGroup(aFamilies, aStyle);
|
return new gfxAtsuiFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxPlatformMac::LookupLocalFont(const nsAString& aFontName)
|
||||||
|
{
|
||||||
|
return gfxQuartzFontCache::SharedFontCache()->LookupLocalFont(aFontName);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxPlatformMac::MakePlatformFont(const gfxFontEntry *aProxyEntry, const gfxDownloadedFontData* aFontData)
|
||||||
|
{
|
||||||
|
return gfxQuartzFontCache::SharedFontCache()->MakePlatformFont(aProxyEntry, aFontData);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
gfxPlatformMac::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags)
|
||||||
|
{
|
||||||
|
// reject based on format flags
|
||||||
|
if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_EOT | gfxUserFontSet::FLAG_FORMAT_SVG)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reject based on filetype in URI
|
||||||
|
|
||||||
|
// otherwise, return true
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -83,13 +83,15 @@ public:
|
||||||
ATSUFontID GetFontID();
|
ATSUFontID GetFontID();
|
||||||
nsresult ReadCMAP();
|
nsresult ReadCMAP();
|
||||||
|
|
||||||
MacOSFamilyEntry* FamilyEntry() { return mFamily; }
|
|
||||||
protected:
|
protected:
|
||||||
|
// for use with data fonts
|
||||||
|
MacOSFontEntry(ATSUFontID aFontID, PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle, gfxUserFontData *aUserFontData);
|
||||||
|
|
||||||
PRUint32 mTraits;
|
PRUint32 mTraits;
|
||||||
MacOSFamilyEntry *mFamily;
|
MacOSFamilyEntry *mFamily;
|
||||||
|
|
||||||
PRPackedBool mATSUIDInitialized;
|
|
||||||
ATSUFontID mATSUFontID;
|
ATSUFontID mATSUFontID;
|
||||||
|
PRPackedBool mATSUIDInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper class for adding other family names back into font cache
|
// helper class for adding other family names back into font cache
|
||||||
|
@ -103,9 +105,8 @@ public:
|
||||||
friend class gfxQuartzFontCache;
|
friend class gfxQuartzFontCache;
|
||||||
|
|
||||||
// name is canonical font family name returned from NSFontManager
|
// name is canonical font family name returned from NSFontManager
|
||||||
MacOSFamilyEntry(nsString &aName) :
|
MacOSFamilyEntry(nsAString &aName) :
|
||||||
gfxFontFamily(aName), mOtherFamilyNamesInitialized(PR_FALSE), mHasOtherFamilyNames(PR_FALSE),
|
gfxFontFamily(aName), mOtherFamilyNamesInitialized(PR_FALSE), mHasOtherFamilyNames(PR_FALSE)
|
||||||
mIsBadUnderlineFontFamily(PR_FALSE)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~MacOSFamilyEntry() {}
|
virtual ~MacOSFamilyEntry() {}
|
||||||
|
@ -132,7 +133,7 @@ public:
|
||||||
virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor);
|
virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor);
|
||||||
|
|
||||||
// search for a specific face using the Postscript name
|
// search for a specific face using the Postscript name
|
||||||
MacOSFontEntry* FindFont(const nsString& aPostscriptName);
|
MacOSFontEntry* FindFont(const nsAString& aPostscriptName);
|
||||||
|
|
||||||
// read in cmaps for all the faces
|
// read in cmaps for all the faces
|
||||||
void ReadCMAP() {
|
void ReadCMAP() {
|
||||||
|
@ -141,9 +142,12 @@ public:
|
||||||
mAvailableFonts[i]->ReadCMAP();
|
mAvailableFonts[i]->ReadCMAP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set whether this font family is in "bad" underline offset blacklist.
|
||||||
// whether this font family is in "bad" underline offset blacklist.
|
void SetBadUnderlineFont(PRBool aIsBadUnderlineFont) {
|
||||||
PRBool IsBadUnderlineFontFamily() { return mIsBadUnderlineFontFamily != 0; }
|
PRUint32 i, numFonts = mAvailableFonts.Length();
|
||||||
|
for (i = 0; i < numFonts; i++)
|
||||||
|
mAvailableFonts[i]->mIsBadUnderlineFont = aIsBadUnderlineFont;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -158,14 +162,13 @@ protected:
|
||||||
nsTArray<nsRefPtr<MacOSFontEntry> > mAvailableFonts;
|
nsTArray<nsRefPtr<MacOSFontEntry> > mAvailableFonts;
|
||||||
PRPackedBool mOtherFamilyNamesInitialized;
|
PRPackedBool mOtherFamilyNamesInitialized;
|
||||||
PRPackedBool mHasOtherFamilyNames;
|
PRPackedBool mHasOtherFamilyNames;
|
||||||
PRPackedBool mIsBadUnderlineFontFamily;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// special-case situation where specific faces need to be treated as separate font family
|
// special-case situation where specific faces need to be treated as separate font family
|
||||||
class SingleFaceFamily : public MacOSFamilyEntry
|
class SingleFaceFamily : public MacOSFamilyEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SingleFaceFamily(nsString &aName) :
|
SingleFaceFamily(nsAString &aName) :
|
||||||
MacOSFamilyEntry(aName)
|
MacOSFamilyEntry(aName)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -222,6 +225,10 @@ public:
|
||||||
|
|
||||||
void AddOtherFamilyName(MacOSFamilyEntry *aFamilyEntry, nsAString& aOtherFamilyName);
|
void AddOtherFamilyName(MacOSFamilyEntry *aFamilyEntry, nsAString& aOtherFamilyName);
|
||||||
|
|
||||||
|
gfxFontEntry* LookupLocalFont(const nsAString& aFontName);
|
||||||
|
|
||||||
|
gfxFontEntry* MakePlatformFont(const gfxFontEntry *aProxyEntry, const gfxDownloadedFontData* aFontData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PLDHashOperator PR_CALLBACK FindFontForCharProc(nsStringHashKey::KeyType aKey,
|
static PLDHashOperator PR_CALLBACK FindFontForCharProc(nsStringHashKey::KeyType aKey,
|
||||||
nsRefPtr<MacOSFamilyEntry>& aFamilyEntry,
|
nsRefPtr<MacOSFamilyEntry>& aFamilyEntry,
|
||||||
|
@ -244,7 +251,7 @@ private:
|
||||||
// commonly used fonts for which the name table should be loaded at startup
|
// commonly used fonts for which the name table should be loaded at startup
|
||||||
void PreloadNamesList();
|
void PreloadNamesList();
|
||||||
|
|
||||||
// initialize the MacOSFamilyEntry::mIsBadUnderlineFontFamily from pref.
|
// initialize the bad underline blacklist from pref.
|
||||||
void InitBadUnderlineList();
|
void InitBadUnderlineList();
|
||||||
|
|
||||||
// eliminate faces which have the same ATSUI id
|
// eliminate faces which have the same ATSUI id
|
||||||
|
@ -293,6 +300,13 @@ private:
|
||||||
PRUint32 mStartIndex;
|
PRUint32 mStartIndex;
|
||||||
PRUint32 mIncrement;
|
PRUint32 mIncrement;
|
||||||
PRUint32 mNumFamilies;
|
PRUint32 mNumFamilies;
|
||||||
|
|
||||||
|
// keep track of ATS generation to prevent unneeded updates when loading downloaded fonts
|
||||||
|
PRUint32 mATSGeneration;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kATSGenerationInitial = -1
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GFXQUARTZFONTCACHE_H_ */
|
#endif /* GFXQUARTZFONTCACHE_H_ */
|
||||||
|
|
|
@ -44,10 +44,18 @@
|
||||||
#include "gfxPlatformMac.h"
|
#include "gfxPlatformMac.h"
|
||||||
#include "gfxQuartzFontCache.h"
|
#include "gfxQuartzFontCache.h"
|
||||||
#include "gfxAtsuiFonts.h"
|
#include "gfxAtsuiFonts.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#include "nsIPref.h" // for pref changes callback notification
|
#include "nsIPref.h" // for pref changes callback notification
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
|
#include "nsDirectoryServiceUtils.h"
|
||||||
|
#include "nsDirectoryServiceDefs.h"
|
||||||
|
#include "nsISimpleEnumerator.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
// _atsFontID is private; add it in our new category to NSFont
|
// _atsFontID is private; add it in our new category to NSFont
|
||||||
@interface NSFont (MozillaCategory)
|
@interface NSFont (MozillaCategory)
|
||||||
- (ATSUFontID)_atsFontID;
|
- (ATSUFontID)_atsFontID;
|
||||||
|
@ -113,12 +121,47 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
||||||
: gfxFontEntry(aPostscriptName), mTraits(aTraits), mFamily(aFamily), mATSUFontID(0),
|
: gfxFontEntry(aPostscriptName), mTraits(aTraits), mFamily(aFamily), mATSUFontID(0),
|
||||||
mATSUIDInitialized(0)
|
mATSUIDInitialized(0)
|
||||||
{
|
{
|
||||||
mWeight = gfxQuartzFontCache::AppleWeightToCSSWeight(aAppleWeight);
|
mWeight = gfxQuartzFontCache::AppleWeightToCSSWeight(aAppleWeight) * 100;
|
||||||
|
|
||||||
mItalic = (mTraits & NSItalicFontMask ? 1 : 0);
|
mItalic = (mTraits & NSItalicFontMask ? 1 : 0);
|
||||||
mFixedPitch = (mTraits & NSFixedPitchFontMask ? 1 : 0);
|
mFixedPitch = (mTraits & NSFixedPitchFontMask ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MacOSFontEntry::MacOSFontEntry(ATSUFontID aFontID, PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle, gfxUserFontData *aUserFontData)
|
||||||
|
{
|
||||||
|
// xxx - stretch is basically ignored for now
|
||||||
|
|
||||||
|
mATSUIDInitialized = PR_TRUE;
|
||||||
|
mATSUFontID = aFontID;
|
||||||
|
mUserFontData = aUserFontData;
|
||||||
|
mWeight = aWeight;
|
||||||
|
mStretch = aStretch;
|
||||||
|
mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
|
||||||
|
mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
|
||||||
|
|
||||||
|
mTraits = (mItalic ? NSItalicFontMask : NSUnitalicFontMask) |
|
||||||
|
(mFixedPitch ? NSFixedPitchFontMask : 0) |
|
||||||
|
(mWeight >= 600 ? NSBoldFontMask : NSUnboldFontMask);
|
||||||
|
|
||||||
|
// get the postscript name
|
||||||
|
OSStatus err;
|
||||||
|
NSString *psname = NULL;
|
||||||
|
|
||||||
|
// now lookup the Postscript name
|
||||||
|
err = ATSFontGetPostScriptName((ATSFontRef) aFontID, kATSOptionFlagsDefault, (CFStringRef*) (&psname));
|
||||||
|
if (err == noErr) {
|
||||||
|
GetStringForNSString(psname, mName);
|
||||||
|
[psname release];
|
||||||
|
} else {
|
||||||
|
mIsValid = PR_FALSE;
|
||||||
|
#if DEBUG
|
||||||
|
char warnBuf[1024];
|
||||||
|
sprintf(warnBuf, "ATSFontGetPostScriptName err = %d", (PRInt32)err);
|
||||||
|
NS_WARNING(warnBuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const nsString&
|
const nsString&
|
||||||
MacOSFontEntry::FamilyName()
|
MacOSFontEntry::FamilyName()
|
||||||
{
|
{
|
||||||
|
@ -174,7 +217,14 @@ MacOSFontEntry::ReadCMAP()
|
||||||
|
|
||||||
status = ATSFontGetTable(fontID, 'cmap', 0, 0, 0, &size);
|
status = ATSFontGetTable(fontID, 'cmap', 0, 0, 0, &size);
|
||||||
cmapSize = size;
|
cmapSize = size;
|
||||||
//printf( "cmap size: %s %d\n", NS_ConvertUTF16toUTF8(mName).get(), size );
|
//printf( "cmap size: %s %d", NS_ConvertUTF16toUTF8(mName).get(), size );
|
||||||
|
#if DEBUG
|
||||||
|
if (status != noErr) {
|
||||||
|
char warnBuf[1024];
|
||||||
|
sprintf(warnBuf, "ATSFontGetTable returned %d for (%s)", (PRInt32)status, NS_ConvertUTF16toUTF8(mName).get());
|
||||||
|
NS_WARNING(warnBuf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
NS_ENSURE_TRUE(status == noErr, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(status == noErr, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsAutoTArray<PRUint8,16384> buffer;
|
nsAutoTArray<PRUint8,16384> buffer;
|
||||||
|
@ -298,7 +348,7 @@ MacOSFamilyEntry::FindFont(const gfxFontStyle* aStyle, PRBool& aNeedsBold)
|
||||||
}
|
}
|
||||||
|
|
||||||
MacOSFontEntry*
|
MacOSFontEntry*
|
||||||
MacOSFamilyEntry::FindFont(const nsString& aPostscriptName)
|
MacOSFamilyEntry::FindFont(const nsAString& aPostscriptName)
|
||||||
{
|
{
|
||||||
// find the font using a simple linear search
|
// find the font using a simple linear search
|
||||||
PRUint32 numFonts = mAvailableFonts.Length();
|
PRUint32 numFonts = mAvailableFonts.Length();
|
||||||
|
@ -339,7 +389,7 @@ MacOSFamilyEntry::FindFontForChar(FontSearch *aMatchData)
|
||||||
|
|
||||||
// italics
|
// italics
|
||||||
if (fe->IsItalic() &&
|
if (fe->IsItalic() &&
|
||||||
(style->style == FONT_STYLE_ITALIC || style->style == FONT_STYLE_ITALIC)) {
|
(style->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0) {
|
||||||
rank += 5;
|
rank += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +401,7 @@ MacOSFamilyEntry::FindFontForChar(FontSearch *aMatchData)
|
||||||
// the "next bolder/lighter face"
|
// the "next bolder/lighter face"
|
||||||
PRUint32 targetWeight = (baseWeight * 100) + (weightDistance * 100);
|
PRUint32 targetWeight = (baseWeight * 100) + (weightDistance * 100);
|
||||||
|
|
||||||
PRUint32 entryWeight = fe->Weight() * 100;
|
PRUint32 entryWeight = fe->Weight();
|
||||||
if (entryWeight == targetWeight) {
|
if (entryWeight == targetWeight) {
|
||||||
rank += 5;
|
rank += 5;
|
||||||
} else {
|
} else {
|
||||||
|
@ -393,7 +443,8 @@ MacOSFamilyEntry::FindFontsWithTraits(gfxFontEntry* aFontsForWeights[], PRUint32
|
||||||
|
|
||||||
// aPosTraitsMask == 0 ==> match all
|
// aPosTraitsMask == 0 ==> match all
|
||||||
if ((!aPosTraitsMask || (traits & aPosTraitsMask)) && !(traits & aNegTraitsMask)) {
|
if ((!aPosTraitsMask || (traits & aPosTraitsMask)) && !(traits & aNegTraitsMask)) {
|
||||||
PRInt32 weight = fe->Weight();
|
PRInt32 weight = fe->Weight() / 100;
|
||||||
|
NS_ASSERTION(weight >= 1 && weight <= 9, "bogus font weight value!");
|
||||||
|
|
||||||
// always prefer the first font for a given weight, helps deal a bit with
|
// always prefer the first font for a given weight, helps deal a bit with
|
||||||
// families with lots of faces (e.g. Minion Pro)
|
// families with lots of faces (e.g. Minion Pro)
|
||||||
|
@ -412,13 +463,14 @@ MacOSFamilyEntry::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gf
|
||||||
// short-circuit the single face per family case
|
// short-circuit the single face per family case
|
||||||
if (mAvailableFonts.Length() == 1) {
|
if (mAvailableFonts.Length() == 1) {
|
||||||
MacOSFontEntry *fe = mAvailableFonts[0];
|
MacOSFontEntry *fe = mAvailableFonts[0];
|
||||||
PRUint32 weight = fe->Weight();
|
PRUint32 weight = fe->Weight() / 100;
|
||||||
|
NS_ASSERTION(weight >= 1 && weight <= 9, "bogus font weight value!");
|
||||||
aFontsForWeights[weight] = fe;
|
aFontsForWeights[weight] = fe;
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool found = PR_FALSE;
|
PRBool found = PR_FALSE;
|
||||||
PRBool isItalic = (aFontStyle.style == FONT_STYLE_ITALIC || aFontStyle.style == FONT_STYLE_OBLIQUE);
|
PRBool isItalic = (aFontStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
|
||||||
|
|
||||||
// match italic faces
|
// match italic faces
|
||||||
if (isItalic) {
|
if (isItalic) {
|
||||||
|
@ -629,6 +681,8 @@ gfxQuartzFontCache *gfxQuartzFontCache::sSharedFontCache = nsnull;
|
||||||
gfxQuartzFontCache::gfxQuartzFontCache()
|
gfxQuartzFontCache::gfxQuartzFontCache()
|
||||||
: mStartIndex(0), mIncrement(kNumFontsPerSlice), mNumFamilies(0)
|
: mStartIndex(0), mIncrement(kNumFontsPerSlice), mNumFamilies(0)
|
||||||
{
|
{
|
||||||
|
mATSGeneration = PRUint32(kATSGenerationInitial);
|
||||||
|
|
||||||
mFontFamilies.Init(100);
|
mFontFamilies.Init(100);
|
||||||
mOtherFamilyNames.Init(30);
|
mOtherFamilyNames.Init(30);
|
||||||
mOtherFamilyNamesInitialized = PR_FALSE;
|
mOtherFamilyNamesInitialized = PR_FALSE;
|
||||||
|
@ -652,6 +706,15 @@ const PRUint32 kNonNormalTraits = NSItalicFontMask | NSBoldFontMask | NSNarrowFo
|
||||||
void
|
void
|
||||||
gfxQuartzFontCache::InitFontList()
|
gfxQuartzFontCache::InitFontList()
|
||||||
{
|
{
|
||||||
|
ATSGeneration currentGeneration = ATSGeneration();
|
||||||
|
|
||||||
|
// need to ignore notifications after adding each font
|
||||||
|
if (mATSGeneration == currentGeneration)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mATSGeneration = currentGeneration;
|
||||||
|
PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) updating to generation: %d", mATSGeneration));
|
||||||
|
|
||||||
mFontFamilies.Clear();
|
mFontFamilies.Clear();
|
||||||
mOtherFamilyNames.Clear();
|
mOtherFamilyNames.Clear();
|
||||||
mOtherFamilyNamesInitialized = PR_FALSE;
|
mOtherFamilyNamesInitialized = PR_FALSE;
|
||||||
|
@ -918,7 +981,7 @@ gfxQuartzFontCache::InitBadUnderlineList()
|
||||||
|
|
||||||
MacOSFamilyEntry *familyEntry = mFontFamilies.GetWeak(key, &found);
|
MacOSFamilyEntry *familyEntry = mFontFamilies.GetWeak(key, &found);
|
||||||
if (familyEntry)
|
if (familyEntry)
|
||||||
familyEntry->mIsBadUnderlineFontFamily = 1;
|
familyEntry->SetBadUnderlineFont(PR_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,6 +1268,158 @@ gfxQuartzFontCache::AddOtherFamilyName(MacOSFamilyEntry *aFamilyEntry, nsAString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxQuartzFontCache::LookupLocalFont(const nsAString& aFontName)
|
||||||
|
{
|
||||||
|
NSString *faceName = GetNSStringForString(aFontName);
|
||||||
|
NSFont *font = [NSFont fontWithName:faceName size:0.0];
|
||||||
|
|
||||||
|
if (font) {
|
||||||
|
nsAutoString availableFamilyName;
|
||||||
|
NSString *availableFamily = [font familyName];
|
||||||
|
GetStringForNSString(availableFamily, availableFamilyName);
|
||||||
|
|
||||||
|
MacOSFamilyEntry *familyEntry = FindFamily(availableFamilyName);
|
||||||
|
if (familyEntry) {
|
||||||
|
MacOSFontEntry *fontEntry = familyEntry->FindFont(aFontName);
|
||||||
|
return fontEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// didn't find the font
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// grumble, another non-publised Apple API dependency (found in Webkit code)
|
||||||
|
// activated with this value, font will not be found via system lookup routines
|
||||||
|
// it can only be used via the created ATSUFontID
|
||||||
|
// needed to prevent one doc from finding a font used in a separate doc
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kPrivateATSFontContextPrivate = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacOSUserFontData : public gfxUserFontData {
|
||||||
|
public:
|
||||||
|
MacOSUserFontData(ATSFontContainerRef aContainerRef, nsIFile *aFontFile,
|
||||||
|
nsISupports *aDownloader)
|
||||||
|
: mContainerRef(aContainerRef), mFontFile(aFontFile),
|
||||||
|
mDownloader(aDownloader)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~MacOSUserFontData()
|
||||||
|
{
|
||||||
|
// deactivate font
|
||||||
|
if (mContainerRef)
|
||||||
|
ATSFontDeactivate(mContainerRef, NULL, kATSOptionFlagsDefault);
|
||||||
|
|
||||||
|
if (mFontFile) {
|
||||||
|
mFontFile->Remove(PR_FALSE); // ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATSFontContainerRef mContainerRef;
|
||||||
|
nsCOMPtr<nsIFile> mFontFile;
|
||||||
|
|
||||||
|
// maintaining a ref to this keeps temp file around or cache file pinned
|
||||||
|
nsCOMPtr<nsISupports> mDownloader;
|
||||||
|
};
|
||||||
|
|
||||||
|
static OSStatus
|
||||||
|
MakeFSSpec(FSSpec *aFSSpec, NSString *path)
|
||||||
|
{
|
||||||
|
FSRef fsref;
|
||||||
|
OSStatus err = FSPathMakeRef((UInt8*)([path fileSystemRepresentation]), &fsref, NULL);
|
||||||
|
|
||||||
|
if (err == noErr)
|
||||||
|
err = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, aFSSpec, NULL);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxQuartzFontCache::MakePlatformFont(const gfxFontEntry *aProxyEntry,
|
||||||
|
const gfxDownloadedFontData* aFontData)
|
||||||
|
{
|
||||||
|
OSStatus err;
|
||||||
|
FSSpec spec;
|
||||||
|
nsAutoString filePath;
|
||||||
|
|
||||||
|
NS_ASSERTION(aFontData && aFontData->mFontFile,
|
||||||
|
"MakePlatformFont called with null file ptr");
|
||||||
|
|
||||||
|
if (!aFontData->mFontFile)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
aFontData->mFontFile->GetPath(filePath);
|
||||||
|
|
||||||
|
NSString *path = GetNSStringForString(filePath);
|
||||||
|
if (!path)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// assumption: filename is already in the form xxx.ttf, otherwise
|
||||||
|
// ATS will reject
|
||||||
|
|
||||||
|
err = MakeFSSpec(&spec, path);
|
||||||
|
if (err != noErr)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
ATSUFontID fontID;
|
||||||
|
ATSFontContainerRef containerRef;
|
||||||
|
|
||||||
|
err = ATSFontActivateFromFileSpecification(&spec,
|
||||||
|
kPrivateATSFontContextPrivate,
|
||||||
|
kATSFontFormatUnspecified,
|
||||||
|
NULL,
|
||||||
|
kATSOptionFlagsDoNotNotify,
|
||||||
|
&containerRef);
|
||||||
|
if (err != noErr)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
mATSGeneration = ATSGeneration();
|
||||||
|
|
||||||
|
// ignoring containers with multiple fonts, use the first face only for now
|
||||||
|
err = ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1,
|
||||||
|
(ATSFontRef*)&fontID, NULL);
|
||||||
|
if (err != noErr)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// font entry will own this
|
||||||
|
MacOSUserFontData *userFontData = new MacOSUserFontData(containerRef,
|
||||||
|
aFontData->mFontFile,
|
||||||
|
aFontData->mDownloader);
|
||||||
|
if (!userFontData)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
PRUint16 w = aProxyEntry->mWeight;
|
||||||
|
NS_ASSERTION(w >= 100 && w <= 900, "bogus font weight value!");
|
||||||
|
|
||||||
|
MacOSFontEntry *newFontEntry =
|
||||||
|
new MacOSFontEntry(fontID, w, aProxyEntry->mStretch,
|
||||||
|
(PRUint32(aProxyEntry->mItalic) ?
|
||||||
|
FONT_STYLE_ITALIC :
|
||||||
|
FONT_STYLE_NORMAL),
|
||||||
|
userFontData);
|
||||||
|
|
||||||
|
// if something is funky about this font, delete immediately
|
||||||
|
if (newFontEntry && !newFontEntry->mIsValid) {
|
||||||
|
#if DEBUG
|
||||||
|
char warnBuf[1024];
|
||||||
|
const gfxProxyFontEntry *proxyEntry =
|
||||||
|
static_cast<const gfxProxyFontEntry*> (aProxyEntry);
|
||||||
|
sprintf(warnBuf, "downloaded font not loaded properly, removed (%s) for (%s)",
|
||||||
|
[path UTF8String],
|
||||||
|
NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get());
|
||||||
|
NS_WARNING(warnBuf);
|
||||||
|
#endif
|
||||||
|
delete newFontEntry;
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newFontEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxQuartzFontCache::InitLoader()
|
gfxQuartzFontCache::InitLoader()
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,6 +113,7 @@ protected:
|
||||||
PRUint32 mLength;
|
PRUint32 mLength;
|
||||||
PRUint32 mAppUnitsPerDevUnit;
|
PRUint32 mAppUnitsPerDevUnit;
|
||||||
PRUint32 mStringHash;
|
PRUint32 mStringHash;
|
||||||
|
PRUint64 mUserFontSetGeneration;
|
||||||
PRPackedBool mIsDoubleByteText;
|
PRPackedBool mIsDoubleByteText;
|
||||||
PRPackedBool mIsRTL;
|
PRPackedBool mIsRTL;
|
||||||
PRPackedBool mEnabledOptionalLigatures;
|
PRPackedBool mEnabledOptionalLigatures;
|
||||||
|
@ -124,6 +125,7 @@ protected:
|
||||||
mLength(aLength),
|
mLength(aLength),
|
||||||
mAppUnitsPerDevUnit(aBaseTextRun->GetAppUnitsPerDevUnit()),
|
mAppUnitsPerDevUnit(aBaseTextRun->GetAppUnitsPerDevUnit()),
|
||||||
mStringHash(aHash),
|
mStringHash(aHash),
|
||||||
|
mUserFontSetGeneration(aBaseTextRun->GetUserFontSetGeneration()),
|
||||||
mIsDoubleByteText((aBaseTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) == 0),
|
mIsDoubleByteText((aBaseTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) == 0),
|
||||||
mIsRTL(aBaseTextRun->IsRightToLeft()),
|
mIsRTL(aBaseTextRun->IsRightToLeft()),
|
||||||
mEnabledOptionalLigatures((aBaseTextRun->GetFlags() & gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES) == 0),
|
mEnabledOptionalLigatures((aBaseTextRun->GetFlags() & gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES) == 0),
|
||||||
|
@ -197,14 +199,17 @@ HashMix(PRUint32 aHash, PRUnichar aCh)
|
||||||
|
|
||||||
// If the substring of the textrun is rendered entirely in the first font
|
// If the substring of the textrun is rendered entirely in the first font
|
||||||
// of the textrun's fontgroup, then return that font. Otherwise return the
|
// of the textrun's fontgroup, then return that font. Otherwise return the
|
||||||
// fontgroup.
|
// fontgroup. When a user font set is in use, always return the font group.
|
||||||
static void *GetWordFontOrGroup(gfxTextRun *aTextRun, PRUint32 aOffset,
|
static void *GetWordFontOrGroup(gfxTextRun *aTextRun, PRUint32 aOffset,
|
||||||
PRUint32 aLength)
|
PRUint32 aLength)
|
||||||
{
|
{
|
||||||
|
gfxFontGroup *fontGroup = aTextRun->GetFontGroup();
|
||||||
|
if (fontGroup->GetUserFontSet() != nsnull)
|
||||||
|
return fontGroup;
|
||||||
|
|
||||||
PRUint32 glyphRunCount;
|
PRUint32 glyphRunCount;
|
||||||
const gfxTextRun::GlyphRun *glyphRuns = aTextRun->GetGlyphRuns(&glyphRunCount);
|
const gfxTextRun::GlyphRun *glyphRuns = aTextRun->GetGlyphRuns(&glyphRunCount);
|
||||||
PRUint32 glyphRunIndex = aTextRun->FindFirstGlyphRunContaining(aOffset);
|
PRUint32 glyphRunIndex = aTextRun->FindFirstGlyphRunContaining(aOffset);
|
||||||
gfxFontGroup *fontGroup = aTextRun->GetFontGroup();
|
|
||||||
gfxFont *firstFont = fontGroup->GetFontAt(0);
|
gfxFont *firstFont = fontGroup->GetFontAt(0);
|
||||||
if (glyphRuns[glyphRunIndex].mFont != firstFont)
|
if (glyphRuns[glyphRunIndex].mFont != firstFont)
|
||||||
return fontGroup;
|
return fontGroup;
|
||||||
|
@ -260,8 +265,11 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont,
|
||||||
{
|
{
|
||||||
if (aEnd <= aStart)
|
if (aEnd <= aStart)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
|
||||||
|
gfxFontGroup *fontGroup = aTextRun->GetFontGroup();
|
||||||
|
|
||||||
CacheHashKey key(aTextRun, aFirstFont, aStart, aEnd - aStart, aHash);
|
PRBool useFontGroup = (fontGroup->GetUserFontSet() != nsnull);
|
||||||
|
CacheHashKey key(aTextRun, (useFontGroup ? (void*)fontGroup : (void*)aFirstFont), aStart, aEnd - aStart, aHash);
|
||||||
CacheHashEntry *fontEntry = mCache.PutEntry(key);
|
CacheHashEntry *fontEntry = mCache.PutEntry(key);
|
||||||
if (!fontEntry)
|
if (!fontEntry)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
@ -269,7 +277,10 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont,
|
||||||
|
|
||||||
if (fontEntry->mTextRun) {
|
if (fontEntry->mTextRun) {
|
||||||
existingEntry = fontEntry;
|
existingEntry = fontEntry;
|
||||||
|
} else if (useFontGroup) {
|
||||||
|
PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): added using font group", aTextRun, aStart, aEnd - aStart, aHash));
|
||||||
} else {
|
} else {
|
||||||
|
// test to see if this can be found using the font group instead
|
||||||
PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): added using font", aTextRun, aStart, aEnd - aStart, aHash));
|
PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): added using font", aTextRun, aStart, aEnd - aStart, aHash));
|
||||||
key.mFontOrGroup = aTextRun->GetFontGroup();
|
key.mFontOrGroup = aTextRun->GetFontGroup();
|
||||||
CacheHashEntry *groupEntry = mCache.GetEntry(key);
|
CacheHashEntry *groupEntry = mCache.GetEntry(key);
|
||||||
|
@ -304,7 +315,8 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont,
|
||||||
// entry, we'll copy within our own textrun
|
// entry, we'll copy within our own textrun
|
||||||
fontEntry->mTextRun = aTextRun;
|
fontEntry->mTextRun = aTextRun;
|
||||||
fontEntry->mWordOffset = aStart;
|
fontEntry->mWordOffset = aStart;
|
||||||
fontEntry->mHashedByFont = PR_TRUE;
|
if (!useFontGroup)
|
||||||
|
fontEntry->mHashedByFont = PR_TRUE;
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +343,11 @@ TextRunWordCache::FinishTextRun(gfxTextRun *aTextRun, gfxTextRun *aNewRun,
|
||||||
PRUint32 i;
|
PRUint32 i;
|
||||||
gfxFontGroup *fontGroup = aTextRun->GetFontGroup();
|
gfxFontGroup *fontGroup = aTextRun->GetFontGroup();
|
||||||
gfxFont *font = fontGroup->GetFontAt(0);
|
gfxFont *font = fontGroup->GetFontAt(0);
|
||||||
|
|
||||||
|
// need to use the font group when user font set is around, since
|
||||||
|
// the first font may change as the result of a font download
|
||||||
|
PRBool useFontGroup = (fontGroup->GetUserFontSet() != nsnull);
|
||||||
|
|
||||||
// copy deferred words from various sources into destination textrun
|
// copy deferred words from various sources into destination textrun
|
||||||
for (i = 0; i < aDeferredWords.Length(); ++i) {
|
for (i = 0; i < aDeferredWords.Length(); ++i) {
|
||||||
const DeferredWord *word = &aDeferredWords[i];
|
const DeferredWord *word = &aDeferredWords[i];
|
||||||
|
@ -350,11 +367,11 @@ TextRunWordCache::FinishTextRun(gfxTextRun *aTextRun, gfxTextRun *aNewRun,
|
||||||
// we need to remove that cache entry and replace it with an entry
|
// we need to remove that cache entry and replace it with an entry
|
||||||
// keyed off the fontgroup.
|
// keyed off the fontgroup.
|
||||||
PRBool rekeyWithFontGroup =
|
PRBool rekeyWithFontGroup =
|
||||||
GetWordFontOrGroup(aNewRun, word->mSourceOffset, word->mLength) != font;
|
GetWordFontOrGroup(aNewRun, word->mSourceOffset, word->mLength) != font && !useFontGroup;
|
||||||
if (!aSuccessful || rekeyWithFontGroup ||
|
if (!aSuccessful || rekeyWithFontGroup ||
|
||||||
wordStartsInsideCluster || wordStartsInsideLigature) {
|
wordStartsInsideCluster || wordStartsInsideLigature) {
|
||||||
// We need to remove the current placeholder cache entry
|
// We need to remove the current placeholder cache entry
|
||||||
CacheHashKey key(aTextRun, font, word->mDestOffset, word->mLength,
|
CacheHashKey key(aTextRun, (useFontGroup ? (void*)fontGroup : (void*)font), word->mDestOffset, word->mLength,
|
||||||
word->mHash);
|
word->mHash);
|
||||||
NS_ASSERTION(mCache.GetEntry(key),
|
NS_ASSERTION(mCache.GetEntry(key),
|
||||||
"This entry should have been added previously!");
|
"This entry should have been added previously!");
|
||||||
|
@ -459,6 +476,9 @@ TextRunWordCache::MakeTextRun(const PRUnichar *aText, PRUint32 aLength,
|
||||||
const gfxFontGroup::Parameters *aParams,
|
const gfxFontGroup::Parameters *aParams,
|
||||||
PRUint32 aFlags)
|
PRUint32 aFlags)
|
||||||
{
|
{
|
||||||
|
// update font list when using user fonts (assures generation is current)
|
||||||
|
aFontGroup->UpdateFontList();
|
||||||
|
|
||||||
if (aFontGroup->GetStyle()->size == 0) {
|
if (aFontGroup->GetStyle()->size == 0) {
|
||||||
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
||||||
// them, and always create at least size 1 fonts, i.e. they still
|
// them, and always create at least size 1 fonts, i.e. they still
|
||||||
|
@ -530,7 +550,7 @@ TextRunWordCache::MakeTextRun(const PRUnichar *aText, PRUint32 aLength,
|
||||||
nsAutoPtr<gfxTextRun> newRun;
|
nsAutoPtr<gfxTextRun> newRun;
|
||||||
newRun = aFontGroup->MakeTextRun(tempString.Elements(), tempString.Length(),
|
newRun = aFontGroup->MakeTextRun(tempString.Elements(), tempString.Length(),
|
||||||
¶ms, aFlags | gfxTextRunFactory::TEXT_IS_PERSISTENT);
|
¶ms, aFlags | gfxTextRunFactory::TEXT_IS_PERSISTENT);
|
||||||
|
|
||||||
FinishTextRun(textRun, newRun, aParams, deferredWords, newRun != nsnull);
|
FinishTextRun(textRun, newRun, aParams, deferredWords, newRun != nsnull);
|
||||||
return textRun.forget();
|
return textRun.forget();
|
||||||
}
|
}
|
||||||
|
@ -541,6 +561,9 @@ TextRunWordCache::MakeTextRun(const PRUint8 *aText, PRUint32 aLength,
|
||||||
const gfxFontGroup::Parameters *aParams,
|
const gfxFontGroup::Parameters *aParams,
|
||||||
PRUint32 aFlags)
|
PRUint32 aFlags)
|
||||||
{
|
{
|
||||||
|
// update font list when using user fonts (assures generation is current)
|
||||||
|
aFontGroup->UpdateFontList();
|
||||||
|
|
||||||
if (aFontGroup->GetStyle()->size == 0) {
|
if (aFontGroup->GetStyle()->size == 0) {
|
||||||
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
|
||||||
// them, and always create at least size 1 fonts, i.e. they still
|
// them, and always create at least size 1 fonts, i.e. they still
|
||||||
|
@ -628,6 +651,7 @@ TextRunWordCache::RemoveWord(gfxTextRun *aTextRun, PRUint32 aStart,
|
||||||
PRUint32 length = aEnd - aStart;
|
PRUint32 length = aEnd - aStart;
|
||||||
CacheHashKey key(aTextRun, GetWordFontOrGroup(aTextRun, aStart, length),
|
CacheHashKey key(aTextRun, GetWordFontOrGroup(aTextRun, aStart, length),
|
||||||
aStart, length, aHash);
|
aStart, length, aHash);
|
||||||
|
|
||||||
CacheHashEntry *entry = mCache.GetEntry(key);
|
CacheHashEntry *entry = mCache.GetEntry(key);
|
||||||
if (entry && entry->mTextRun == aTextRun) {
|
if (entry && entry->mTextRun == aTextRun) {
|
||||||
// XXX would like to use RawRemoveEntry here plus some extra method
|
// XXX would like to use RawRemoveEntry here plus some extra method
|
||||||
|
@ -710,7 +734,8 @@ TextRunWordCache::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const
|
||||||
aKey->mAppUnitsPerDevUnit != mTextRun->GetAppUnitsPerDevUnit() ||
|
aKey->mAppUnitsPerDevUnit != mTextRun->GetAppUnitsPerDevUnit() ||
|
||||||
aKey->mIsRTL != mTextRun->IsRightToLeft() ||
|
aKey->mIsRTL != mTextRun->IsRightToLeft() ||
|
||||||
aKey->mEnabledOptionalLigatures != ((mTextRun->GetFlags() & gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES) == 0) ||
|
aKey->mEnabledOptionalLigatures != ((mTextRun->GetFlags() & gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES) == 0) ||
|
||||||
aKey->mOptimizeSpeed != ((mTextRun->GetFlags() & gfxTextRunFactory::TEXT_OPTIMIZE_SPEED) != 0))
|
aKey->mOptimizeSpeed != ((mTextRun->GetFlags() & gfxTextRunFactory::TEXT_OPTIMIZE_SPEED) != 0) ||
|
||||||
|
aKey->mUserFontSetGeneration != (mTextRun->GetUserFontSetGeneration()))
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
if (mTextRun->GetFlags() & gfxFontGroup::TEXT_IS_8BIT) {
|
if (mTextRun->GetFlags() & gfxFontGroup::TEXT_IS_8BIT) {
|
||||||
|
@ -731,7 +756,12 @@ TextRunWordCache::CacheHashEntry::KeyEquals(const KeyTypePointer aKey) const
|
||||||
PLDHashNumber
|
PLDHashNumber
|
||||||
TextRunWordCache::CacheHashEntry::HashKey(const KeyTypePointer aKey)
|
TextRunWordCache::CacheHashEntry::HashKey(const KeyTypePointer aKey)
|
||||||
{
|
{
|
||||||
return aKey->mStringHash + (long)aKey->mFontOrGroup + aKey->mAppUnitsPerDevUnit +
|
// only use lower 32 bits of generation counter in hash key,
|
||||||
|
// since these vary the most
|
||||||
|
PRUint32 fontSetGen;
|
||||||
|
LL_L2UI(fontSetGen, aKey->mUserFontSetGeneration);
|
||||||
|
|
||||||
|
return aKey->mStringHash + fontSetGen + (long)aKey->mFontOrGroup + aKey->mAppUnitsPerDevUnit +
|
||||||
aKey->mIsDoubleByteText + aKey->mIsRTL*2 + aKey->mEnabledOptionalLigatures*4 +
|
aKey->mIsDoubleByteText + aKey->mIsRTL*2 + aKey->mEnabledOptionalLigatures*4 +
|
||||||
aKey->mOptimizeSpeed*8;
|
aKey->mOptimizeSpeed*8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,21 +192,8 @@ FontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
|
||||||
// Some fonts claim to support things > 900, but we don't so clamp the sizes
|
// Some fonts claim to support things > 900, but we don't so clamp the sizes
|
||||||
logFont.lfWeight = PR_MAX(PR_MIN(logFont.lfWeight, 900), 100);
|
logFont.lfWeight = PR_MAX(PR_MIN(logFont.lfWeight, 900), 100);
|
||||||
|
|
||||||
gfxWindowsFontType feType;
|
|
||||||
if (metrics.ntmFlags & NTM_TYPE1)
|
gfxWindowsFontType feType = FontEntry::DetermineFontType(metrics, fontType);
|
||||||
feType = GFX_FONT_TYPE_TYPE1;
|
|
||||||
else if (metrics.ntmFlags & (NTM_PS_OPENTYPE))
|
|
||||||
feType = GFX_FONT_TYPE_PS_OPENTYPE;
|
|
||||||
else if (metrics.ntmFlags & (NTM_TT_OPENTYPE))
|
|
||||||
feType = GFX_FONT_TYPE_TT_OPENTYPE;
|
|
||||||
else if (fontType == TRUETYPE_FONTTYPE)
|
|
||||||
feType = GFX_FONT_TYPE_TRUETYPE;
|
|
||||||
else if (fontType == RASTER_FONTTYPE)
|
|
||||||
feType = GFX_FONT_TYPE_RASTER;
|
|
||||||
else if (fontType == DEVICE_FONTTYPE)
|
|
||||||
feType = GFX_FONT_TYPE_DEVICE;
|
|
||||||
else
|
|
||||||
feType = GFX_FONT_TYPE_UNKNOWN;
|
|
||||||
|
|
||||||
FontEntry *fe = nsnull;
|
FontEntry *fe = nsnull;
|
||||||
for (PRUint32 i = 0; i < ff->mVariations.Length(); ++i) {
|
for (PRUint32 i = 0; i < ff->mVariations.Length(); ++i) {
|
||||||
|
@ -232,15 +219,14 @@ FontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fe = new FontEntry(ff->mName);
|
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||||
|
logFont.lfOutPrecision = FontTypeToOutPrecision(feType);
|
||||||
|
fe = FontEntry::CreateFontEntry(ff->mName, feType, (logFont.lfItalic == 0xFF), (PRUint16) (logFont.lfWeight), nsnull, hdc, &logFont);
|
||||||
|
|
||||||
|
if (!fe)
|
||||||
|
return 1;
|
||||||
|
|
||||||
ff->mVariations.AppendElement(fe);
|
ff->mVariations.AppendElement(fe);
|
||||||
fe->mFontType = feType;
|
|
||||||
|
|
||||||
fe->mItalic = (logFont.lfItalic == 0xFF);
|
|
||||||
fe->mWeight = logFont.lfWeight;
|
|
||||||
|
|
||||||
if (fe->IsType1())
|
|
||||||
fe->mForceGDI = PR_TRUE;
|
|
||||||
|
|
||||||
// mark the charset bit
|
// mark the charset bit
|
||||||
fe->mCharset[metrics.tmCharSet] = 1;
|
fe->mCharset[metrics.tmCharSet] = 1;
|
||||||
|
@ -263,39 +249,7 @@ FontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fe->mIsBadUnderlineFont = ff->mIsBadUnderlineFont;
|
fe->mIsBadUnderlineFont = ff->mIsBadUnderlineFontFamily;
|
||||||
|
|
||||||
// read in the character map
|
|
||||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
|
||||||
logFont.lfOutPrecision = FontTypeToOutPrecision(fe->mFontType);
|
|
||||||
|
|
||||||
HFONT font = CreateFontIndirectW(&logFont);
|
|
||||||
|
|
||||||
NS_ASSERTION(font, "This font creation should never ever ever fail");
|
|
||||||
if (font) {
|
|
||||||
HFONT oldFont = (HFONT)SelectObject(hdc, font);
|
|
||||||
|
|
||||||
// ReadCMAP may change the values of mUnicodeFont and mSymbolFont
|
|
||||||
if (NS_FAILED(ReadCMAP(hdc, fe))) {
|
|
||||||
// Type1 fonts aren't necessarily Unicode but
|
|
||||||
// this is the best guess we can make here
|
|
||||||
if (fe->IsType1())
|
|
||||||
fe->mUnicodeFont = PR_TRUE;
|
|
||||||
else
|
|
||||||
fe->mUnicodeFont = PR_FALSE;
|
|
||||||
|
|
||||||
// For fonts where we failed to read the character map,
|
|
||||||
// we can take a slow path to look up glyphs character by character
|
|
||||||
fe->mUnknownCMAP = PR_TRUE;
|
|
||||||
|
|
||||||
//printf("(fontinit-cmap) %s failed to get cmap, type1:%d \n", NS_ConvertUTF16toUTF8(fe->mFaceName).get(), (PRUint32)(fe->mIsType1));
|
|
||||||
} else {
|
|
||||||
//printf("(fontinit-cmap) %s cmap loaded, italic:%d, weight:%d\n", NS_ConvertUTF16toUTF8(fe->mFaceName).get(), (PRUint32)(fe->mItalic), (PRUint32)(fe->mWeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectObject(hdc, oldFont);
|
|
||||||
DeleteObject(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -393,6 +347,102 @@ FontFamily::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gfxFontS
|
||||||
return matchesSomething;
|
return matchesSomething;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FontEntry*
|
||||||
|
FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc, LOGFONTW *aLogFont)
|
||||||
|
{
|
||||||
|
LOGFONTW logFont;
|
||||||
|
PRBool needRelease = PR_FALSE;
|
||||||
|
|
||||||
|
// jtdfix - need to set charset, unicode ranges, pitch/family
|
||||||
|
|
||||||
|
FontEntry *fe;
|
||||||
|
|
||||||
|
fe = new FontEntry(aName);
|
||||||
|
fe->mFontType = aFontType;
|
||||||
|
fe->mUserFontData = aUserFontData;
|
||||||
|
|
||||||
|
fe->mItalic = aItalic;
|
||||||
|
fe->mWeight = aWeight;
|
||||||
|
|
||||||
|
if (fe->IsType1())
|
||||||
|
fe->mForceGDI = PR_TRUE;
|
||||||
|
|
||||||
|
if (!aLogFont) {
|
||||||
|
aLogFont = &logFont;
|
||||||
|
FontEntry::FillLogFont(aLogFont, fe, 0, aItalic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hdc) {
|
||||||
|
hdc = GetDC(nsnull);
|
||||||
|
SetGraphicsMode(hdc, GM_ADVANCED);
|
||||||
|
needRelease = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HFONT font = CreateFontIndirectW(aLogFont);
|
||||||
|
|
||||||
|
if (font) {
|
||||||
|
HFONT oldFont = (HFONT)SelectObject(hdc, font);
|
||||||
|
|
||||||
|
// ReadCMAP may change the values of mUnicodeFont and mSymbolFont
|
||||||
|
if (NS_FAILED(::ReadCMAP(hdc, fe))) {
|
||||||
|
// Type1 fonts aren't necessarily Unicode but
|
||||||
|
// this is the best guess we can make here
|
||||||
|
if (fe->IsType1())
|
||||||
|
fe->mUnicodeFont = PR_TRUE;
|
||||||
|
else
|
||||||
|
fe->mUnicodeFont = PR_FALSE;
|
||||||
|
|
||||||
|
// For fonts where we failed to read the character map,
|
||||||
|
// we can take a slow path to look up glyphs character by character
|
||||||
|
fe->mUnknownCMAP = PR_TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectObject(hdc, oldFont);
|
||||||
|
DeleteObject(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needRelease)
|
||||||
|
ReleaseDC(nsnull, hdc);
|
||||||
|
|
||||||
|
return fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FontEntry::FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize, PRBool aItalic)
|
||||||
|
{
|
||||||
|
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
||||||
|
|
||||||
|
aLogFont->lfHeight = (LONG)-ROUND(aSize);
|
||||||
|
|
||||||
|
if (aLogFont->lfHeight == 0)
|
||||||
|
aLogFont->lfHeight = -1;
|
||||||
|
|
||||||
|
// Fill in logFont structure
|
||||||
|
aLogFont->lfWidth = 0;
|
||||||
|
aLogFont->lfEscapement = 0;
|
||||||
|
aLogFont->lfOrientation = 0;
|
||||||
|
aLogFont->lfUnderline = FALSE;
|
||||||
|
aLogFont->lfStrikeOut = FALSE;
|
||||||
|
aLogFont->lfCharSet = DEFAULT_CHARSET;
|
||||||
|
aLogFont->lfOutPrecision = FontTypeToOutPrecision(aFontEntry->mFontType);
|
||||||
|
aLogFont->lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
|
||||||
|
aLogFont->lfQuality = DEFAULT_QUALITY;
|
||||||
|
aLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||||
|
// always force lfItalic if we want it. Font selection code will
|
||||||
|
// do its best to give us an italic font entry, but if no face exists
|
||||||
|
// it may give us a regular one based on weight. Windows should
|
||||||
|
// do fake italic for us in that case.
|
||||||
|
aLogFont->lfItalic = aItalic;
|
||||||
|
aLogFont->lfWeight = aFontEntry->mWeight;
|
||||||
|
|
||||||
|
int len = PR_MIN(aFontEntry->Name().Length(), LF_FACESIZE - 1);
|
||||||
|
memcpy(aLogFont->lfFaceName, nsPromiseFlatString(aFontEntry->Name()).get(), len * 2);
|
||||||
|
aLogFont->lfFaceName[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
FontEntry::TestCharacterMap(PRUint32 aCh)
|
FontEntry::TestCharacterMap(PRUint32 aCh)
|
||||||
{
|
{
|
||||||
|
@ -664,40 +714,13 @@ gfxWindowsFont::ComputeMetrics()
|
||||||
|
|
||||||
ReleaseDC((HWND)nsnull, dc);
|
ReleaseDC((HWND)nsnull, dc);
|
||||||
|
|
||||||
SanitizeMetrics(mMetrics, GetFontEntry()->IsBadUnderlineFont());
|
SanitizeMetrics(mMetrics, GetFontEntry()->mIsBadUnderlineFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxWindowsFont::FillLogFont(gfxFloat aSize)
|
gfxWindowsFont::FillLogFont(gfxFloat aSize)
|
||||||
{
|
{
|
||||||
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
FontEntry::FillLogFont(&mLogFont, GetFontEntry(), aSize, (GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
|
||||||
|
|
||||||
mLogFont.lfHeight = (LONG)-ROUND(aSize);
|
|
||||||
|
|
||||||
if (mLogFont.lfHeight == 0)
|
|
||||||
mLogFont.lfHeight = -1;
|
|
||||||
|
|
||||||
// Fill in logFont structure
|
|
||||||
mLogFont.lfWidth = 0;
|
|
||||||
mLogFont.lfEscapement = 0;
|
|
||||||
mLogFont.lfOrientation = 0;
|
|
||||||
mLogFont.lfUnderline = FALSE;
|
|
||||||
mLogFont.lfStrikeOut = FALSE;
|
|
||||||
mLogFont.lfCharSet = DEFAULT_CHARSET;
|
|
||||||
mLogFont.lfOutPrecision = FontTypeToOutPrecision(GetFontEntry()->mFontType);
|
|
||||||
mLogFont.lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
|
|
||||||
mLogFont.lfQuality = DEFAULT_QUALITY;
|
|
||||||
mLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
|
||||||
// always force lfItalic if we want it. Font selection code will
|
|
||||||
// do its best to give us an italic font entry, but if no face exists
|
|
||||||
// it may give us a regular one based on weight. Windows should
|
|
||||||
// do fake italic for us in that case.
|
|
||||||
mLogFont.lfItalic = (GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? TRUE : FALSE;
|
|
||||||
mLogFont.lfWeight = GetFontEntry()->mWeight;
|
|
||||||
|
|
||||||
int len = PR_MIN(GetName().Length(), LF_FACESIZE - 1);
|
|
||||||
memcpy(mLogFont.lfFaceName, nsPromiseFlatString(mFontEntry->Name()).get(), len * 2);
|
|
||||||
mLogFont.lfFaceName[len] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -806,6 +829,7 @@ AddFontNameToArray(const nsAString& aName,
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list)
|
gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *list)
|
||||||
{
|
{
|
||||||
|
@ -814,8 +838,25 @@ gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray<nsRefPtr<FontEntry> > *
|
||||||
|
|
||||||
PRUint32 len = fonts.Length();
|
PRUint32 len = fonts.Length();
|
||||||
for (PRUint32 i = 0; i < len; ++i) {
|
for (PRUint32 i = 0; i < len; ++i) {
|
||||||
nsRefPtr<FontEntry> fe = gfxWindowsPlatform::GetPlatform()->FindFontEntry(fonts[i], mStyle);
|
nsRefPtr<FontEntry> fe;
|
||||||
list->AppendElement(fe);
|
|
||||||
|
// first, look up in the user font set
|
||||||
|
gfxFontEntry *gfe;
|
||||||
|
PRBool needsBold;
|
||||||
|
if (mUserFontSet && (gfe = mUserFontSet->FindFontEntry(fonts[i], mStyle, needsBold))) {
|
||||||
|
// assume for now platform font if not SVG
|
||||||
|
fe = static_cast<FontEntry*> (gfe);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing in the user font set ==> check system fonts
|
||||||
|
if (!fe) {
|
||||||
|
fe = gfxWindowsPlatform::GetPlatform()->FindFontEntry(fonts[i], mStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if found, add to the list
|
||||||
|
if (fe) {
|
||||||
|
list->AppendElement(fe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,8 +876,50 @@ gfxWindowsFontGroup::FamilyListToArrayList(const nsString& aFamilies,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle)
|
gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet *aUserFontSet)
|
||||||
: gfxFontGroup(aFamilies, aStyle)
|
: gfxFontGroup(aFamilies, aStyle, aUserFontSet)
|
||||||
|
{
|
||||||
|
InitFontList();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxWindowsFontGroup::~gfxWindowsFontGroup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxWindowsFont *
|
||||||
|
gfxWindowsFontGroup::GetFontAt(PRInt32 i)
|
||||||
|
{
|
||||||
|
if (!mFonts[i]) {
|
||||||
|
nsRefPtr<gfxWindowsFont> font =
|
||||||
|
gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle);
|
||||||
|
mFonts[i] = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<gfxWindowsFont*>(mFonts[i].get());
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontGroup *
|
||||||
|
gfxWindowsFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||||
|
{
|
||||||
|
return new gfxWindowsFontGroup(mFamilies, aStyle, mUserFontSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gfxWindowsFontGroup::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();
|
||||||
|
mFontEntries.Clear();
|
||||||
|
InitFontList();
|
||||||
|
mCurrGeneration = GetGeneration();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gfxWindowsFontGroup::InitFontList()
|
||||||
{
|
{
|
||||||
GroupFamilyListToArrayList(&mFontEntries);
|
GroupFamilyListToArrayList(&mFontEntries);
|
||||||
|
|
||||||
|
@ -892,7 +975,7 @@ gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFo
|
||||||
|
|
||||||
if (!mStyle.systemFont) {
|
if (!mStyle.systemFont) {
|
||||||
for (PRUint32 i = 0; i < mFontEntries.Length(); ++i) {
|
for (PRUint32 i = 0; i < mFontEntries.Length(); ++i) {
|
||||||
if (mFontEntries[i]->IsBadUnderlineFont()) {
|
if (mFontEntries[i]->mIsBadUnderlineFont) {
|
||||||
gfxFloat first = GetFontAt(0)->GetMetrics().underlineOffset;
|
gfxFloat first = GetFontAt(0)->GetMetrics().underlineOffset;
|
||||||
gfxFloat bad = GetFontAt(i)->GetMetrics().underlineOffset;
|
gfxFloat bad = GetFontAt(i)->GetMetrics().underlineOffset;
|
||||||
mUnderlineOffset = PR_MIN(first, bad);
|
mUnderlineOffset = PR_MIN(first, bad);
|
||||||
|
@ -900,28 +983,7 @@ gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gfxWindowsFontGroup::~gfxWindowsFontGroup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
gfxWindowsFont *
|
|
||||||
gfxWindowsFontGroup::GetFontAt(PRInt32 i)
|
|
||||||
{
|
|
||||||
if (!mFonts[i]) {
|
|
||||||
nsRefPtr<gfxWindowsFont> font =
|
|
||||||
gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle);
|
|
||||||
mFonts[i] = font;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<gfxWindowsFont*>(mFonts[i].get());
|
|
||||||
}
|
|
||||||
|
|
||||||
gfxFontGroup *
|
|
||||||
gfxWindowsFontGroup::Copy(const gfxFontStyle *aStyle)
|
|
||||||
{
|
|
||||||
return new gfxWindowsFontGroup(mFamilies, aStyle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
|
|
|
@ -49,14 +49,18 @@
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
#include "nsIWindowsRegKey.h"
|
#include "nsIWindowsRegKey.h"
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
#include "plbase64.h"
|
||||||
|
|
||||||
#include "gfxWindowsFonts.h"
|
#include "gfxWindowsFonts.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "lcms.h"
|
#include "lcms.h"
|
||||||
|
|
||||||
//#define DEBUG_CMAP_SIZE 1
|
static void InitializeFontEmbeddingProcs();
|
||||||
|
|
||||||
// font info loader constants
|
// font info loader constants
|
||||||
static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
|
static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
|
||||||
|
@ -96,6 +100,8 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
||||||
pref->RegisterCallback("font.name-list.", PrefChangedCallback, this);
|
pref->RegisterCallback("font.name-list.", PrefChangedCallback, this);
|
||||||
pref->RegisterCallback("intl.accept_languages", PrefChangedCallback, this);
|
pref->RegisterCallback("intl.accept_languages", PrefChangedCallback, this);
|
||||||
// don't bother unregistering. We'll get shutdown after the pref service
|
// don't bother unregistering. We'll get shutdown after the pref service
|
||||||
|
|
||||||
|
InitializeFontEmbeddingProcs();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxWindowsPlatform::~gfxWindowsPlatform()
|
gfxWindowsPlatform::~gfxWindowsPlatform()
|
||||||
|
@ -319,7 +325,7 @@ gfxWindowsPlatform::InitBadUnderlineList()
|
||||||
FontFamily *ff = FindFontFamily(resolved);
|
FontFamily *ff = FindFontFamily(resolved);
|
||||||
if (!ff)
|
if (!ff)
|
||||||
continue;
|
continue;
|
||||||
ff->mIsBadUnderlineFont = 1;
|
ff->mIsBadUnderlineFontFamily = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,9 +523,364 @@ gfxWindowsPlatform::FindFontForChar(PRUint32 aCh, gfxWindowsFont *aFont)
|
||||||
|
|
||||||
gfxFontGroup *
|
gfxFontGroup *
|
||||||
gfxWindowsPlatform::CreateFontGroup(const nsAString &aFamilies,
|
gfxWindowsPlatform::CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle)
|
const gfxFontStyle *aStyle,
|
||||||
|
gfxUserFontSet *aUserFontSet)
|
||||||
{
|
{
|
||||||
return new gfxWindowsFontGroup(aFamilies, aStyle);
|
return new gfxWindowsFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct FullFontNameSearch {
|
||||||
|
FullFontNameSearch(const nsAString& aFullName)
|
||||||
|
: mFound(PR_FALSE), mFullName(aFullName), mDC(nsnull), mFontEntry(nsnull)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
PRPackedBool mFound;
|
||||||
|
nsString mFullName;
|
||||||
|
nsString mFamilyName;
|
||||||
|
HDC mDC;
|
||||||
|
gfxFontEntry *mFontEntry;
|
||||||
|
};
|
||||||
|
|
||||||
|
// callback called for each face within a single family
|
||||||
|
// match against elfFullName
|
||||||
|
|
||||||
|
static int CALLBACK
|
||||||
|
FindFullNameForFace(const ENUMLOGFONTEXW *lpelfe,
|
||||||
|
const NEWTEXTMETRICEXW *nmetrics,
|
||||||
|
DWORD fontType, LPARAM userArg)
|
||||||
|
{
|
||||||
|
FullFontNameSearch *data = reinterpret_cast<FullFontNameSearch*>(userArg);
|
||||||
|
|
||||||
|
// does the full name match?
|
||||||
|
if (!data->mFullName.Equals(nsDependentString(lpelfe->elfFullName)))
|
||||||
|
return 1; // continue
|
||||||
|
|
||||||
|
// found match, create a new font entry
|
||||||
|
data->mFound = PR_TRUE;
|
||||||
|
|
||||||
|
const NEWTEXTMETRICW& metrics = nmetrics->ntmTm;
|
||||||
|
LOGFONTW logFont = lpelfe->elfLogFont;
|
||||||
|
|
||||||
|
// Some fonts claim to support things > 900, but we don't so clamp the sizes
|
||||||
|
logFont.lfWeight = PR_MAX(PR_MIN(logFont.lfWeight, 900), 100);
|
||||||
|
|
||||||
|
gfxWindowsFontType feType = FontEntry::DetermineFontType(metrics, fontType);
|
||||||
|
|
||||||
|
data->mFontEntry = FontEntry::CreateFontEntry(data->mFamilyName, feType, (logFont.lfItalic == 0xFF), (PRUint16) (logFont.lfWeight), nsnull, data->mDC, &logFont);
|
||||||
|
|
||||||
|
return 0; // stop iteration
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// callback called for each family name, based on the assumption that the
|
||||||
|
// first part of the full name is the family name
|
||||||
|
|
||||||
|
static PLDHashOperator PR_CALLBACK
|
||||||
|
FindFullName(nsStringHashKey::KeyType aKey,
|
||||||
|
nsRefPtr<FontFamily>& aFontFamily,
|
||||||
|
void* userArg)
|
||||||
|
{
|
||||||
|
FullFontNameSearch *data = reinterpret_cast<FullFontNameSearch*>(userArg);
|
||||||
|
|
||||||
|
// does the family name match up to the length of the family name?
|
||||||
|
const nsString& family = aFontFamily->Name();
|
||||||
|
|
||||||
|
nsString fullNameFamily;
|
||||||
|
data->mFullName.Left(fullNameFamily, family.Length());
|
||||||
|
|
||||||
|
// if so, iterate over faces in this family to see if there is a match
|
||||||
|
if (family.Equals(fullNameFamily)) {
|
||||||
|
HDC hdc;
|
||||||
|
|
||||||
|
if (!data->mDC) {
|
||||||
|
data->mDC= GetDC(nsnull);
|
||||||
|
SetGraphicsMode(data->mDC, GM_ADVANCED);
|
||||||
|
}
|
||||||
|
hdc = data->mDC;
|
||||||
|
|
||||||
|
LOGFONTW logFont;
|
||||||
|
memset(&logFont, 0, sizeof(LOGFONTW));
|
||||||
|
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||||
|
logFont.lfPitchAndFamily = 0;
|
||||||
|
PRUint32 l = PR_MIN(family.Length(), LF_FACESIZE - 1);
|
||||||
|
memcpy(logFont.lfFaceName,
|
||||||
|
nsPromiseFlatString(family).get(),
|
||||||
|
l * sizeof(PRUnichar));
|
||||||
|
logFont.lfFaceName[l] = 0;
|
||||||
|
data->mFamilyName.Assign(family);
|
||||||
|
|
||||||
|
EnumFontFamiliesExW(hdc, &logFont, (FONTENUMPROCW)FindFullNameForFace, (LPARAM)data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->mFound)
|
||||||
|
return PL_DHASH_STOP;
|
||||||
|
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxWindowsPlatform::LookupLocalFont(const nsAString& aFontName)
|
||||||
|
{
|
||||||
|
// walk over list of names
|
||||||
|
FullFontNameSearch data(aFontName);
|
||||||
|
|
||||||
|
// find fonts that support the character
|
||||||
|
mFonts.Enumerate(FindFullName, &data);
|
||||||
|
|
||||||
|
if (data.mDC)
|
||||||
|
ReleaseDC(nsnull, data.mDC);
|
||||||
|
|
||||||
|
return data.mFontEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a unique font name, limited on Windows to 31 two-byte characters
|
||||||
|
static void MakeUniqueFontName(PRUnichar aName[LF_FACESIZE])
|
||||||
|
{
|
||||||
|
static PRUint32 fontCount = 0;
|
||||||
|
++fontCount;
|
||||||
|
PRUint32 time = (PRUint32) _time32(nsnull);
|
||||||
|
|
||||||
|
char buf[LF_FACESIZE];
|
||||||
|
|
||||||
|
sprintf(buf, "mozfont%8.8x%8.8x", time, fontCount); // slightly retarded, figure something better later...
|
||||||
|
|
||||||
|
nsCAutoString fontName(buf);
|
||||||
|
|
||||||
|
PRUint32 nameLen = PR_MIN(fontName.Length(), LF_FACESIZE - 1);
|
||||||
|
memcpy(aName, nsPromiseFlatString(NS_ConvertUTF8toUTF16(fontName)).get(), nameLen * 2);
|
||||||
|
aName[nameLen] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from t2embapi.h, included in Platform SDK 6.1 but not 6.0
|
||||||
|
|
||||||
|
#ifndef __t2embapi__
|
||||||
|
|
||||||
|
#define TTLOAD_PRIVATE 0x00000001
|
||||||
|
#define LICENSE_PREVIEWPRINT 0x0004
|
||||||
|
#define E_NONE 0x0000L
|
||||||
|
|
||||||
|
typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long );
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short usStructSize; // size in bytes of structure client should set to sizeof(TTLOADINFO)
|
||||||
|
unsigned short usRefStrSize; // size in wide characters of pusRefStr including NULL terminator
|
||||||
|
unsigned short *pusRefStr; // reference or actual string.
|
||||||
|
}TTLOADINFO;
|
||||||
|
|
||||||
|
LONG WINAPI TTLoadEmbeddedFont
|
||||||
|
(
|
||||||
|
__out HANDLE* phFontReference, // on completion, contains handle to identify embedded font installed
|
||||||
|
// on system
|
||||||
|
__in ULONG ulFlags, // flags specifying the request
|
||||||
|
__out ULONG* pulPrivStatus, // on completion, contains the embedding status
|
||||||
|
__in ULONG ulPrivs, // allows for the reduction of licensing privileges
|
||||||
|
__out ULONG* pulStatus, // on completion, may contain status flags for request
|
||||||
|
__in READEMBEDPROC lpfnReadFromStream, // callback function for doc/disk reads
|
||||||
|
__in LPVOID lpvReadStream, // the input stream tokin
|
||||||
|
__in_opt LPWSTR szWinFamilyName, // the new 16 bit windows family name can be NULL
|
||||||
|
__in_opt LPSTR szMacFamilyName, // the new 8 bit mac family name can be NULL
|
||||||
|
__in_opt TTLOADINFO* pTTLoadInfo // optional security
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // __t2embapi__
|
||||||
|
|
||||||
|
typedef LONG( WINAPI *TTLoadEmbeddedFontProc ) (HANDLE* phFontReference, ULONG ulFlags, ULONG* pulPrivStatus, ULONG ulPrivs, ULONG* pulStatus,
|
||||||
|
READEMBEDPROC lpfnReadFromStream, LPVOID lpvReadStream, LPWSTR szWinFamilyName,
|
||||||
|
LPSTR szMacFamilyName, TTLOADINFO* pTTLoadInfo);
|
||||||
|
|
||||||
|
typedef LONG( WINAPI *TTDeleteEmbeddedFontProc ) (HANDLE hFontReference, ULONG ulFlags, ULONG* pulStatus);
|
||||||
|
|
||||||
|
|
||||||
|
static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nsnull;
|
||||||
|
static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nsnull;
|
||||||
|
|
||||||
|
static void InitializeFontEmbeddingProcs()
|
||||||
|
{
|
||||||
|
HMODULE fontlib = LoadLibrary("t2embed.dll");
|
||||||
|
if (!fontlib)
|
||||||
|
return;
|
||||||
|
TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc) GetProcAddress(fontlib, "TTLoadEmbeddedFont");
|
||||||
|
TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc) GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
|
||||||
|
}
|
||||||
|
|
||||||
|
class WinUserFontData : public gfxUserFontData {
|
||||||
|
public:
|
||||||
|
WinUserFontData(HANDLE aFontRef)
|
||||||
|
: mFontRef(aFontRef)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~WinUserFontData()
|
||||||
|
{
|
||||||
|
ULONG pulStatus;
|
||||||
|
TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE mFontRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to control stream read by Windows TTLoadEmbeddedFont API
|
||||||
|
|
||||||
|
class EOTFontStreamReader {
|
||||||
|
public:
|
||||||
|
EOTFontStreamReader(nsILocalFile *aFontFile, PRUint8 *aEOTHeader,
|
||||||
|
PRUint32 aEOTHeaderLen)
|
||||||
|
: mFontFile(aFontFile), mFd(nsnull), mOpenError(PR_FALSE),
|
||||||
|
mInHeader(PR_TRUE), mHeaderOffset(0), mEOTHeader(aEOTHeader),
|
||||||
|
mEOTHeaderLen(aEOTHeaderLen)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~EOTFontStreamReader()
|
||||||
|
{
|
||||||
|
if (mFd) {
|
||||||
|
PR_Close(mFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFontFile->Remove(PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsILocalFile> mFontFile;
|
||||||
|
PRFileDesc *mFd;
|
||||||
|
PRPackedBool mOpenError;
|
||||||
|
PRPackedBool mInHeader;
|
||||||
|
PRUint32 mHeaderOffset;
|
||||||
|
PRUint8 *mEOTHeader;
|
||||||
|
PRUint32 mEOTHeaderLen;
|
||||||
|
|
||||||
|
PRBool OpenFontFile()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
rv = mFontFile->OpenNSPRFileDesc(PR_RDONLY, 0, &mFd);
|
||||||
|
if (NS_FAILED(rv) || !mFd)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long Read(void *outBuffer, const unsigned long aBytesToRead)
|
||||||
|
{
|
||||||
|
PRUint32 bytesLeft = aBytesToRead;
|
||||||
|
PRUint8 *out = static_cast<PRUint8*> (outBuffer);
|
||||||
|
|
||||||
|
if (mOpenError)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!mFd) {
|
||||||
|
if (!OpenFontFile()) {
|
||||||
|
mOpenError = PR_TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read from EOT header
|
||||||
|
if (mInHeader) {
|
||||||
|
PRUint32 toCopy = PR_MIN(aBytesToRead, mEOTHeaderLen - mHeaderOffset);
|
||||||
|
memcpy(out, mEOTHeader + mHeaderOffset, toCopy);
|
||||||
|
bytesLeft -= toCopy;
|
||||||
|
mHeaderOffset += toCopy;
|
||||||
|
out += toCopy;
|
||||||
|
if (mHeaderOffset == mEOTHeaderLen)
|
||||||
|
mInHeader = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesLeft) {
|
||||||
|
PRInt32 bytesRead = PR_Read(mFd, out, bytesLeft);
|
||||||
|
if (bytesRead > 0)
|
||||||
|
bytesLeft -= bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aBytesToRead - bytesLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long ReadEOTStream(void *aReadStream, void *outBuffer,
|
||||||
|
const unsigned long aBytesToRead)
|
||||||
|
{
|
||||||
|
EOTFontStreamReader *eotReader =
|
||||||
|
static_cast<EOTFontStreamReader*> (aReadStream);
|
||||||
|
return eotReader->Read(outBuffer, aBytesToRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
gfxFontEntry*
|
||||||
|
gfxWindowsPlatform::MakePlatformFont(const gfxFontEntry *aProxyEntry,
|
||||||
|
const gfxDownloadedFontData* aFontData)
|
||||||
|
{
|
||||||
|
// if calls aren't available, bail
|
||||||
|
if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// create an eot header
|
||||||
|
nsAutoTArray<PRUint8,2048> eotHeader;
|
||||||
|
PRUint8 *buffer;
|
||||||
|
PRUint32 eotlen;
|
||||||
|
PRUnichar fontName[LF_FACESIZE];
|
||||||
|
PRBool isCFF;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
HANDLE fontRef;
|
||||||
|
PRInt32 ret;
|
||||||
|
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsILocalFile> fontFile(do_QueryInterface(aFontData->mFontFile, &rv));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
rv = gfxFontUtils::MakeEOTHeader(fontFile, &eotHeader, &isCFF);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// load in embedded font data
|
||||||
|
eotlen = eotHeader.Length();
|
||||||
|
buffer = reinterpret_cast<PRUint8*> (eotHeader.Elements());
|
||||||
|
|
||||||
|
ULONG privStatus, pulStatus;
|
||||||
|
MakeUniqueFontName(fontName);
|
||||||
|
EOTFontStreamReader eotReader(fontFile, buffer, eotlen);
|
||||||
|
|
||||||
|
ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus,
|
||||||
|
LICENSE_PREVIEWPRINT, &pulStatus,
|
||||||
|
EOTFontStreamReader::ReadEOTStream,
|
||||||
|
&eotReader, fontName, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != E_NONE)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// make a new font entry using the unique name
|
||||||
|
WinUserFontData *winUserFontData = new WinUserFontData(fontRef);
|
||||||
|
PRUint16 w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
|
||||||
|
|
||||||
|
return FontEntry::CreateFontEntry(nsDependentString(fontName),
|
||||||
|
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/,
|
||||||
|
PRUint32(aProxyEntry->mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL),
|
||||||
|
w, winUserFontData);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
gfxWindowsPlatform::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags)
|
||||||
|
{
|
||||||
|
// reject based on format flags
|
||||||
|
if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_EOT | gfxUserFontSet::FLAG_FORMAT_SVG)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exclude AAT fonts on platforms other than Mac OS X, this allows
|
||||||
|
// fonts for complex scripts which require AAT tables to be omitted
|
||||||
|
// on other platforms
|
||||||
|
if ((aFormatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT)
|
||||||
|
&& !(aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_OPENTYPE | gfxUserFontSet::FLAG_FORMAT_TRUETYPE))) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reject based on filetype in URI
|
||||||
|
|
||||||
|
// otherwise, return true
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontFamily *
|
FontFamily *
|
||||||
|
|
|
@ -52,7 +52,9 @@ REQUIRES = \
|
||||||
cairo \
|
cairo \
|
||||||
pref \
|
pref \
|
||||||
lcms \
|
lcms \
|
||||||
|
necko \
|
||||||
unicharutil \
|
unicharutil \
|
||||||
|
nspr \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# All platforms
|
# All platforms
|
||||||
|
|
|
@ -288,7 +288,7 @@ PRBool
|
||||||
RunTest (TestEntry *test, gfxContext *ctx) {
|
RunTest (TestEntry *test, gfxContext *ctx) {
|
||||||
nsRefPtr<gfxFontGroup> fontGroup;
|
nsRefPtr<gfxFontGroup> fontGroup;
|
||||||
|
|
||||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle);
|
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle, nsnull);
|
||||||
|
|
||||||
nsAutoPtr<gfxTextRun> textRun;
|
nsAutoPtr<gfxTextRun> textRun;
|
||||||
gfxTextRunFactory::Parameters params = {
|
gfxTextRunFactory::Parameters params = {
|
||||||
|
|
|
@ -96,7 +96,7 @@ RunTest (TestEntry *test, gfxContext *ctx) {
|
||||||
0.0,
|
0.0,
|
||||||
PR_FALSE, PR_FALSE);
|
PR_FALSE, PR_FALSE);
|
||||||
|
|
||||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16);
|
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16, nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoPtr<gfxTextRun> textRun;
|
nsAutoPtr<gfxTextRun> textRun;
|
||||||
|
|
|
@ -163,7 +163,7 @@ main (int argc, char **argv) {
|
||||||
PR_FALSE, PR_FALSE);
|
PR_FALSE, PR_FALSE);
|
||||||
|
|
||||||
nsRefPtr<gfxFontGroup> fontGroup =
|
nsRefPtr<gfxFontGroup> fontGroup =
|
||||||
gfxPlatform::GetPlatform()->CreateFontGroup(NS_LITERAL_STRING("Geneva, MS Sans Serif, Helvetica,serif"), &style);
|
gfxPlatform::GetPlatform()->CreateFontGroup(NS_LITERAL_STRING("Geneva, MS Sans Serif, Helvetica,serif"), &style, nsnull);
|
||||||
|
|
||||||
gfxTextRunFactory::Parameters params = {
|
gfxTextRunFactory::Parameters params = {
|
||||||
ctx, nsnull, nsnull, nsnull, 0, 60
|
ctx, nsnull, nsnull, nsnull, 0, 60
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "gfxMatrix.h"
|
#include "gfxMatrix.h"
|
||||||
#include "gfxTypes.h"
|
#include "gfxTypes.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#ifdef MOZ_SVG
|
#ifdef MOZ_SVG
|
||||||
#include "nsSVGUtils.h"
|
#include "nsSVGUtils.h"
|
||||||
|
@ -1493,10 +1494,13 @@ nsresult
|
||||||
nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
|
nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
|
||||||
nsIFontMetrics** aFontMetrics)
|
nsIFontMetrics** aFontMetrics)
|
||||||
{
|
{
|
||||||
return aStyleContext->PresContext()->DeviceContext()->
|
// pass the user font set object into the device context to pass along to CreateFontGroup
|
||||||
GetMetricsFor(aStyleContext->GetStyleFont()->mFont,
|
gfxUserFontSet* fs = aStyleContext->PresContext()->GetUserFontSet();
|
||||||
|
|
||||||
|
return aStyleContext->PresContext()->DeviceContext()->GetMetricsFor(
|
||||||
|
aStyleContext->GetStyleFont()->mFont,
|
||||||
aStyleContext->GetStyleVisibility()->mLangGroup,
|
aStyleContext->GetStyleVisibility()->mLangGroup,
|
||||||
*aFontMetrics);
|
*aFontMetrics, fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame*
|
nsIFrame*
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
#include "nsStyleChangeList.h"
|
#include "nsStyleChangeList.h"
|
||||||
#include "nsRuleNode.h"
|
#include "nsRuleNode.h"
|
||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
|
||||||
#ifdef IBMBIDI
|
#ifdef IBMBIDI
|
||||||
#include "nsBidiPresUtils.h"
|
#include "nsBidiPresUtils.h"
|
||||||
|
@ -226,6 +227,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
||||||
mNeverAnimate = PR_FALSE;
|
mNeverAnimate = PR_FALSE;
|
||||||
}
|
}
|
||||||
NS_ASSERTION(mDocument, "Null document");
|
NS_ASSERTION(mDocument, "Null document");
|
||||||
|
mUserFontSet = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPresContext::~nsPresContext()
|
nsPresContext::~nsPresContext()
|
||||||
|
@ -283,6 +285,8 @@ nsPresContext::~nsPresContext()
|
||||||
NS_IF_RELEASE(mDeviceContext);
|
NS_IF_RELEASE(mDeviceContext);
|
||||||
NS_IF_RELEASE(mLookAndFeel);
|
NS_IF_RELEASE(mLookAndFeel);
|
||||||
NS_IF_RELEASE(mLangGroup);
|
NS_IF_RELEASE(mLangGroup);
|
||||||
|
|
||||||
|
SetUserFontSet(nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
|
||||||
|
@ -1576,6 +1580,19 @@ nsPresContext::HasAuthorSpecifiedRules(nsIFrame *aFrame, PRUint32 ruleTypeMask)
|
||||||
HasAuthorSpecifiedRules(aFrame->GetStyleContext(), ruleTypeMask);
|
HasAuthorSpecifiedRules(aFrame->GetStyleContext(), ruleTypeMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfxUserFontSet*
|
||||||
|
nsPresContext::GetUserFontSet() {
|
||||||
|
return mUserFontSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsPresContext::SetUserFontSet(gfxUserFontSet *aUserFontSet)
|
||||||
|
{
|
||||||
|
NS_IF_RELEASE(mUserFontSet);
|
||||||
|
mUserFontSet = aUserFontSet;
|
||||||
|
NS_IF_ADDREF(mUserFontSet);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::FireDOMPaintEvent()
|
nsPresContext::FireDOMPaintEvent()
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
// This also pulls in gfxTypes.h, which we cannot include directly.
|
// This also pulls in gfxTypes.h, which we cannot include directly.
|
||||||
#include "gfxRect.h"
|
#include "gfxRect.h"
|
||||||
#include "nsRegion.h"
|
#include "nsRegion.h"
|
||||||
|
|
||||||
class nsImageLoader;
|
class nsImageLoader;
|
||||||
#ifdef IBMBIDI
|
#ifdef IBMBIDI
|
||||||
class nsBidiPresUtils;
|
class nsBidiPresUtils;
|
||||||
|
@ -91,6 +92,7 @@ class nsIAtom;
|
||||||
struct nsStyleBackground;
|
struct nsStyleBackground;
|
||||||
template <class T> class nsRunnableMethod;
|
template <class T> class nsRunnableMethod;
|
||||||
class nsIRunnable;
|
class nsIRunnable;
|
||||||
|
class gfxUserFontSet;
|
||||||
|
|
||||||
#ifdef MOZ_REFLOW_PERF
|
#ifdef MOZ_REFLOW_PERF
|
||||||
class nsIRenderingContext;
|
class nsIRenderingContext;
|
||||||
|
@ -778,6 +780,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool SupressingResizeReflow() const { return mSupressResizeReflow; }
|
PRBool SupressingResizeReflow() const { return mSupressResizeReflow; }
|
||||||
|
|
||||||
|
gfxUserFontSet* GetUserFontSet();
|
||||||
|
void SetUserFontSet(gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
void NotifyInvalidation(const nsRect& aRect, PRBool aIsCrossDoc);
|
void NotifyInvalidation(const nsRect& aRect, PRBool aIsCrossDoc);
|
||||||
void FireDOMPaintEvent();
|
void FireDOMPaintEvent();
|
||||||
|
@ -845,6 +850,9 @@ protected:
|
||||||
nsRegion mSameDocDirtyRegion;
|
nsRegion mSameDocDirtyRegion;
|
||||||
nsRegion mCrossDocDirtyRegion;
|
nsRegion mCrossDocDirtyRegion;
|
||||||
|
|
||||||
|
// container for per-context fonts (downloadable, SVG, etc.)
|
||||||
|
gfxUserFontSet* mUserFontSet;
|
||||||
|
|
||||||
nsLanguageSpecificTransformType mLanguageSpecificTransformType;
|
nsLanguageSpecificTransformType mLanguageSpecificTransformType;
|
||||||
PRInt32 mFontScaler;
|
PRInt32 mFontScaler;
|
||||||
nscoord mMinimumFontSize;
|
nscoord mMinimumFontSize;
|
||||||
|
|
|
@ -151,6 +151,7 @@ CPPSRCS = \
|
||||||
nsDOMCSSRGBColor.cpp \
|
nsDOMCSSRGBColor.cpp \
|
||||||
nsDOMCSSRect.cpp \
|
nsDOMCSSRect.cpp \
|
||||||
nsDOMCSSValueList.cpp \
|
nsDOMCSSValueList.cpp \
|
||||||
|
nsFontFaceLoader.cpp \
|
||||||
nsHTMLCSSStyleSheet.cpp \
|
nsHTMLCSSStyleSheet.cpp \
|
||||||
nsHTMLStyleSheet.cpp \
|
nsHTMLStyleSheet.cpp \
|
||||||
nsInspectorCSSUtils.cpp \
|
nsInspectorCSSUtils.cpp \
|
||||||
|
|
|
@ -82,6 +82,10 @@
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIMediaList.h"
|
#include "nsIMediaList.h"
|
||||||
|
#include "gfxPlatform.h"
|
||||||
|
#include "gfxUserFontSet.h"
|
||||||
|
#include "nsCSSRules.h"
|
||||||
|
#include "nsFontFaceLoader.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||||
static nsTArray< nsCOMPtr<nsIAtom> >* sSystemMetrics = 0;
|
static nsTArray< nsCOMPtr<nsIAtom> >* sSystemMetrics = 0;
|
||||||
|
@ -2292,6 +2296,129 @@ struct CascadeEnumData {
|
||||||
PLArenaPool& mArena;
|
PLArenaPool& mArena;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
InsertFontFaceRule(nsICSSRule* aRule, gfxUserFontSet* fs)
|
||||||
|
{
|
||||||
|
nsCSSFontFaceRule *fontFace = static_cast<nsCSSFontFaceRule*> (aRule);
|
||||||
|
PRInt32 type;
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(aRule->GetType(type))
|
||||||
|
&& type == nsICSSRule::FONT_FACE_RULE,
|
||||||
|
"InsertFontFaceRule passed a non-fontface CSS rule");
|
||||||
|
|
||||||
|
// fontFace->List();
|
||||||
|
|
||||||
|
nsAutoString fontfamily, valueString;
|
||||||
|
nsCSSValue val;
|
||||||
|
|
||||||
|
PRUint32 unit;
|
||||||
|
PRUint32 weight = NS_STYLE_FONT_WEIGHT_NORMAL;
|
||||||
|
PRUint32 stretch = NS_STYLE_FONT_STRETCH_NORMAL;
|
||||||
|
PRUint32 italicStyle = FONT_STYLE_NORMAL;
|
||||||
|
|
||||||
|
// set up family name
|
||||||
|
fontFace->GetDesc(eCSSFontDesc_Family, val);
|
||||||
|
unit = val.GetUnit();
|
||||||
|
if (unit == eCSSUnit_String) {
|
||||||
|
val.GetStringValue(fontfamily);
|
||||||
|
fontfamily.Trim("\"");
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(unit == eCSSUnit_String,
|
||||||
|
"@font-face family name has non-string unit type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up weight
|
||||||
|
fontFace->GetDesc(eCSSFontDesc_Weight, val);
|
||||||
|
unit = val.GetUnit();
|
||||||
|
if (unit != eCSSUnit_Null) {
|
||||||
|
if (unit == eCSSUnit_Normal) {
|
||||||
|
weight = NS_STYLE_FONT_WEIGHT_NORMAL;
|
||||||
|
} else {
|
||||||
|
weight = val.GetIntValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up stretch
|
||||||
|
fontFace->GetDesc(eCSSFontDesc_Stretch, val);
|
||||||
|
unit = val.GetUnit();
|
||||||
|
if (unit != eCSSUnit_Null) {
|
||||||
|
if (unit == eCSSUnit_Normal) {
|
||||||
|
stretch = NS_STYLE_FONT_STRETCH_NORMAL;
|
||||||
|
} else {
|
||||||
|
stretch = val.GetIntValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up font style
|
||||||
|
fontFace->GetDesc(eCSSFontDesc_Style, val);
|
||||||
|
if (val.GetUnit() != eCSSUnit_Null) {
|
||||||
|
if (val.GetUnit() == eCSSUnit_Normal) {
|
||||||
|
italicStyle = FONT_STYLE_NORMAL;
|
||||||
|
} else {
|
||||||
|
italicStyle = val.GetIntValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up src array
|
||||||
|
nsTArray<gfxFontFaceSrc> srcArray;
|
||||||
|
|
||||||
|
fontFace->GetDesc(eCSSFontDesc_Src, val);
|
||||||
|
unit = val.GetUnit();
|
||||||
|
if (unit == eCSSUnit_Array) {
|
||||||
|
nsCSSValue::Array *srcArr = val.GetArrayValue();
|
||||||
|
PRUint32 i, numSrc = srcArr->Count(), faceIndex = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < numSrc; i++) {
|
||||||
|
val = srcArr->Item(i);
|
||||||
|
unit = val.GetUnit();
|
||||||
|
gfxFontFaceSrc *face = srcArray.AppendElements(1);
|
||||||
|
if (!face)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (unit) {
|
||||||
|
|
||||||
|
case eCSSUnit_Local_Font:
|
||||||
|
val.GetStringValue(face->mLocalName);
|
||||||
|
face->mIsLocal = PR_TRUE;
|
||||||
|
face->mURI = nsnull;
|
||||||
|
face->mFormatFlags = 0;
|
||||||
|
break;
|
||||||
|
case eCSSUnit_URL:
|
||||||
|
face->mIsLocal = PR_FALSE;
|
||||||
|
face->mURI = val.GetURLValue();
|
||||||
|
face->mLocalName.Truncate();
|
||||||
|
face->mFormatFlags = 0;
|
||||||
|
while (i + 1 < numSrc && (val = srcArr->Item(i+1),
|
||||||
|
val.GetUnit() == eCSSUnit_Font_Format)) {
|
||||||
|
nsDependentString valueString(val.GetStringBufferValue());
|
||||||
|
if (valueString.LowerCaseEqualsASCII("opentype")) {
|
||||||
|
face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_OPENTYPE;
|
||||||
|
} else if (valueString.LowerCaseEqualsASCII("truetype")) {
|
||||||
|
face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_TRUETYPE;
|
||||||
|
} else if (valueString.LowerCaseEqualsASCII("truetype-aat")) {
|
||||||
|
face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT;
|
||||||
|
} else if (valueString.LowerCaseEqualsASCII("embedded-opentype")) {
|
||||||
|
face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_EOT;
|
||||||
|
} else if (valueString.LowerCaseEqualsASCII("svg")) {
|
||||||
|
face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_SVG;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_ASSERTION(unit == eCSSUnit_Local_Font || unit == eCSSUnit_URL,
|
||||||
|
"strange unit type in font-face src array");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fontfamily.IsEmpty() && srcArray.Length() > 0) {
|
||||||
|
fs->AddFontFace(fontfamily, srcArray, weight, stretch, italicStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
InsertRuleByWeight(nsICSSRule* aRule, void* aData)
|
InsertRuleByWeight(nsICSSRule* aRule, void* aData)
|
||||||
{
|
{
|
||||||
|
@ -2325,10 +2452,28 @@ InsertRuleByWeight(nsICSSRule* aRule, void* aData)
|
||||||
if (!groupRule->EnumerateRulesForwards(InsertRuleByWeight, aData))
|
if (!groupRule->EnumerateRulesForwards(InsertRuleByWeight, aData))
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
else if (nsICSSRule::FONT_FACE_RULE == type
|
||||||
|
&& gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) {
|
||||||
|
nsPresContext *presContext = data->mPresContext;
|
||||||
|
gfxUserFontSet *fs = presContext->GetUserFontSet();
|
||||||
|
if (!fs) {
|
||||||
|
nsFontFaceLoaderContext *loaderCtx = new nsFontFaceLoaderContext(presContext);
|
||||||
|
if (!loaderCtx)
|
||||||
|
return PR_FALSE;
|
||||||
|
fs = new gfxUserFontSet(loaderCtx); // user font set owns loader context
|
||||||
|
if (!fs) {
|
||||||
|
delete loaderCtx;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
presContext->SetUserFontSet(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertFontFaceRule(aRule, fs);
|
||||||
|
}
|
||||||
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
|
CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ nsSVGGlyphFrame::EnsureTextRun(float *aDrawScale, float *aMetricsScale,
|
||||||
font.familyNameQuirks);
|
font.familyNameQuirks);
|
||||||
|
|
||||||
nsRefPtr<gfxFontGroup> fontGroup =
|
nsRefPtr<gfxFontGroup> fontGroup =
|
||||||
gfxPlatform::GetPlatform()->CreateFontGroup(font.name, &fontStyle);
|
gfxPlatform::GetPlatform()->CreateFontGroup(font.name, &fontStyle, presContext->GetUserFontSet());
|
||||||
|
|
||||||
PRUint32 flags = gfxTextRunFactory::TEXT_NEED_BOUNDING_BOX |
|
PRUint32 flags = gfxTextRunFactory::TEXT_NEED_BOUNDING_BOX |
|
||||||
nsLayoutUtils::GetTextRunFlagsForStyle(GetStyleContext(), GetStyleText(), GetStyleFont());
|
nsLayoutUtils::GetTextRunFlagsForStyle(GetStyleContext(), GetStyleText(), GetStyleFont());
|
||||||
|
|
|
@ -134,6 +134,9 @@ pref("gfx.color_management.mode", 2);
|
||||||
pref("gfx.color_management.display_profile", "");
|
pref("gfx.color_management.display_profile", "");
|
||||||
pref("gfx.color_management.rendering_intent", 0);
|
pref("gfx.color_management.rendering_intent", 0);
|
||||||
|
|
||||||
|
pref("gfx.downloadable_fonts.enabled", true);
|
||||||
|
pref("gfx.downloadable_fonts.enforce_same_site_origin", true);
|
||||||
|
|
||||||
pref("accessibility.browsewithcaret", false);
|
pref("accessibility.browsewithcaret", false);
|
||||||
pref("accessibility.warn_on_browsewithcaret", true);
|
pref("accessibility.warn_on_browsewithcaret", true);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче