зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
7fa2400b0e
Коммит
47c43f3950
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче