Bug 352174 need font-family resolver (cannot resolve alias of font family / is not checking whether the specified font family is installed the system) r=pavlov+vlad

This commit is contained in:
masayuki%d-toybox.com 2006-11-21 06:31:04 +00:00
parent 9fece135de
commit 8472edc4b6
18 changed files with 876 additions and 168 deletions

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -96,7 +97,6 @@ public:
protected:
static PRBool FindATSUFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure);
ATSUFontFallbacks mFallbacks;

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -41,6 +42,16 @@
#include "gfxPlatform.h"
#include "nsTArray.h"
#include "nsDataHashtable.h"
class gfxFontNameList : public nsTArray<nsString>
{
public:
THEBES_INLINE_DECL_REFCOUNTING(gfxFontList)
PRBool Exists(nsAString& aName);
};
class NS_EXPORT gfxBeOSPlatform : public gfxPlatform {
public:
gfxBeOSPlatform();
@ -58,6 +69,27 @@ public:
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts);
nsresult UpdateFontList();
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
protected:
PRInt32 IsExistingFont(const nsACString& aFontName);
nsresult GetResolvedFonts(const nsACString& aName,
gfxFontNameList* aResult);
nsresult GetFontListInternal(nsCStringArray& aListOfFonts,
const nsACString *aLangGroup = nsnull);
nsresult UpdateFontListInternal(PRBool aForce = PR_FALSE);
nsCStringArray mFonts;
nsCStringArray mNonExistingFonts;
nsCStringArray mAliasForSingleFont;
nsCStringArray mAliasForMultiFonts;
nsDataHashtable<nsCStringHashKey, nsRefPtr<gfxFontNameList> > mAliasTable;
};
#endif /* GFX_PLATFORM_BEOS_H */

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -205,7 +206,6 @@ public:
*/
typedef PRBool (*FontCreationCallback) (const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure);
static PRBool ForEachFont(const nsAString& aFamilies,
const nsACString& aLangGroup,
@ -228,6 +228,8 @@ protected:
PRBool aResolveGeneric,
FontCreationCallback fc,
void *closure);
static PRBool FontResolverProc(const nsAString& aName, void *aClosure);
};

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -49,8 +50,7 @@
class gfxPangoFont : public gfxFont {
public:
gfxPangoFont (const nsAString& aName,
const gfxFontStyle *aFontStyle,
PangoLanguage* aPangoLang = nsnull);
const gfxFontStyle *aFontStyle);
virtual ~gfxPangoFont ();
virtual const gfxFont::Metrics& GetMetrics();
@ -73,10 +73,6 @@ protected:
PRBool mHasMetrics;
Metrics mMetrics;
PangoLanguage *mPangoLang;
nsCString mMozLang;
nsCString mActualFontFamily;
void RealizeFont(PRBool force = PR_FALSE);
void RealizeXftFont(PRBool force = PR_FALSE);
void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize);
@ -109,7 +105,6 @@ public:
protected:
static PRBool FontCallback (const nsAString& fontName,
const nsACString& genericName,
const nsACString& aLangGroup,
void *closure);
private:
nsDataHashtable<nsStringHashKey, nsRefPtr<gfxPangoFont> > mFontCache;

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -96,6 +97,19 @@ public:
*/
virtual nsresult UpdateFontList();
/**
* Font name resolver, this returns actual font name(s) by the callback
* function. If the font doesn't exist, the callback function is not called.
* If the callback function returns PR_FALSE, the aAborted value is set to
* PR_TRUE, otherwise, PR_FALSE.
*/
typedef PRBool (*FontResolverCallback) (const nsAString& aName,
void *aClosure);
virtual nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
PRBool& aAborted) = 0;
/* Returns PR_TRUE if the given block of ARGB32 data really has alpha, otherwise PR_FALSE */
static PRBool DoesARGBImageDataHaveAlpha(PRUint8* data,
PRUint32 width,

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -42,6 +43,16 @@
#include "gfxPlatform.h"
#include "nsTArray.h"
#include "nsDataHashtable.h"
class gfxFontNameList : public nsTArray<nsString>
{
public:
THEBES_INLINE_DECL_REFCOUNTING(gfxFontList)
PRBool Exists(nsAString& aName);
};
class THEBES_API gfxPlatformGtk : public gfxPlatform {
public:
gfxPlatformGtk();
@ -63,6 +74,12 @@ public:
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts);
nsresult UpdateFontList();
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
static PRInt32 DPI() {
if (sDPI == -1) {
InitDPI();
@ -72,6 +89,20 @@ public:
}
protected:
PRInt32 IsExistingFont(const nsACString& aFontName);
nsresult GetResolvedFonts(const nsACString& aName,
gfxFontNameList* aResult);
nsresult GetFontListInternal(nsCStringArray& aListOfFonts,
const nsACString *aLangGroup = nsnull);
nsresult UpdateFontListInternal(PRBool aForce = PR_FALSE);
nsCStringArray mFonts;
nsCStringArray mNonExistingFonts;
nsCStringArray mAliasForSingleFont;
nsCStringArray mAliasForMultiFonts;
nsDataHashtable<nsCStringHashKey, nsRefPtr<gfxFontNameList> > mAliasTable;
static void InitDPI();

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -51,6 +52,11 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat);
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
};
#endif /* GFX_PLATFORM_MAC_H */

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -456,7 +457,6 @@ public:
protected:
static PRBool MakeFont(const nsAString& fontName,
const nsACString& genericName,
const nsACString& aLangGroup,
void *closure);
private:

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <pavlov@pavlov.net>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -65,6 +66,9 @@ public:
nsresult UpdateFontList();
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
/* local methods */
void FindOtherFonts(const PRUnichar *aString, PRUint32 aLength, const char *aLangGroup, const char *aGeneric, nsString& array);
@ -79,6 +83,10 @@ private:
const NEWTEXTMETRICEXW *metrics,
DWORD fontType, LPARAM data);
static int CALLBACK FontResolveProc(const ENUMLOGFONTEXW *lpelfe,
const NEWTEXTMETRICEXW *metrics,
DWORD fontType, LPARAM data);
static PLDHashOperator PR_CALLBACK HashEnumFunc(nsStringHashKey::KeyType aKey,
nsRefPtr<FontEntry>& aData,
void* userArg);
@ -89,6 +97,8 @@ private:
nsDataHashtable<nsStringHashKey, nsRefPtr<FontEntry> > mFonts;
nsDataHashtable<nsStringHashKey, nsRefPtr<WeightTable> > mFontWeights;
nsDataHashtable<nsStringHashKey, nsRefPtr<FontEntry> > mFontAliases;
nsStringArray mNonExistingFonts;
};
#endif /* GFX_WINDOWS_PLATFORM_H */

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -260,7 +261,6 @@ gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
PRBool
gfxAtsuiFontGroup::FindATSUFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure)
{
gfxAtsuiFontGroup *fontGroup = (gfxAtsuiFontGroup*) closure;

View File

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -66,57 +67,43 @@ gfxBeOSPlatform::CreateOffscreenSurface (PRUint32 width,
return newSurface;
}
// this is in nsFontConfigUtils.h
extern void NS_AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
nsresult
gfxBeOSPlatform::GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts)
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts)
{
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
nsresult rv = NS_ERROR_FAILURE;
aListOfFonts.Clear();
nsresult rv = UpdateFontListInternal();
if (NS_FAILED(rv))
return rv;
nsCStringArray tmpFonts;
nsCStringArray *fonts = &mFonts;
if (!aLangGroup.IsEmpty() || !aGenericFamily.IsEmpty()) {
rv = GetFontListInternal(tmpFonts, &aLangGroup);
if (NS_FAILED(rv))
return rv;
fonts = &tmpFonts;
}
for (PRInt32 i = 0; i < fonts->Count(); ++i)
aListOfFonts.AppendString(NS_ConvertUTF8toUTF16(*fonts->CStringAt(i)));
PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics;
pat = FcPatternCreate();
if (!pat)
goto end;
os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0);
if (!os)
goto end;
// take the pattern and add the lang group to it
if (!aLangGroup.IsEmpty()) {
nsCOMPtr<nsIAtom> langAtom = do_GetAtom(aLangGroup);
//XXX fix me //NS_AddLangGroup(pat, langAtom);
}
fs = FcFontList(0, pat, os);
if (!fs)
goto end;
if (fs->nfont == 0) {
rv = NS_OK;
goto end;
}
// Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
// "monospace", slightly different from CSS's 5.
if (aGenericFamily.IsEmpty())
serif = sansSerif = monospace = 1;
else if (aGenericFamily.EqualsLiteral("serif"))
else if (aGenericFamily.LowerCaseEqualsLiteral("serif"))
serif = 1;
else if (aGenericFamily.EqualsLiteral("sans-serif"))
else if (aGenericFamily.LowerCaseEqualsLiteral("sans-serif"))
sansSerif = 1;
else if (aGenericFamily.EqualsLiteral("monospace"))
else if (aGenericFamily.LowerCaseEqualsLiteral("monospace"))
monospace = 1;
else if (aGenericFamily.EqualsLiteral("cursive") || aGenericFamily.EqualsLiteral("fantasy"))
else if (aGenericFamily.LowerCaseEqualsLiteral("cursive") ||
aGenericFamily.LowerCaseEqualsLiteral("fantasy"))
serif = sansSerif = 1;
else
NS_NOTREACHED("unexpected CSS generic font family");
@ -129,20 +116,60 @@ gfxBeOSPlatform::GetFontList(const nsACString& aLangGroup,
if (monospace)
aListOfFonts.AppendString(NS_LITERAL_STRING("monospace"));
aListOfFonts.Sort();
return NS_OK;
}
// this is in nsFontConfigUtils.h
extern void NS_AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
nsresult
gfxBeOSPlatform::GetFontListInternal(nsCStringArray& aListOfFonts,
const nsACString *aLangGroup)
{
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
nsresult rv = NS_ERROR_FAILURE;
aListOfFonts.Clear();
pat = FcPatternCreate();
if (!pat)
goto end;
os = FcObjectSetBuild(FC_FAMILY, NULL);
if (!os)
goto end;
// take the pattern and add the lang group to it
if (aLangGroup && !aLangGroup->IsEmpty()) {
nsCOMPtr<nsIAtom> langAtom = do_GetAtom(*aLangGroup);
//XXX fix me //NS_AddLangGroup(pat, langAtom);
}
fs = FcFontList(NULL, pat, os);
if (!fs)
goto end;
for (int i = 0; i < fs->nfont; i++) {
char *family;
// if there's no family name, skip this match
if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch)
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch)
{
continue;
}
aListOfFonts.AppendString(NS_ConvertASCIItoUTF16(nsDependentCString(family)));
// Remove duplicates...
nsCAutoString strFamily(family);
if (aListOfFonts.IndexOf(strFamily) >= 0)
continue;
aListOfFonts.AppendCString(strFamily);
}
aListOfFonts.Sort();
rv = NS_OK;
end:
@ -158,3 +185,239 @@ gfxBeOSPlatform::GetFontList(const nsACString& aLangGroup,
return rv;
}
nsresult
gfxBeOSPlatform::UpdateFontList()
{
return UpdateFontListInternal(PR_TRUE);
}
nsresult
gfxBeOSPlatform::UpdateFontListInternal(PRBool aForce)
{
if (!aForce && FcConfigUptoDate(NULL))
return NS_OK;
FcInitReinitialize();
mFonts.Clear();
mAliasForSingleFont.Clear();
mAliasForMultiFonts.Clear();
mNonExistingFonts.Clear();
mAliasTable.Clear();
nsresult rv = GetFontListInternal(mFonts);
if (NS_FAILED(rv))
return rv;
// XXX we don't support all alias names.
// Because if we don't check whether the given font name is alias name,
// fontconfig converts the non existing font to sans-serif.
// This is not good if the web page specifies font-family
// that has Windows font name in the first.
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrefBranch> prefBranch;
prefs->GetBranch(0, getter_AddRefs(prefBranch));
if (!prefBranch)
return NS_ERROR_FAILURE;
nsXPIDLCString list;
rv = prefBranch->GetCharPref("font.alias-list", getter_Copies(list));
if (NS_FAILED(rv))
return NS_OK;
if (!list.IsEmpty()) {
const char kComma = ',';
const char *p, *p_end;
list.BeginReading(p);
list.EndReading(p_end);
while (p < p_end) {
while (nsCRT::IsAsciiSpace(*p)) {
if (++p == p_end)
break;
}
if (p == p_end)
break;
const char *start = p;
while (++p != p_end && *p != kComma)
/* nothing */ ;
nsCAutoString name(Substring(start, p));
name.CompressWhitespace(PR_FALSE, PR_TRUE);
mAliasForMultiFonts.AppendCString(name);
p++;
}
}
if (mAliasForMultiFonts.Count() == 0)
return NS_OK;
for (PRInt32 i = 0; i < mAliasForMultiFonts.Count(); i++) {
nsRefPtr<gfxFontNameList> fonts = new gfxFontNameList;
nsCAutoString fontname(*mAliasForMultiFonts.CStringAt(i));
rv = GetResolvedFonts(fontname, fonts);
if (NS_FAILED(rv))
return rv;
nsCAutoString key;
ToLowerCase(fontname, key);
mAliasTable.Put(key, fonts);
}
return NS_OK;
}
nsresult
gfxBeOSPlatform::GetResolvedFonts(const nsACString& aName,
gfxFontNameList* aResult)
{
FcPattern *pat = NULL;
FcFontSet *fs = NULL;
FcResult fresult;
aResult->Clear();
nsresult rv = NS_ERROR_FAILURE;
pat = FcPatternCreate();
if (!pat)
goto end;
FcDefaultSubstitute(pat);
FcPatternAddString(pat, FC_FAMILY,
(FcChar8 *)nsPromiseFlatCString(aName).get());
// Delete the lang param. We need lang independent alias list.
FcPatternDel(pat, FC_LANG);
FcConfigSubstitute(NULL, pat, FcMatchPattern);
fs = FcFontSort(NULL, pat, FcTrue, NULL, &fresult);
if (!fs)
goto end;
rv = NS_OK;
for (int i = 0; i < fs->nfont; i++) {
char *family;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch ||
mAliasForMultiFonts.IndexOfIgnoreCase(nsDependentCString(family)) >= 0 ||
IsExistingFont(nsDependentCString(family)) == 0)
{
continue;
}
NS_ConvertUTF8toUTF16 actualName(family);
if (aResult->Exists(actualName))
continue;
aResult->AppendElement(actualName);
}
end:
if (pat)
FcPatternDestroy(pat);
if (fs)
FcFontSetDestroy(fs);
return rv;
}
nsresult
gfxBeOSPlatform::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
PRBool& aAborted)
{
nsresult rv = UpdateFontListInternal();
if (NS_FAILED(rv))
return rv;
NS_ConvertUTF16toUTF8 fontname(aFontName);
if (mAliasForMultiFonts.IndexOfIgnoreCase(fontname) >= 0) {
nsCAutoString key;
ToLowerCase(fontname, key);
nsRefPtr<gfxFontNameList> fonts;
if (!mAliasTable.Get(key, &fonts))
NS_ERROR("The mAliasTable was broken!");
for (PRUint32 i = 0; i < fonts->Length(); i++) {
aAborted = !(*aCallback)(fonts->ElementAt(i), aClosure);
if (aAborted)
break;
}
} else {
PRInt32 result = IsExistingFont(fontname);
if (result < 0)
return NS_ERROR_FAILURE;
if (result > 0)
aAborted = !(*aCallback)(aFontName, aClosure);
}
return NS_OK;
}
PRInt32
gfxBeOSPlatform::IsExistingFont(const nsACString &aFontName)
{
// Very many sites may specify the font-family only for Windows and Mac.
// We should check negative cache at first.
if (mNonExistingFonts.IndexOf(aFontName) >= 0)
return 0;
else if (mAliasForSingleFont.IndexOf(aFontName) >= 0)
return 1;
else if (mFonts.IndexOf(aFontName) >= 0)
return 1;
// XXX Sometimes, the font has two or more names (e.g., "Sazanami Gothic"
// has Japanese localized name). The another name doesn't including the
// cache. Therefore, we need to check the name.
// But we don't need to resolve the name. Because both names are not same
// behavior. E.g., the default settings of "Sazanami" on Fedora Core 5,
// the non-localized name uses Anti-alias, but the localized name uses it.
// So, we should check just whether the font is existing, don't resolve
// to regular name.
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
PRInt32 result = -1;
pat = FcPatternCreate();
if (!pat)
goto end;
FcPatternAddString(pat, FC_FAMILY,
(FcChar8 *)nsPromiseFlatCString(aFontName).get());
os = FcObjectSetBuild(FC_FAMILY, NULL);
if (!os)
goto end;
fs = FcFontList(NULL, pat, os);
if (!fs)
goto end;
result = fs->nfont;
NS_ASSERTION(result == 1, "What's this case?");
if (result > 0)
mAliasForSingleFont.AppendCString(aFontName);
else
mNonExistingFonts.AppendCString(aFontName);
end:
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
return result;
}
PRBool
gfxFontNameList::Exists(nsAString& aName) {
for (PRUint32 i = 0; i < Length(); i++) {
if (aName.Equals(ElementAt(i)))
return PR_TRUE;
}
return PR_FALSE;
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -40,6 +41,7 @@
#include "nsReadableUtils.h"
#include "gfxFont.h"
#include "gfxPlatform.h"
#include "prtypes.h"
#include "gfxTypes.h"
@ -77,6 +79,19 @@ gfxFontGroup::ForEachFont(const nsAString& aFamilies,
PR_FALSE, fc, closure);
}
struct ResolveData {
ResolveData(gfxFontGroup::FontCreationCallback aCallback,
nsACString& aGenericFamily,
void *aClosure) :
mCallback(aCallback),
mGenericFamily(aGenericFamily),
mClosure(aClosure) {
};
gfxFontGroup::FontCreationCallback mCallback;
nsCString mGenericFamily;
void *mClosure;
};
PRBool
gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
const nsACString& aLangGroup,
@ -167,8 +182,14 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
}
if (!family.IsEmpty()) {
if (!((*fc) (family, NS_LossyConvertUTF16toASCII(genericFamily),
lang, closure)))
NS_LossyConvertUTF16toASCII gf(genericFamily);
ResolveData data(fc, gf, closure);
PRBool aborted;
gfxPlatform *pf = gfxPlatform::GetPlatform();
nsresult rv = pf->ResolveFontName(family,
gfxFontGroup::FontResolverProc,
&data, aborted);
if (NS_FAILED(rv) || aborted)
return PR_FALSE;
}
@ -190,6 +211,13 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
return PR_TRUE;
}
PRBool
gfxFontGroup::FontResolverProc(const nsAString& aName, void *aClosure)
{
ResolveData *data = reinterpret_cast<ResolveData*>(aClosure);
return (data->mCallback)(aName, data->mGenericFamily, data->mClosure);
}
void
gfxFontGroup::FindGenericFontFromStyle(FontCreationCallback fc,
void *closure)
@ -214,8 +242,8 @@ gfxFontGroup::FindGenericFontFromStyle(FontCreationCallback fc,
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(familyName));
if (NS_SUCCEEDED(rv)) {
(*fc)(familyName, NS_LossyConvertUTF16toASCII(genericName),
mStyle.langGroup, closure);
ForEachFontInternal(familyName, mStyle.langGroup,
PR_FALSE, fc, closure);
}
prefName.AssignLiteral("font.name-list.");

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* based on nsFontMetricsPango.cpp by
* Christopher Blizzard <blizzard@mozilla.org>
@ -117,12 +118,11 @@ FFRECountHyphens (const nsAString &aFFREName)
PRBool
gfxPangoFontGroup::FontCallback (const nsAString& fontName,
const nsACString& genericName,
const nsACString& aLangGroup,
void *closure)
{
nsStringArray *sa = NS_STATIC_CAST(nsStringArray*, closure);
if (FFRECountHyphens(fontName) < 3) {
if (FFRECountHyphens(fontName) < 3 && sa->IndexOf(fontName) < 0) {
sa->AppendString(fontName);
}
@ -143,6 +143,14 @@ gfxPangoFontGroup::gfxPangoFontGroup (const nsAString& families,
FindGenericFontFromStyle (FontCallback, &familyArray);
// XXX If there are no actual fonts, we should use dummy family.
// Pango will resolve from this.
if (familyArray.Count() == 0) {
// printf("%s(%s)\n", NS_ConvertUTF16toUTF8(families).get(),
// aStyle->langGroup.get());
familyArray.AppendString(NS_LITERAL_STRING("sans-serif"));
}
for (int i = 0; i < familyArray.Count(); i++)
mFonts.AppendElement(new gfxPangoFont(*familyArray[i], &mStyle));
}
@ -252,8 +260,7 @@ MOZ_pango_font_description_set_absolute_size(PangoFontDescription *desc, double
#endif
gfxPangoFont::gfxPangoFont(const nsAString &aName,
const gfxFontStyle *aFontStyle,
PangoLanguage* aPangoLang)
const gfxFontStyle *aFontStyle)
: gfxFont(aName, aFontStyle)
{
InitPangoLib();
@ -262,7 +269,6 @@ gfxPangoFont::gfxPangoFont(const nsAString &aName,
mPangoCtx = nsnull;
mHasMetrics = PR_FALSE;
mXftFont = nsnull;
mPangoLang = aPangoLang;
}
gfxPangoFont::~gfxPangoFont()
@ -364,9 +370,7 @@ gfxPangoFont::RealizeFont(PRBool force)
mPangoCtx = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(pango_cairo_font_map_get_default()));
#endif
if (mPangoLang)
pango_context_set_language(mPangoCtx, mPangoLang);
else if (!mStyle->langGroup.IsEmpty())
if (!mStyle->langGroup.IsEmpty())
pango_context_set_language(mPangoCtx, GetPangoLanguage(mStyle->langGroup));
pango_context_set_font_description(mPangoCtx, mPangoFontDesc);
@ -594,34 +598,9 @@ gfxPangoFont::GetMetrics()
void
gfxPangoFont::GetMozLang(nsACString &aMozLang)
{
if (!mMozLang.IsEmpty()) {
aMozLang.Assign(mMozLang);
return;
}
if (mPangoLang) {
GetMozLanguage(mPangoLang, mMozLang);
aMozLang.Assign(mMozLang);
return;
}
aMozLang.Assign(mStyle->langGroup);
}
void
gfxPangoFont::GetActualFontFamily(nsACString &aFamily)
{
if (!mActualFontFamily.IsEmpty()) {
aFamily.Assign(mActualFontFamily);
return;
}
PangoFont* font = GetPangoFont();
FcChar8 *family;
FcPatternGetString(PANGO_FC_FONT(font)->font_pattern,
FC_FAMILY, 0, &family);
mActualFontFamily.Assign((char *)family);
aFamily.Assign(mActualFontFamily);
}
PangoFont*
gfxPangoFont::GetPangoFont()
{
@ -1063,60 +1042,31 @@ public:
}
static PRBool ExistsFont(FontSelector *aFs,
nsACString &aName) {
const nsAString &aName) {
PRUint32 len = aFs->mFonts.Length();
for (PRUint32 i = 0; i < len; ++i) {
nsCAutoString family;
aFs->mFonts[i]->GetActualFontFamily(family);
if (aName.Equals(family))
if (aName.Equals(aFs->mFonts[i]->GetName()))
return PR_TRUE;
}
return PR_FALSE;
}
static PRBool IsAliasFontName(const nsACString &aName) {
return aName.Equals("serif",
nsCaseInsensitiveCStringComparator()) ||
aName.Equals("sans-serif",
nsCaseInsensitiveCStringComparator()) ||
aName.Equals("sans",
nsCaseInsensitiveCStringComparator()) ||
aName.Equals("monospace",
nsCaseInsensitiveCStringComparator());
}
static PRBool AddFontCallback(const nsAString &aName,
const nsACString &aGenericName,
const nsACString &aLangGroup,
void *closure) {
if (aName.IsEmpty())
return PR_TRUE;
NS_ConvertUTF16toUTF8 name(aName);
FontSelector *fs = NS_STATIC_CAST(FontSelector*, closure);
PRBool isASCIIFontName = IsASCII(name);
// XXX do something better than this to remove dups
if (isASCIIFontName && !IsAliasFontName(name) && ExistsFont(fs, name))
if (ExistsFont(fs, aName))
return PR_TRUE;
nsRefPtr<gfxPangoFont> font = fs->mGroup->GetCachedFont(aName);
if (!font) {
const gfxFontStyle *style = fs->mGroup->GetStyle();
font = new gfxPangoFont(aName, style, GetPangoLanguage(aLangGroup));
nsCAutoString family;
font->GetActualFontFamily(family);
if (!family.Equals(name) && ExistsFont(fs, family))
return PR_TRUE;
// XXX Asume that the alias name is ASCII in fontconfig.
// Maybe, it is worong, but it is enough in general cases.
if (!isASCIIFontName)
fs->mGroup->PutCachedFont(aName, font);
else
fs->mGroup->PutCachedFont(NS_ConvertUTF8toUTF16(family), font);
font = new gfxPangoFont(aName, fs->mGroup->GetStyle());
fs->mGroup->PutCachedFont(aName, font);
}
fs->mFonts.AppendElement(font);

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -53,8 +54,9 @@
#include "glitz-glx.h"
#endif
#ifndef THEBES_USE_PANGO_CAIRO
#include <fontconfig/fontconfig.h>
#ifndef THEBES_USE_PANGO_CAIRO
#include <pango/pangoxft.h>
#endif // THEBES_USE_PANGO_CAIRO
@ -62,6 +64,12 @@
#include "nsUnitConversion.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsServiceManagerUtils.h"
#include "nsCRT.h"
PRInt32 gfxPlatformGtk::sDPI = -1;
static cairo_user_data_key_t cairo_gdk_window_key;
@ -78,6 +86,8 @@ gfxPlatformGtk::gfxPlatformGtk()
if (UseGlitz())
glitz_glx_init(NULL);
#endif
mAliasTable.Init(50);
UpdateFontListInternal(PR_TRUE);
}
already_AddRefed<gfxASurface>
@ -217,47 +227,31 @@ gfxPlatformGtk::SetSurfaceGdkWindow(gfxASurface *aSurf,
nsnull);
}
// this is in nsFontConfigUtils.h
extern void NS_AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
nsresult
gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts)
{
#ifndef THEBES_USE_PANGO_CAIRO
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
nsresult rv = NS_ERROR_FAILURE;
aListOfFonts.Clear();
nsresult rv = UpdateFontListInternal();
if (NS_FAILED(rv))
return rv;
nsCStringArray tmpFonts;
nsCStringArray *fonts = &mFonts;
if (!aLangGroup.IsEmpty() || !aGenericFamily.IsEmpty()) {
rv = GetFontListInternal(tmpFonts, &aLangGroup);
if (NS_FAILED(rv))
return rv;
fonts = &tmpFonts;
}
for (PRInt32 i = 0; i < fonts->Count(); ++i)
aListOfFonts.AppendString(NS_ConvertUTF8toUTF16(*fonts->CStringAt(i)));
PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics;
pat = FcPatternCreate();
if (!pat)
goto end;
os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0, NULL);
if (!os)
goto end;
// take the pattern and add the lang group to it
if (!aLangGroup.IsEmpty()) {
nsCOMPtr<nsIAtom> langAtom = do_GetAtom(aLangGroup);
//XXX fix me //NS_AddLangGroup(pat, langAtom);
}
fs = FcFontList(0, pat, os);
if (!fs)
goto end;
if (fs->nfont == 0) {
rv = NS_OK;
goto end;
}
// Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
// "monospace", slightly different from CSS's 5.
if (aGenericFamily.IsEmpty())
@ -282,20 +276,60 @@ gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
if (monospace)
aListOfFonts.AppendString(NS_LITERAL_STRING("monospace"));
aListOfFonts.Sort();
return NS_OK;
}
// this is in nsFontConfigUtils.h
extern void NS_AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
nsresult
gfxPlatformGtk::GetFontListInternal(nsCStringArray& aListOfFonts,
const nsACString *aLangGroup)
{
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
nsresult rv = NS_ERROR_FAILURE;
aListOfFonts.Clear();
pat = FcPatternCreate();
if (!pat)
goto end;
os = FcObjectSetBuild(FC_FAMILY, NULL);
if (!os)
goto end;
// take the pattern and add the lang group to it
if (aLangGroup && !aLangGroup->IsEmpty()) {
nsCOMPtr<nsIAtom> langAtom = do_GetAtom(*aLangGroup);
//XXX fix me //NS_AddLangGroup(pat, langAtom);
}
fs = FcFontList(NULL, pat, os);
if (!fs)
goto end;
for (int i = 0; i < fs->nfont; i++) {
char *family;
// if there's no family name, skip this match
if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch)
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch)
{
continue;
}
aListOfFonts.AppendString(NS_ConvertUTF8toUTF16(nsDependentCString(family)));
// Remove duplicates...
nsCAutoString strFamily(family);
if (aListOfFonts.IndexOf(strFamily) >= 0)
continue;
aListOfFonts.AppendCString(strFamily);
}
aListOfFonts.Sort();
rv = NS_OK;
end:
@ -310,10 +344,232 @@ gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
FcFontSetDestroy(fs);
return rv;
#else
// pango_cairo case; needs to be written
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
nsresult
gfxPlatformGtk::UpdateFontList()
{
return UpdateFontListInternal(PR_TRUE);
}
nsresult
gfxPlatformGtk::UpdateFontListInternal(PRBool aForce)
{
if (!aForce && FcConfigUptoDate(NULL))
return NS_OK;
FcInitReinitialize();
mFonts.Clear();
mAliasForSingleFont.Clear();
mAliasForMultiFonts.Clear();
mNonExistingFonts.Clear();
mAliasTable.Clear();
nsresult rv = GetFontListInternal(mFonts);
if (NS_FAILED(rv))
return rv;
// XXX we don't support all alias names.
// Because if we don't check whether the given font name is alias name,
// fontconfig converts the non existing font to sans-serif.
// This is not good if the web page specifies font-family
// that has Windows font name in the first.
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPrefBranch> prefBranch;
prefs->GetBranch(0, getter_AddRefs(prefBranch));
if (!prefBranch)
return NS_ERROR_FAILURE;
nsXPIDLCString list;
rv = prefBranch->GetCharPref("font.alias-list", getter_Copies(list));
if (NS_FAILED(rv))
return NS_OK;
if (!list.IsEmpty()) {
const char kComma = ',';
const char *p, *p_end;
list.BeginReading(p);
list.EndReading(p_end);
while (p < p_end) {
while (nsCRT::IsAsciiSpace(*p)) {
if (++p == p_end)
break;
}
if (p == p_end)
break;
const char *start = p;
while (++p != p_end && *p != kComma)
/* nothing */ ;
nsCAutoString name(Substring(start, p));
name.CompressWhitespace(PR_FALSE, PR_TRUE);
mAliasForMultiFonts.AppendCString(name);
p++;
}
}
if (mAliasForMultiFonts.Count() == 0)
return NS_OK;
for (PRInt32 i = 0; i < mAliasForMultiFonts.Count(); i++) {
nsRefPtr<gfxFontNameList> fonts = new gfxFontNameList;
nsCAutoString fontname(*mAliasForMultiFonts.CStringAt(i));
rv = GetResolvedFonts(fontname, fonts);
if (NS_FAILED(rv))
return rv;
nsCAutoString key;
ToLowerCase(fontname, key);
mAliasTable.Put(key, fonts);
}
return NS_OK;
}
nsresult
gfxPlatformGtk::GetResolvedFonts(const nsACString& aName,
gfxFontNameList* aResult)
{
FcPattern *pat = NULL;
FcFontSet *fs = NULL;
FcResult fresult;
aResult->Clear();
nsresult rv = NS_ERROR_FAILURE;
pat = FcPatternCreate();
if (!pat)
goto end;
FcDefaultSubstitute(pat);
FcPatternAddString(pat, FC_FAMILY,
(FcChar8 *)nsPromiseFlatCString(aName).get());
// Delete the lang param. We need lang independent alias list.
FcPatternDel(pat, FC_LANG);
FcConfigSubstitute(NULL, pat, FcMatchPattern);
fs = FcFontSort(NULL, pat, FcTrue, NULL, &fresult);
if (!fs)
goto end;
rv = NS_OK;
for (int i = 0; i < fs->nfont; i++) {
char *family;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &family) != FcResultMatch ||
mAliasForMultiFonts.IndexOfIgnoreCase(nsDependentCString(family)) >= 0 ||
IsExistingFont(nsDependentCString(family)) == 0)
{
continue;
}
NS_ConvertUTF8toUTF16 actualName(family);
if (aResult->Exists(actualName))
continue;
aResult->AppendElement(actualName);
}
end:
if (pat)
FcPatternDestroy(pat);
if (fs)
FcFontSetDestroy(fs);
return rv;
}
nsresult
gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
PRBool& aAborted)
{
nsresult rv = UpdateFontListInternal();
if (NS_FAILED(rv))
return rv;
NS_ConvertUTF16toUTF8 fontname(aFontName);
if (mAliasForMultiFonts.IndexOfIgnoreCase(fontname) >= 0) {
nsCAutoString key;
ToLowerCase(fontname, key);
nsRefPtr<gfxFontNameList> fonts;
if (!mAliasTable.Get(key, &fonts))
NS_ERROR("The mAliasTable was broken!");
for (PRUint32 i = 0; i < fonts->Length(); i++) {
aAborted = !(*aCallback)(fonts->ElementAt(i), aClosure);
if (aAborted)
break;
}
} else {
PRInt32 result = IsExistingFont(fontname);
if (result < 0)
return NS_ERROR_FAILURE;
if (result > 0)
aAborted = !(*aCallback)(aFontName, aClosure);
}
return NS_OK;
}
PRInt32
gfxPlatformGtk::IsExistingFont(const nsACString &aFontName)
{
// Very many sites may specify the font-family only for Windows and Mac.
// We should check negative cache at first.
if (mNonExistingFonts.IndexOf(aFontName) >= 0)
return 0;
else if (mAliasForSingleFont.IndexOf(aFontName) >= 0)
return 1;
else if (mFonts.IndexOf(aFontName) >= 0)
return 1;
// XXX Sometimes, the font has two or more names (e.g., "Sazanami Gothic"
// has Japanese localized name). The another name doesn't including the
// cache. Therefore, we need to check the name.
// But we don't need to resolve the name. Because both names are not same
// behavior. E.g., the default settings of "Sazanami" on Fedora Core 5,
// the non-localized name uses Anti-alias, but the localized name uses it.
// So, we should check just whether the font is existing, don't resolve
// to regular name.
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *fs = NULL;
PRInt32 result = -1;
pat = FcPatternCreate();
if (!pat)
goto end;
FcPatternAddString(pat, FC_FAMILY,
(FcChar8 *)nsPromiseFlatCString(aFontName).get());
os = FcObjectSetBuild(FC_FAMILY, NULL);
if (!os)
goto end;
fs = FcFontList(NULL, pat, os);
if (!fs)
goto end;
result = fs->nfont;
NS_ASSERTION(result == 1, "What's this case?");
if (result > 0)
mAliasForSingleFont.AppendCString(aFontName);
else
mNonExistingFonts.AppendCString(aFontName);
end:
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
return result;
}
static PRInt32
@ -406,3 +662,12 @@ gfxPlatformGtk::InitDPI()
}
}
PRBool
gfxFontNameList::Exists(nsAString& aName) {
for (PRUint32 i = 0; i < Length(); i++) {
if (aName.Equals(ElementAt(i)))
return PR_TRUE;
}
return PR_FALSE;
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -132,3 +133,14 @@ gfxPlatformMac::CreateOffscreenSurface(PRUint32 width,
NS_IF_ADDREF(newSurface);
return newSurface;
}
nsresult
gfxPlatformMac::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted)
{
// XXX Implement me with GetFontList!
aAborted = !(*aCallback)(aFontName, aClosure);
return NS_OK;
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -407,7 +408,6 @@ gfxWindowsFont::FillLogFont(PRInt16 currentWeight)
PRBool
gfxWindowsFontGroup::MakeFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure)
{
if (!aName.IsEmpty()) {
@ -436,6 +436,19 @@ gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFo
if (mGenericFamily.IsEmpty())
FindGenericFontFromStyle(MakeFont, this);
if (mFonts.Length() == 0) {
// Should append default GUI font if there are no available fonts.
HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
LOGFONTW logFont;
if (!hGDI ||
!::GetObjectW(hGDI, sizeof(logFont), &logFont)) {
NS_ERROR("Failed to create font group");
return;
}
nsAutoString defaultFont(logFont.lfFaceName);
MakeFont(defaultFont, mGenericFamily, this);
}
}
gfxWindowsFontGroup::~gfxWindowsFontGroup()
@ -966,7 +979,6 @@ public:
static PRBool AddFontCallback(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure) {
if (aName.IsEmpty())
return PR_TRUE;

View File

@ -21,6 +21,7 @@
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
* Vladimir Vukicevic <vladimir@pobox.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -52,6 +53,7 @@ gfxWindowsPlatform::gfxWindowsPlatform()
{
mFonts.Init(200);
mFontWeights.Init(200);
mFontAliases.Init(20);
UpdateFontList();
}
@ -170,6 +172,8 @@ nsresult
gfxWindowsPlatform::UpdateFontList()
{
mFonts.Clear();
mFontAliases.Clear();
mNonExistingFonts.Clear();
LOGFONTW logFont;
logFont.lfCharSet = DEFAULT_CHARSET;
@ -184,6 +188,86 @@ gfxWindowsPlatform::UpdateFontList()
return NS_OK;
}
struct ResolveData {
ResolveData(gfxPlatform::FontResolverCallback aCallback,
gfxWindowsPlatform *aCaller, const nsAString *aFontName,
void *aClosure) :
mFoundCount(0), mCallback(aCallback), mCaller(aCaller),
mFontName(aFontName), mClosure(aClosure) {}
PRUint32 mFoundCount;
gfxPlatform::FontResolverCallback mCallback;
gfxWindowsPlatform *mCaller;
const nsAString *mFontName;
void *mClosure;
};
nsresult
gfxWindowsPlatform::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
PRBool& aAborted)
{
if (aFontName.IsEmpty())
return NS_ERROR_FAILURE;
nsRefPtr<FontEntry> fe;
if (mFonts.Get(aFontName, &fe) || mFontAliases.Get(aFontName, &fe)) {
aAborted = !(*aCallback)(fe->mName, aClosure);
// XXX If the font has font link, we should add the linked font.
return NS_OK;
}
if (mNonExistingFonts.IndexOf(aFontName) >= 0) {
aAborted = PR_FALSE;
return NS_OK;
}
LOGFONTW logFont;
PRInt32 len = aFontName.Length();
if (len >= LF_FACESIZE)
len = LF_FACESIZE - 1;
memcpy(logFont.lfFaceName,
nsPromiseFlatString(aFontName).get(), len * sizeof(PRUnichar));
logFont.lfFaceName[len] = 0;
HDC dc = ::GetDC(nsnull);
ResolveData data(aCallback, this, &aFontName, aClosure);
aAborted =
!EnumFontFamiliesExW(dc, &logFont,
(FONTENUMPROCW)gfxWindowsPlatform::FontResolveProc,
(LPARAM)&data, 0);
if (data.mFoundCount == 0)
mNonExistingFonts.AppendString(aFontName);
::ReleaseDC(nsnull, dc);
return NS_OK;
}
int CALLBACK
gfxWindowsPlatform::FontResolveProc(const ENUMLOGFONTEXW *lpelfe,
const NEWTEXTMETRICEXW *nmetrics,
DWORD fontType, LPARAM data)
{
const LOGFONTW& logFont = lpelfe->elfLogFont;
// Ignore vertical fonts
if (logFont.lfFaceName[0] == L'@' || logFont.lfFaceName[0] == 0)
return 1;
ResolveData *rData = reinterpret_cast<ResolveData*>(data);
rData->mFoundCount++;
nsAutoString name(logFont.lfFaceName);
// Save the alias name to cache
nsRefPtr<FontEntry> fe;
if (rData->mCaller->mFonts.Get(name, &fe))
rData->mCaller->mFontAliases.Put(*(rData->mFontName), fe);
return (rData->mCallback)(name, rData->mClosure);
// XXX If the font has font link, we should add the linked font.
}
struct FontMatch {
FontMatch() : rank(0) {}
PRBool operator <(const FontMatch& other) const { return (rank < other.rank); }

View File

@ -1784,6 +1784,8 @@ pref("intl.font_charset", "");
pref("intl.font_spec_list", "");
pref("mail.signature_date", 0);
pref("font.alias-list", "sans,sans-serif,serif,monospace");
pref("font.default.ar", "sans-serif");
pref("font.size.variable.ar", 16);
pref("font.size.fixed.ar", 13);
@ -1941,6 +1943,8 @@ pref("print.whileInPrintPreview", false);
pref("font.allow_double_byte_special_chars", true);
// font names
pref("font.alias-list", "sans,sans-serif,serif,monospace");
// ar
#ifdef MOZ_ENABLE_XFT