Bug 390901 CJK - font-name is not recognised correctly in preferences p=me+jdagett(mac part)+kerlt(fontconfig part) r=jdagett+me+stuart+mconnor b1.9=stuart

This commit is contained in:
masayuki@d-toybox.com 2008-03-13 03:32:50 -07:00
parent eecf0ccd4b
commit 75cfe2466f
21 changed files with 278 additions and 17 deletions

View File

@ -186,7 +186,7 @@ var gContentPane = {
const kFontSizeFmtVariable = "font.size.variable.%LANG%";
var prefs = [{ format : aIsSerif ? kFontNameFmtSerif : kFontNameFmtSansSerif,
type : "unichar",
type : "fontname",
element : "defaultFont",
fonttype : aIsSerif ? "serif" : "sans-serif" },
{ format : aIsSerif ? kFontNameListFmtSerif : kFontNameListFmtSansSerif,

View File

@ -53,16 +53,16 @@ const kFontMinSizeFmt = "font.minimum-size.%LANG%";
var gFontsDialog = {
_selectLanguageGroup: function (aLanguageGroup)
{
var prefs = [{ format: kDefaultFontType, type: "string", element: "defaultFontType", fonttype: null},
{ format: kFontNameFmtSerif, type: "unichar", element: "serif", fonttype: "serif" },
{ format: kFontNameFmtSansSerif, type: "unichar", element: "sans-serif", fonttype: "sans-serif" },
{ format: kFontNameFmtMonospace, type: "unichar", element: "monospace", fonttype: "monospace" },
{ format: kFontNameListFmtSerif, type: "unichar", element: null, fonttype: "serif" },
{ format: kFontNameListFmtSansSerif, type: "unichar", element: null, fonttype: "sans-serif" },
{ format: kFontNameListFmtMonospace, type: "unichar", element: null, fonttype: "monospace" },
{ format: kFontSizeFmtVariable, type: "int", element: "sizeVar", fonttype: null },
{ format: kFontSizeFmtFixed, type: "int", element: "sizeMono", fonttype: null },
{ format: kFontMinSizeFmt, type: "int", element: "minSize", fonttype: null }];
var prefs = [{ format: kDefaultFontType, type: "string", element: "defaultFontType", fonttype: null},
{ format: kFontNameFmtSerif, type: "fontname", element: "serif", fonttype: "serif" },
{ format: kFontNameFmtSansSerif, type: "fontname", element: "sans-serif", fonttype: "sans-serif" },
{ format: kFontNameFmtMonospace, type: "fontname", element: "monospace", fonttype: "monospace" },
{ format: kFontNameListFmtSerif, type: "unichar", element: null, fonttype: "serif" },
{ format: kFontNameListFmtSansSerif, type: "unichar", element: null, fonttype: "sans-serif" },
{ format: kFontNameListFmtMonospace, type: "unichar", element: null, fonttype: "monospace" },
{ format: kFontSizeFmtVariable, type: "int", element: "sizeVar", fonttype: null },
{ format: kFontSizeFmtFixed, type: "int", element: "sizeMono", fonttype: null },
{ format: kFontMinSizeFmt, type: "int", element: "minSize", fonttype: null }];
var preferences = document.getElementById("fontPreferences");
for (var i = 0; i < prefs.length; ++i) {
var preference = document.getElementById(prefs[i].format.replace(/%LANG%/, aLanguageGroup));

View File

@ -39,7 +39,7 @@
#include "nsISupports.idl"
[scriptable, uuid(a6cf9114-15b3-11d2-932e-00805f8add32)]
[scriptable, uuid(924d98d9-3518-4cb4-8708-c74fe8e3ec3c)]
interface nsIFontEnumerator : nsISupports
{
/**
@ -83,4 +83,12 @@ interface nsIFontEnumerator : nsISupports
* return true if font list is changed
*/
boolean updateFontList();
/**
* get the standard family name on the system from given family
* @param aName family name which may be alias
* @return the standard family name on the system, if given name does not
* exist, returns empty string
*/
wstring getStandardFamilyName(in wstring aName);
};

View File

@ -128,3 +128,27 @@ nsThebesFontEnumerator::UpdateFontList(PRBool *_retval)
*_retval = PR_FALSE; // always return false for now
return NS_OK;
}
NS_IMETHODIMP
nsThebesFontEnumerator::GetStandardFamilyName(const PRUnichar *aName,
PRUnichar **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_ARG_POINTER(aName);
nsAutoString name(aName);
if (name.IsEmpty()) {
*aResult = nsnull;
return NS_OK;
}
nsAutoString family;
nsresult rv = gfxPlatform::GetPlatform()->
GetStandardFamilyName(nsDependentString(aName), family);
if (NS_FAILED(rv) || family.IsEmpty()) {
*aResult = nsnull;
return NS_OK;
}
*aResult = ToNewUnicode(family);
return NS_OK;
}

View File

@ -20,7 +20,6 @@
* 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
@ -67,6 +66,8 @@ public:
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
protected:
static gfxFontconfigUtils *sFontconfigUtils;
};

View File

@ -66,6 +66,7 @@ public:
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle);

View File

@ -169,6 +169,12 @@ public:
void *aClosure,
PRBool& aAborted) = 0;
/**
* Resolving a font name to family name. The result MUST be in the result of GetFontList().
* If the name doesn't in the system, aFamilyName will be empty string, but not failed.
*/
virtual nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) = 0;
/**
* Create the appropriate platform font group
*/

View File

@ -67,6 +67,8 @@ public:
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle);

View File

@ -60,6 +60,8 @@ public:
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle);

View File

@ -69,6 +69,8 @@ public:
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle);

View File

@ -109,3 +109,9 @@ gfxBeOSPlatform::ResolveFontName(const nsAString& aFontName,
return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
aClosure, aAborted);
}
nsresult
gfxBeOSPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
}

View File

@ -368,6 +368,115 @@ gfxFontconfigUtils::GetResolvedFonts(const nsACString& aName,
return rv;
}
nsresult
gfxFontconfigUtils::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
aFamilyName.Truncate();
// The fontconfig has generic family names in the font list.
if (aFontName.EqualsLiteral("serif") ||
aFontName.EqualsLiteral("sans-serif") ||
aFontName.EqualsLiteral("monospace")) {
aFamilyName.Assign(aFontName);
return NS_OK;
}
NS_ConvertUTF16toUTF8 fontname(aFontName);
if (mFonts.IndexOf(fontname) >= 0) {
aFamilyName.Assign(aFontName);
return NS_OK;
}
if (mNonExistingFonts.IndexOf(fontname) >= 0)
return NS_OK;
FcPattern *pat = NULL;
FcObjectSet *os = NULL;
FcFontSet *givenFS = NULL;
nsCStringArray candidates;
FcFontSet *candidateFS = NULL;
nsresult rv = NS_ERROR_FAILURE;
pat = FcPatternCreate();
if (!pat)
goto end;
FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)fontname.get());
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, NULL);
if (!os)
goto end;
givenFS = FcFontList(NULL, pat, os);
if (!givenFS)
goto end;
// The first value associated with a FC_FAMILY property is the family
// returned by GetFontList(), so use this value if appropriate.
// See if there is a font face with first family equal to the given family.
for (int i = 0; i < givenFS->nfont; ++i) {
char *firstFamily;
if (FcPatternGetString(givenFS->fonts[i], FC_FAMILY, 0,
(FcChar8 **) &firstFamily) != FcResultMatch)
continue;
nsDependentCString first(firstFamily);
if (candidates.IndexOf(first) < 0) {
candidates.AppendCString(first);
if (fontname.Equals(first)) {
aFamilyName.Assign(aFontName);
rv = NS_OK;
goto end;
}
}
}
// See if any of the first family names represent the same set of font
// faces as the given family.
for (PRInt32 j = 0; j < candidates.Count(); ++j) {
FcPatternDel(pat, FC_FAMILY);
FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)candidates[j]->get());
candidateFS = FcFontList(NULL, pat, os);
if (!candidateFS)
goto end;
if (candidateFS->nfont != givenFS->nfont)
continue;
PRBool equal = PR_TRUE;
for (int i = 0; i < givenFS->nfont; ++i) {
if (!FcPatternEqual(candidateFS->fonts[i], givenFS->fonts[i])) {
equal = PR_FALSE;
break;
}
}
if (equal) {
AppendUTF8toUTF16(*candidates[j], aFamilyName);
rv = NS_OK;
goto end;
}
}
// No match found; return empty string.
rv = NS_OK;
end:
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (givenFS)
FcFontSetDestroy(givenFS);
if (candidateFS)
FcFontSetDestroy(candidateFS);
return rv;
}
nsresult
gfxFontconfigUtils::ResolveFontName(const nsAString& aFontName,
gfxPlatform::FontResolverCallback aCallback,

View File

@ -75,6 +75,8 @@ public:
gfxPlatform::FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
protected:
static gfxFontconfigUtils* sUtils;

View File

@ -147,6 +147,12 @@ gfxOS2Platform::ResolveFontName(const nsAString& aFontName,
//return NS_OK;
}
nsresult
gfxOS2Platform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
}
gfxFontGroup *
gfxOS2Platform::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle)

View File

@ -253,6 +253,12 @@ gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
aClosure, aAborted);
}
nsresult
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
}
gfxFontGroup *
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle)

View File

@ -180,6 +180,13 @@ gfxPlatformMac::ResolveFontName(const nsAString& aFontName,
return NS_OK;
}
nsresult
gfxPlatformMac::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
gfxQuartzFontCache::SharedFontCache()->GetStandardFamilyName(aFontName, aFamilyName);
return NS_OK;
}
gfxFontGroup *
gfxPlatformMac::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle)

View File

