mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
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:
parent
35f55ae89a
commit
2d15463f40
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
gfxPlatform::FontResolverCallback aCallback,
|
||||
void *aClosure, PRBool& aAborted);
|
||||
|
||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||
|
||||
protected:
|
||||
static gfxFontconfigUtils* sUtils;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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(); }
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user