diff --git a/gfx/src/os2/nsFontMetricsOS2.cpp b/gfx/src/os2/nsFontMetricsOS2.cpp index 8f2c2a587ea0..f0e606fa1a5b 100644 --- a/gfx/src/os2/nsFontMetricsOS2.cpp +++ b/gfx/src/os2/nsFontMetricsOS2.cpp @@ -70,6 +70,7 @@ static nsICharsetConverterManager2 *gCharsetManager = nsnull; #endif static nsIPref *gPref = nsnull; static nsIAtom *gUsersLocale = nsnull; +static nsIAtom *gSystemLocale = nsnull; static nsIAtom *gUserDefined = nsnull; #ifdef WINCODE static nsIUnicodeEncoder *gUserDefinedConverter = nsnull; @@ -279,6 +280,7 @@ FreeGlobals(void) #endif NS_IF_RELEASE(gPref); NS_IF_RELEASE(gUsersLocale); + NS_IF_RELEASE(gSystemLocale); NS_IF_RELEASE(gUserDefined); #ifdef WINCODE NS_IF_RELEASE(gUserDefinedConverter); @@ -351,6 +353,20 @@ InitGlobals(void) return NS_ERROR_OUT_OF_MEMORY; } + if (!gSystemLocale) { + UINT cp = WinQueryCp(HMQ_CURRENT); + for (int i = 1; i < eCharset_COUNT; ++i) { + if (gCharsetInfo[i].mCodePage == cp) { + gSystemLocale = NS_NewAtom(gCharsetInfo[i].mLangGroup); + break; + } + } + } + if (!gSystemLocale) { + gSystemLocale = gUsersLocale; + NS_ADDREF(gSystemLocale); + } + gUserDefined = NS_NewAtom(USER_DEFINED); if (!gUserDefined) { FreeGlobals(); @@ -949,6 +965,41 @@ GenericFontEnumCallback(const nsString& aFamily, PRBool aGeneric, void* aData) _pref.Assign(_s0); \ _pref.Append(_s1); +static void +AppendGenericFontFromPref(nsString& aFontname, + const char* aLangGroup, + const char* aGeneric) +{ + nsresult res; + nsCAutoString pref; + nsXPIDLString value; + nsCAutoString generic_dot_langGroup; + + generic_dot_langGroup.Assign(aGeneric); + generic_dot_langGroup.Append('.'); + generic_dot_langGroup.Append(aLangGroup); + + // font.name.[generic].[langGroup] + // the current user' selected font, it gives the first preferred font + MAKE_FONT_PREF_KEY(pref, "font.name.", generic_dot_langGroup); + res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); + if (NS_SUCCEEDED(res)) { + if(aFontname.Length() > 0) + aFontname.Append((PRUnichar)','); + aFontname.Append(value); + } + + // font.name-list.[generic].[langGroup] + // the pre-built list of default fonts, it gives alternative fonts + MAKE_FONT_PREF_KEY(pref, "font.name-list.", generic_dot_langGroup); + res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); + if (NS_SUCCEEDED(res)) { + if(aFontname.Length() > 0) + aFontname.Append((PRUnichar)','); + aFontname.Append(value); + } +} + nsFontOS2* nsFontMetricsOS2::FindGenericFont( HDC aPS ) { @@ -956,68 +1007,16 @@ nsFontMetricsOS2::FindGenericFont( HDC aPS ) return nsnull; } - nsAutoString langGroup; - nsCAutoString generic_dot_langGroup; - // This is a nifty hook that we will use to just iterate over // the list of names using the callback mechanism of nsFont... nsFont font("", 0, 0, 0, 0, 0); - nsresult res; - nsCAutoString pref; - nsXPIDLString value; - - // Get the fonts in the element's language group - // . font.name.[generic].[langGroup] - // . font.name-list.[generic].[langGroup] - if (mLangGroup) { + nsAutoString langGroup; mLangGroup->ToString(langGroup); - generic_dot_langGroup.Assign(NS_ConvertUCS2toUTF8(mGeneric)); - generic_dot_langGroup.Append('.'); - generic_dot_langGroup.Append(NS_ConvertUCS2toUTF8(langGroup)); - - // font.name.[generic].[langGroup] - // the current user' selected font, it gives the first preferred font - MAKE_FONT_PREF_KEY(pref, "font.name.", generic_dot_langGroup); - res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); - if (NS_SUCCEEDED(res)) { - font.name.Assign(value); - } - - // font.name-list.[generic].[langGroup] - // the pre-built list of default fonts, it gives alternative fonts - MAKE_FONT_PREF_KEY(pref, "font.name-list.", generic_dot_langGroup); - res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); - if (NS_SUCCEEDED(res)) { - font.name.Append((PRUnichar)','); - font.name.Append(value); - } - } - - // Get extra alternative fonts in the user's locale's language group - // . font.name.[generic].[locale's langGroup] - // . font.name-list.[generic].[locale's langGroup] - - if (gUsersLocale != mLangGroup) { - gUsersLocale->ToString(langGroup); - generic_dot_langGroup.Assign(NS_ConvertUCS2toUTF8(mGeneric)); - generic_dot_langGroup.Append('.'); - generic_dot_langGroup.Append(NS_ConvertUCS2toUTF8(langGroup)); - - MAKE_FONT_PREF_KEY(pref, "font.name.", generic_dot_langGroup); - res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); - if (NS_SUCCEEDED(res)) { - font.name.Append((PRUnichar)','); - font.name.Append(value); - } - - MAKE_FONT_PREF_KEY(pref, "font.name-list.", generic_dot_langGroup); - res = gPref->CopyUnicharPref(pref.get(), getter_Copies(value)); - if (NS_SUCCEEDED(res)) { - font.name.Append((PRUnichar)','); - font.name.Append(value); - } + AppendGenericFontFromPref(font.name, + NS_ConvertUCS2toUTF8(langGroup).get(), + NS_ConvertUCS2toUTF8(mGeneric).get()); } // Iterate over the list of names using the callback mechanism of nsFont... @@ -1031,6 +1030,58 @@ nsFontMetricsOS2::FindGenericFont( HDC aPS ) return nsnull; } +nsFontOS2* +nsFontMetricsOS2::FindPrefFont(HPS aPS) +{ +#ifdef WINCODE + if (mTriedAllPref) { + // don't bother anymore because mLoadedFonts[] already has all our pref fonts + return nsnull; + } +#endif + nsFont font("", 0, 0, 0, 0, 0); + // Try the pref of the user's ui lang group + // For example, if the ui language is Japanese, try pref from "ja" + // Make localized build work better on other OS + if (gUsersLocale != mLangGroup) { + nsAutoString langGroup; + gUsersLocale->ToString(langGroup); + AppendGenericFontFromPref(font.name, + NS_ConvertUCS2toUTF8(langGroup).get(), + NS_ConvertUCS2toUTF8(mGeneric).get()); + } + // Try the pref of the user's system lang group + // For example, if the os language is Simplified Chinese, + // try pref from "zh-CN" + // Make English build work better on other OS + if ((gSystemLocale != mLangGroup) && (gSystemLocale != gUsersLocale)) { + nsAutoString langGroup; + gSystemLocale->ToString(langGroup); + AppendGenericFontFromPref(font.name, + NS_ConvertUCS2toUTF8(langGroup).get(), + NS_ConvertUCS2toUTF8(mGeneric).get()); + } + + // Also try all the default pref fonts enlisted from other languages + for (int i = 1; i < eCharset_COUNT; ++i) { + nsIAtom* langGroup = NS_NewAtom(gCharsetInfo[i].mLangGroup); + if((gUsersLocale != langGroup) && (gSystemLocale != langGroup)) { + AppendGenericFontFromPref(font.name, gCharsetInfo[i].mLangGroup, + NS_ConvertUCS2toUTF8(mGeneric).get()); + } + NS_IF_RELEASE(langGroup); + } + GenericFontEnumContext context = {aPS, nsnull, this}; + font.EnumerateFamilies(GenericFontEnumCallback, &context); + if (context.mFont) { // a suitable font was found + return context.mFont; + } +#ifdef WINCODE + mTriedAllPref = 1; +#endif + return nsnull; +} + // returns family name of font that can display given char nsFontOS2* nsFontMetricsOS2::FindFont( HPS aPS ) @@ -1041,7 +1092,10 @@ nsFontMetricsOS2::FindFont( HPS aPS ) if (!font) { font = FindGenericFont(aPS); if (!font) { - font = FindGlobalFont(aPS); + font = FindPrefFont(aPS); + if (!font) { + font = FindGlobalFont(aPS); + } } } } @@ -1537,7 +1591,7 @@ nsFontMetricsOS2::ResolveForwards(HPS aPS, void* aData) { NS_ASSERTION(aString || !aLength, "invalid call"); - PRBool running; + PRBool running = PR_TRUE; const PRUnichar* firstChar = aString; const PRUnichar* lastChar = aString + aLength; const PRUnichar* currChar = firstChar; @@ -1547,7 +1601,7 @@ nsFontMetricsOS2::ResolveForwards(HPS aPS, if( mCodePage == 1252 ) { - while( firstChar < lastChar ) + while( running && firstChar < lastChar ) { if( *currChar > 0x00FF ) { @@ -1582,7 +1636,7 @@ nsFontMetricsOS2::ResolveForwards(HPS aPS, } else { - while( firstChar < lastChar ) + while( running && firstChar < lastChar ) { if( *currChar >= 0x0080 && *currChar <= 0x00FF ) { @@ -1628,7 +1682,7 @@ nsFontMetricsOS2::ResolveBackwards(HPS aPS, void* aData) { NS_ASSERTION(aString || !aLength, "invalid call"); - PRBool running; + PRBool running = PR_TRUE; const PRUnichar* firstChar = aString + aLength - 1; const PRUnichar* lastChar = aString - 1; const PRUnichar* currChar = firstChar; @@ -1638,7 +1692,7 @@ nsFontMetricsOS2::ResolveBackwards(HPS aPS, if( mCodePage == 1252 ) { - while( firstChar > lastChar ) + while( running && firstChar > lastChar ) { if( *currChar > 0x00FF ) { @@ -1673,7 +1727,7 @@ nsFontMetricsOS2::ResolveBackwards(HPS aPS, } else { - while( firstChar > lastChar ) + while( running && firstChar > lastChar ) { if( *currChar >= 0x0080 && *currChar <= 0x00FF ) { diff --git a/gfx/src/os2/nsFontMetricsOS2.h b/gfx/src/os2/nsFontMetricsOS2.h index f0009dd91c6b..1ef560b32f93 100644 --- a/gfx/src/os2/nsFontMetricsOS2.h +++ b/gfx/src/os2/nsFontMetricsOS2.h @@ -179,6 +179,7 @@ class nsFontMetricsOS2 : public nsIFontMetrics nsFontOS2* FindFont( HPS aPS ); nsFontOS2* FindGlobalFont( HPS aPS ); nsFontOS2* FindGenericFont( HPS aPS ); + nsFontOS2* FindPrefFont( HPS aPS ); nsFontOS2* FindLocalFont( HPS aPS ); nsFontOS2* FindUserDefinedFont( HPS aPS ); nsFontOS2* LoadFont (HPS aPS, nsString* aName ); diff --git a/gfx/src/os2/nsRenderingContextOS2.cpp b/gfx/src/os2/nsRenderingContextOS2.cpp index c76a95a19847..147fa193f22f 100644 --- a/gfx/src/os2/nsRenderingContextOS2.cpp +++ b/gfx/src/os2/nsRenderingContextOS2.cpp @@ -1477,7 +1477,7 @@ nsRenderingContextOS2::GetTextDimensions(const char* aString, // Find the nearest place to break that is less than or equal to // the estimated break offset - if (aLength < estimatedBreakOffset) { + if (aLength <= estimatedBreakOffset) { // All the characters should fit numChars = aLength - start; breakIndex = aNumBreaks - 1;