@ -128,7 +128,7 @@ public:
virtual ~MacOSFamilyEntry() {}
const nsString& Name() { return mName; }
virtual void LocalizedName(nsString& aLocalizedName);
virtual void LocalizedName(nsAString& aLocalizedName);
virtual PRBool HasOtherFamilyNames();
nsTArray<nsRefPtr<MacOSFontEntry> >& GetFontList() { return mAvailableFonts; }
@ -182,7 +182,7 @@ public:
virtual ~SingleFaceFamily() {}
virtual void LocalizedName(nsString& aLocalizedName);
virtual void LocalizedName(nsAString& aLocalizedName);
// read in other family names, if any, and use functor to add each into cache
virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor);
@ -213,6 +213,7 @@ public:
nsStringArray& aListOfFonts);
PRBool ResolveFontName(const nsAString& aFontName,
nsAString& aResolvedFontName);
PRBool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
void UpdateFontList() { InitFontList(); }

View File

@ -256,7 +256,7 @@ public:
gfxQuartzFontCache *mFontCache;
};
void MacOSFamilyEntry::LocalizedName(nsString& aLocalizedName)
void MacOSFamilyEntry::LocalizedName(nsAString& aLocalizedName)
{
// no other names ==> only one name, just return it
if (!HasOtherFamilyNames()) {
@ -656,7 +656,7 @@ MacOSFamilyEntry::ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFu
/* SingleFaceFamily */
#pragma mark-
void SingleFaceFamily::LocalizedName(nsString& aLocalizedName)
void SingleFaceFamily::LocalizedName(nsAString& aLocalizedName)
{
MacOSFontEntry *fontEntry;
@ -973,6 +973,57 @@ gfxQuartzFontCache::ResolveFontName(const nsAString& aFontName, nsAString& aReso
return PR_FALSE;
}
PRBool
gfxQuartzFontCache::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
MacOSFamilyEntry *family = FindFamily(aFontName);
if (family) {
family->LocalizedName(aFamilyName);
return PR_TRUE;
}
// Gecko 1.8 used Quickdraw font api's which produce a slightly different set of "family"
// names. Try to resolve based on these names, in case this is stored in an old profile
// 1.8: "Futura", "Futura Condensed" ==> 1.9: "Futura
FMFont fmFont;
// convert of a NSString
NSString *fontName = GetNSStringForString(aFontName);
// name ==> family id ==> old-style FMFont
ATSFontFamilyRef fmFontFamily = ATSFontFamilyFindFromName((CFStringRef)fontName, kATSOptionFlagsDefault);
OSStatus err = FMGetFontFromFontFamilyInstance(fmFontFamily, 0, &fmFont, nsnull);
if (err != noErr || fmFont == kInvalidFont)
return PR_FALSE;
ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont);
if (!atsFont)
return PR_FALSE;
NSString *psname;
// now lookup the Postscript name
err = ATSFontGetPostScriptName(atsFont, kATSOptionFlagsDefault, (CFStringRef*) (&psname));
if (err != noErr)
return PR_FALSE;
// given an NSFont instance, Cocoa api's return the canonical family name
NSString *canonicalfamily = [[NSFont fontWithName:psname size:0.0] familyName];
[psname release];
nsAutoString familyName;
// lookup again using the canonical family name
GetStringForNSString(canonicalfamily, familyName);
family = FindFamily(familyName);
if (family) {
family->LocalizedName(aFamilyName);
return PR_TRUE;
}
return PR_FALSE;
}
void
gfxQuartzFontCache::ATSNotification(ATSFontNotificationInfoRef aInfo,
void* aUserArg)

View File

@ -395,6 +395,14 @@ gfxWindowsPlatform::InitBadUnderlineList()
}
}
nsresult
gfxWindowsPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
aFamilyName.Truncate();
PRBool aborted;
return ResolveFontName(aFontName, SimpleResolverCallback, &aFamilyName, aborted);
}
struct ResolveData {
ResolveData(gfxPlatform::FontResolverCallback aCallback,
gfxWindowsPlatform *aCaller, const nsAString *aFontName,

View File

@ -293,6 +293,11 @@
return this._branch
.getComplexValue(this.name, Components.interfaces.nsISupportsString)
.data;
case "fontname":
var family = this._branch
.getComplexValue(this.name, Components.interfaces.nsISupportsString)
.data;
return FontBuilder.enumerator.getStandardFamilyName(family);
case "file":
var f = this._branch
.getComplexValue(this.name, Components.interfaces.nsILocalFile);
@ -327,6 +332,7 @@
break;
case "string":
case "unichar":
case "fontname":
var iss = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
iss.data = val;

View File

@ -116,5 +116,18 @@ var FontBuilder = {
}
}
aMenuList.appendChild(popup);
},
getStandardFamilyName: function (aName)
{
// XXX should return empty string on failure?
try {
var family = this.enumerator.getStandardFamilyName(aName);
if (!family)
return aName;
return family;
} catch (e) {
return aName;
}
}
};