mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-02 12:07:52 +00:00
bug 21352; was crashing on Japanese Win95 since we didn't keep our
subclass for that platform in sync with the base class; r=ftang a=chofmann
This commit is contained in:
parent
607109cab2
commit
a3cb05fd7a
@ -78,6 +78,11 @@ nsFontMetricsWin :: ~nsFontMetricsWin()
|
||||
}
|
||||
|
||||
mDeviceContext = nsnull;
|
||||
|
||||
if (mGeneric) {
|
||||
delete mGeneric;
|
||||
mGeneric = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LEAK_DEBUG
|
||||
@ -1464,7 +1469,7 @@ nsFontMetricsWin::InitializeFamilyNames(void)
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar, nsString** aGeneric)
|
||||
nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
{
|
||||
if (!gFamilyNames) {
|
||||
if (!InitializeFamilyNames()) {
|
||||
@ -1478,8 +1483,7 @@ nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar, nsString** aGeneric)
|
||||
low->ToLowerCase();
|
||||
nsString* winName = (nsString*) PL_HashTableLookup(gFamilyNames, low);
|
||||
if (winName == gGeneric) {
|
||||
mFontsIndex--; // causes us to look for generic next time too
|
||||
*aGeneric = low;
|
||||
mGeneric = low;
|
||||
return nsnull;
|
||||
}
|
||||
else if (!winName) {
|
||||
@ -1500,6 +1504,20 @@ nsFontWin*
|
||||
nsFontMetricsWin::LoadGenericFont(HDC aDC, PRUnichar aChar, char** aName)
|
||||
{
|
||||
if (*aName) {
|
||||
int found = 0;
|
||||
int i;
|
||||
for (i = 0; i < mLoadedFontsCount; i++) {
|
||||
nsFontWin* font = mLoadedFonts[i];
|
||||
if (!strcmp(font->mName, *aName)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
nsAllocator::Free(*aName);
|
||||
*aName = nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
PRUnichar name[LF_FACESIZE] = { 0 };
|
||||
PRUnichar format[] = { '%', 's', 0 };
|
||||
PRUint32 n = nsTextFormater::snprintf(name, LF_FACESIZE, format, *aName);
|
||||
@ -1556,7 +1574,7 @@ PrefEnumCallback(const char* aName, void* aClosure)
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar, nsString* aGeneric)
|
||||
nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar)
|
||||
{
|
||||
if (!gPref) {
|
||||
nsServiceManager::GetService(kPrefCID,
|
||||
@ -1565,9 +1583,12 @@ nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar, nsString* aGeneric)
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
if (mTriedAllGenerics) {
|
||||
return nsnull;
|
||||
}
|
||||
nsAutoString prefix("font.name.");
|
||||
if (aGeneric) {
|
||||
prefix.Append(*aGeneric);
|
||||
if (mGeneric) {
|
||||
prefix.Append(*mGeneric);
|
||||
}
|
||||
else {
|
||||
prefix.Append("serif");
|
||||
@ -1598,6 +1619,7 @@ nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar, nsString* aGeneric)
|
||||
if (info.mFont) {
|
||||
return info.mFont;
|
||||
}
|
||||
mTriedAllGenerics = 1;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
@ -1605,17 +1627,13 @@ nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar, nsString* aGeneric)
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindFont(HDC aDC, PRUnichar aChar)
|
||||
{
|
||||
nsString* generic = nsnull;
|
||||
nsFontWin* font = FindLocalFont(aDC, aChar, &generic);
|
||||
nsFontWin* font = FindLocalFont(aDC, aChar);
|
||||
if (!font) {
|
||||
font = FindGenericFont(aDC, aChar, generic);
|
||||
font = FindGenericFont(aDC, aChar);
|
||||
if (!font) {
|
||||
font = FindGlobalFont(aDC, aChar);
|
||||
}
|
||||
}
|
||||
if (generic) {
|
||||
delete generic;
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
@ -1840,7 +1858,9 @@ nsFontMetricsWin::GetFontHandle(nsFontHandle &aHandle)
|
||||
|
||||
nsFontWin::nsFontWin(LOGFONT* aLogFont, HFONT aFont, PRUint8* aMap)
|
||||
{
|
||||
strcpy(mName, aLogFont->lfFaceName);
|
||||
if (aLogFont) {
|
||||
strcpy(mName, aLogFont->lfFaceName);
|
||||
}
|
||||
mFont = aFont;
|
||||
mMap = aMap;
|
||||
}
|
||||
@ -2552,21 +2572,34 @@ nsFontWinA::GetSubsets(HDC aDC)
|
||||
}
|
||||
}
|
||||
|
||||
mSubsets = (nsFontSubset*) PR_Calloc(mSubsetsCount, sizeof(nsFontSubset));
|
||||
mSubsets = (nsFontSubset**) PR_Calloc(mSubsetsCount, sizeof(nsFontSubset*));
|
||||
if (!mSubsets) {
|
||||
mSubsetsCount = 0;
|
||||
return 0;
|
||||
}
|
||||
int j;
|
||||
for (j = 0; j < mSubsetsCount; j++) {
|
||||
mSubsets[j] = new nsFontSubset();
|
||||
if (!mSubsets[j]) {
|
||||
for (j = j - 1; j >= 0; j--) {
|
||||
delete mSubsets[j];
|
||||
}
|
||||
PR_Free(mSubsets);
|
||||
mSubsets = nsnull;
|
||||
mSubsetsCount = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
int j = 0;
|
||||
j = 0;
|
||||
for (dword = 0; dword < 2; dword++) {
|
||||
for (int bit = 0; bit < sizeof(DWORD) * 8; bit++) {
|
||||
if ((array[dword] >> bit) & 1) {
|
||||
PRUint8 charSet = bitToCharSet[i];
|
||||
if (charSet != DEFAULT_CHARSET) {
|
||||
if (HaveConverterFor(charSet)) {
|
||||
mSubsets[j].mCharSet = charSet;
|
||||
mSubsets[j]->mCharSet = charSet;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@ -2578,53 +2611,85 @@ nsFontWinA::GetSubsets(HDC aDC)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeFont(nsFontWinA* aFont)
|
||||
nsFontSubset::nsFontSubset()
|
||||
: nsFontWin(nsnull, nsnull, nsnull)
|
||||
{
|
||||
nsFontSubset* subset = aFont->mSubsets;
|
||||
nsFontSubset* endSubsets = &(aFont->mSubsets[aFont->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (subset->mFont) {
|
||||
::DeleteObject(subset->mFont);
|
||||
}
|
||||
if (subset->mMap) {
|
||||
PR_Free(subset->mMap);
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
PR_Free(aFont->mSubsets);
|
||||
if (aFont->mFont) {
|
||||
::DeleteObject(aFont->mFont);
|
||||
}
|
||||
delete aFont;
|
||||
}
|
||||
|
||||
nsFontMetricsWinA::~nsFontMetricsWinA()
|
||||
nsFontSubset::~nsFontSubset()
|
||||
{
|
||||
if (nsnull != mFont) {
|
||||
delete mFont;
|
||||
mFont = nsnull;
|
||||
if (mMap) {
|
||||
PR_Free(mMap);
|
||||
mMap = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsFontSubset::GetWidth(HDC aDC, const PRUnichar* aString, PRUint32 aLength)
|
||||
{
|
||||
// XXX allocate on heap if string is too long
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(mCodePage, 0, aString, aLength, str,
|
||||
sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::SelectObject(aDC, mFont);
|
||||
SIZE size;
|
||||
::GetTextExtentPoint32A(aDC, str, len, &size);
|
||||
return size.cx;
|
||||
}
|
||||
|
||||
mFontHandle = nsnull; // released below
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mFonts) {
|
||||
delete [] mFonts;
|
||||
mFonts = nsnull;
|
||||
void
|
||||
nsFontSubset::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength)
|
||||
{
|
||||
// XXX allocate on heap if string is too long
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(mCodePage, 0, aString, aLength, str,
|
||||
sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::SelectObject(aDC, mFont);
|
||||
::ExtTextOutA(aDC, aX, aY, 0, NULL, str, len, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (mLoadedFonts) {
|
||||
nsFontWinA** font = (nsFontWinA**) mLoadedFonts;
|
||||
nsFontWinA** end = (nsFontWinA**) &mLoadedFonts[mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
FreeFont(*font);
|
||||
font++;
|
||||
nsFontWinA::nsFontWinA(LOGFONT* aLogFont, HFONT aFont, PRUint8* aMap)
|
||||
: nsFontWin(aLogFont, aFont, aMap)
|
||||
{
|
||||
NS_ASSERTION(aLogFont, "must pass LOGFONT here");
|
||||
if (aLogFont) {
|
||||
mLogFont = *aLogFont;
|
||||
}
|
||||
}
|
||||
|
||||
nsFontWinA::~nsFontWinA()
|
||||
{
|
||||
if (mSubsets) {
|
||||
nsFontSubset** subset = mSubsets;
|
||||
nsFontSubset** endSubsets = &mSubsets[mSubsetsCount];
|
||||
while (subset < endSubsets) {
|
||||
delete *subset;
|
||||
subset++;
|
||||
}
|
||||
PR_Free(mLoadedFonts);
|
||||
mLoadedFonts = nsnull;
|
||||
PR_Free(mSubsets);
|
||||
mSubsets = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
mDeviceContext = nsnull;
|
||||
PRInt32
|
||||
nsFontWinA::GetWidth(HDC aDC, const PRUnichar* aString, PRUint32 aLength)
|
||||
{
|
||||
NS_ASSERTION(0, "must call nsFontSubset's GetWidth");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsFontWinA::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength)
|
||||
{
|
||||
NS_ASSERTION(0, "must call nsFontSubset's DrawString");
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
@ -2636,9 +2701,19 @@ nsFontMetricsWinA::LoadFont(HDC aDC, nsString* aName)
|
||||
PRInt32 weight = GetFontWeight(mFont->weight, weightTable);
|
||||
FillLogFont(&logFont, weight);
|
||||
|
||||
// XXX need to preserve Unicode chars in face name (use LOGFONTW) -- erik
|
||||
aName->ToCString(logFont.lfFaceName, LF_FACESIZE);
|
||||
/*
|
||||
* XXX we are losing info by converting from Unicode to system code page
|
||||
* but we don't really have a choice since CreateFontIndirectW is
|
||||
* not supported on Windows 9X (see below) -- erik
|
||||
*/
|
||||
logFont.lfFaceName[0] = 0;
|
||||
WideCharToMultiByte(CP_ACP, 0, aName->GetUnicode(), aName->Length() + 1,
|
||||
logFont.lfFaceName, sizeof(logFont.lfFaceName), nsnull, nsnull);
|
||||
|
||||
/*
|
||||
* According to http://msdn.microsoft.com/library/
|
||||
* CreateFontIndirectW is only supported on NT/2000
|
||||
*/
|
||||
HFONT hfont = ::CreateFontIndirect(&logFont);
|
||||
|
||||
if (hfont) {
|
||||
@ -2655,34 +2730,39 @@ nsFontMetricsWinA::LoadFont(HDC aDC, nsString* aName)
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
nsFontWinA* font = new nsFontWinA;
|
||||
if (!font) {
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, (HGDIOBJ) hfont);
|
||||
char name[sizeof(logFont.lfFaceName)];
|
||||
if ((!::GetTextFace(aDC, sizeof(name), name)) ||
|
||||
strcmp(name, logFont.lfFaceName)) {
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
PRUint8* map = GetCMAP(aDC, logFont.lfFaceName, nsnull);
|
||||
if (!map) {
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
nsFontWinA* font = new nsFontWinA(&logFont, hfont, map);
|
||||
if (!font) {
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
mLoadedFonts[mLoadedFontsCount++] = (nsFontWin*) font;
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, (HGDIOBJ) hfont);
|
||||
font->mFont = hfont;
|
||||
font->mLogFont = logFont;
|
||||
#ifdef DEBUG_FONT_SIGNATURE
|
||||
printf("%s\n", logFont.lfFaceName);
|
||||
#endif
|
||||
if (!font->GetSubsets(aDC)) {
|
||||
mLoadedFontsCount--;
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
font->mMap = GetCMAP(aDC, logFont.lfFaceName, nsnull);
|
||||
if (!font->mMap) {
|
||||
mLoadedFontsCount--;
|
||||
delete font;
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
mLoadedFonts[mLoadedFontsCount++] = font;
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
|
||||
return (nsFontWin*) font;
|
||||
return font;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
@ -2739,23 +2819,27 @@ nsFontMetricsWinA::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
if (low) {
|
||||
low->ToLowerCase();
|
||||
nsString* winName = (nsString*) PL_HashTableLookup(gFamilyNames, low);
|
||||
delete low;
|
||||
if (!winName) {
|
||||
if (winName == gGeneric) {
|
||||
mGeneric = low;
|
||||
return nsnull;
|
||||
}
|
||||
else if (!winName) {
|
||||
winName = name;
|
||||
}
|
||||
delete low;
|
||||
nsFontWinA* font = (nsFontWinA*) LoadFont(aDC, winName);
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
nsFontSubset* subset = font->mSubsets;
|
||||
nsFontSubset* endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
nsFontSubset** subset = font->mSubsets;
|
||||
nsFontSubset** endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(font)) {
|
||||
if (!(*subset)->mMap) {
|
||||
if (!(*subset)->Load(font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, aChar)) {
|
||||
return (nsFontWin*) subset;
|
||||
if (FONT_HAS_GLYPH((*subset)->mMap, aChar)) {
|
||||
return *subset;
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
@ -2766,6 +2850,87 @@ nsFontMetricsWinA::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWinA::LoadGenericFont(HDC aDC, PRUnichar aChar, char** aName)
|
||||
{
|
||||
if (*aName) {
|
||||
int found = 0;
|
||||
int i;
|
||||
for (i = 0; i < mLoadedFontsCount; i++) {
|
||||
nsFontWin* font = mLoadedFonts[i];
|
||||
if (!strcmp(font->mName, *aName)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
nsAllocator::Free(*aName);
|
||||
*aName = nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
PRUnichar name[LF_FACESIZE] = { 0 };
|
||||
PRUnichar format[] = { '%', 's', 0 };
|
||||
PRUint32 n = nsTextFormater::snprintf(name, LF_FACESIZE, format, *aName);
|
||||
nsAllocator::Free(*aName);
|
||||
*aName = nsnull;
|
||||
if (n && (n != (PRUint32) -1)) {
|
||||
nsString* fontName = new nsAutoString(name);
|
||||
if (fontName) {
|
||||
nsFontWinA* font = (nsFontWinA*) LoadFont(aDC, fontName);
|
||||
delete fontName;
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
nsFontSubset** subset = font->mSubsets;
|
||||
nsFontSubset** endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!(*subset)->mMap) {
|
||||
if (!(*subset)->Load(font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH((*subset)->mMap, aChar)) {
|
||||
return *subset;
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static int
|
||||
SystemSupportsChar(PRUnichar aChar)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(bitToCharSet); i++) {
|
||||
PRUint8 charSet = bitToCharSet[i];
|
||||
if (charSet != DEFAULT_CHARSET) {
|
||||
if (HaveConverterFor(charSet)) {
|
||||
int j = gCharSetToIndex[charSet];
|
||||
PRUint8* charSetMap = gCharSetInfo[j].mMap;
|
||||
if (!charSetMap) {
|
||||
charSetMap = (PRUint8*) PR_Calloc(8192, 1);
|
||||
if (charSetMap) {
|
||||
gCharSetInfo[j].mMap = charSetMap;
|
||||
gCharSetInfo[j].GenerateMap(&gCharSetInfo[j]);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(charSetMap, aChar)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWinA::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
{
|
||||
@ -2774,6 +2939,9 @@ nsFontMetricsWinA::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
if (!SystemSupportsChar(c)) {
|
||||
return nsnull;
|
||||
}
|
||||
for (int i = 0; i < gGlobalFontsCount; i++) {
|
||||
if (!gGlobalFonts[i].skip) {
|
||||
if (!gGlobalFonts[i].map) {
|
||||
@ -2796,22 +2964,22 @@ nsFontMetricsWinA::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
if (FONT_HAS_GLYPH(gGlobalFonts[i].map, c)) {
|
||||
nsFontWinA* font = (nsFontWinA*) LoadFont(aDC, gGlobalFonts[i].name);
|
||||
if (font) {
|
||||
nsFontSubset* subset = font->mSubsets;
|
||||
nsFontSubset* endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
nsFontSubset** subset = font->mSubsets;
|
||||
nsFontSubset** endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(font)) {
|
||||
if (!(*subset)->mMap) {
|
||||
if (!(*subset)->Load(font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
return (nsFontWin*) subset;
|
||||
if (FONT_HAS_GLYPH((*subset)->mMap, c)) {
|
||||
return *subset;
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
mLoadedFontsCount--;
|
||||
FreeFont(font);
|
||||
delete font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,11 @@ class nsFontWin
|
||||
public:
|
||||
nsFontWin(LOGFONT* aLogFont, HFONT aFont, PRUint8* aMap);
|
||||
virtual ~nsFontWin();
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString,
|
||||
PRUint32 aLength) = 0;
|
||||
// XXX return width from DrawString
|
||||
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength) = 0;
|
||||
#ifdef MOZ_MATHML
|
||||
@ -105,10 +107,8 @@ public:
|
||||
|
||||
virtual nsresult GetSpaceWidth(nscoord &aSpaceWidth);
|
||||
virtual nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* FindGenericFont(HDC aDC, PRUnichar aChar,
|
||||
nsString* aGeneric);
|
||||
virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar,
|
||||
nsString** aGeneric);
|
||||
virtual nsFontWin* FindGenericFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar);
|
||||
nsFontWin* FindFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* LoadGenericFont(HDC aDC, PRUnichar aChar, char** aName);
|
||||
virtual nsFontWin* LoadFont(HDC aDC, nsString* aName);
|
||||
@ -124,6 +124,8 @@ public:
|
||||
PRUint16 mFontsCount;
|
||||
PRUint16 mFontsIndex;
|
||||
|
||||
nsString *mGeneric;
|
||||
int mTriedAllGenerics;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
|
||||
nscoord mSpaceWidth;
|
||||
@ -200,37 +202,45 @@ public:
|
||||
|
||||
// The following is a workaround for a Japanse Windows 95 problem.
|
||||
|
||||
typedef struct nsFontWinA nsFontWinA;
|
||||
class nsFontWinA;
|
||||
|
||||
// must start with same fields as nsFontWin
|
||||
struct nsFontSubset
|
||||
class nsFontSubset : public nsFontWin
|
||||
{
|
||||
public:
|
||||
nsFontSubset();
|
||||
virtual ~nsFontSubset();
|
||||
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString,
|
||||
PRUint32 aLength);
|
||||
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength);
|
||||
int Load(nsFontWinA* aFont);
|
||||
|
||||
HFONT mFont;
|
||||
PRUint8* mMap;
|
||||
BYTE mCharSet;
|
||||
PRUint16 mCodePage;
|
||||
};
|
||||
|
||||
struct nsFontWinA
|
||||
class nsFontWinA : public nsFontWin
|
||||
{
|
||||
public:
|
||||
nsFontWinA(LOGFONT* aLogFont, HFONT aFont, PRUint8* aMap);
|
||||
virtual ~nsFontWinA();
|
||||
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString,
|
||||
PRUint32 aLength);
|
||||
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength);
|
||||
int GetSubsets(HDC aDC);
|
||||
|
||||
LOGFONT mLogFont;
|
||||
HFONT mFont;
|
||||
PRUint8* mMap;
|
||||
nsFontSubset* mSubsets;
|
||||
PRUint16 mSubsetsCount;
|
||||
LOGFONT mLogFont;
|
||||
nsFontSubset** mSubsets;
|
||||
PRUint16 mSubsetsCount;
|
||||
};
|
||||
|
||||
class nsFontMetricsWinA : public nsFontMetricsWin
|
||||
{
|
||||
public:
|
||||
virtual ~nsFontMetricsWinA();
|
||||
|
||||
virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* LoadGenericFont(HDC aDC, PRUnichar aChar, char** aName);
|
||||
virtual nsFontWin* LoadFont(HDC aDC, nsString* aName);
|
||||
};
|
||||
|
||||
|
@ -2473,7 +2473,6 @@ NS_IMETHODIMP nsRenderingContextWinA :: GetWidth(const PRUnichar *aString,
|
||||
{
|
||||
nsFontMetricsWinA* metrics = (nsFontMetricsWinA*) mFontMetrics;
|
||||
nsFontSubset* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
||||
@ -2486,17 +2485,17 @@ NS_IMETHODIMP nsRenderingContextWinA :: GetWidth(const PRUnichar *aString,
|
||||
nsFontWinA** end = (nsFontWinA**) &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH((*font)->mMap, c)) {
|
||||
nsFontSubset* subset = (*font)->mSubsets;
|
||||
nsFontSubset* endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
nsFontSubset** subset = (*font)->mSubsets;
|
||||
nsFontSubset** endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(*font)) {
|
||||
if (!(*subset)->mMap) {
|
||||
if (!(*subset)->Load(*font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
currFont = subset;
|
||||
if (FONT_HAS_GLYPH((*subset)->mMap, c)) {
|
||||
currFont = *subset;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
subset++;
|
||||
@ -2509,18 +2508,7 @@ FoundFont:
|
||||
// XXX avoid this test by duplicating code
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, &aString[start],
|
||||
i - start, str, sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::GetTextExtentPoint32A(mDC, str, len, &size);
|
||||
width += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
width += prevFont->GetWidth(mDC, &aString[start], i - start);
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
}
|
||||
@ -2532,18 +2520,7 @@ FoundFont:
|
||||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, &aString[start],
|
||||
i - start, str, sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::GetTextExtentPoint32A(mDC, str, len, &size);
|
||||
width += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
width += prevFont->GetWidth(mDC, &aString[start], i - start);
|
||||
}
|
||||
|
||||
aWidth = NSToCoordRound(float(width) * mP2T);
|
||||
@ -2577,7 +2554,6 @@ NS_IMETHODIMP nsRenderingContextWinA :: DrawString(const PRUnichar *aString, PRU
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
nsFontMetricsWinA* metrics = (nsFontMetricsWinA*) mFontMetrics;
|
||||
nsFontSubset* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
||||
@ -2589,17 +2565,17 @@ NS_IMETHODIMP nsRenderingContextWinA :: DrawString(const PRUnichar *aString, PRU
|
||||
nsFontWinA** end = (nsFontWinA**) &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH((*font)->mMap, c)) {
|
||||
nsFontSubset* subset = (*font)->mSubsets;
|
||||
nsFontSubset* endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
nsFontSubset** subset = (*font)->mSubsets;
|
||||
nsFontSubset** endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(*font)) {
|
||||
if (!(*subset)->mMap) {
|
||||
if (!(*subset)->Load(*font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
currFont = subset;
|
||||
if (FONT_HAS_GLYPH((*subset)->mMap, c)) {
|
||||
currFont = *subset;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
subset++;
|
||||
@ -2611,7 +2587,6 @@ NS_IMETHODIMP nsRenderingContextWinA :: DrawString(const PRUnichar *aString, PRU
|
||||
FoundFont:
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
@ -2626,33 +2601,14 @@ FoundFont:
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, str, 1, mb,
|
||||
sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
prevFont->DrawString(mDC, x, y, str, 1);
|
||||
aX += *aSpacing++;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0,
|
||||
&aString[start], i - start, mb, sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
::GetTextExtentPoint32A(mDC, mb, len, &size);
|
||||
x += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
prevFont->DrawString(mDC, x, y, &aString[start], i - start);
|
||||
x += prevFont->GetWidth(mDC, &aString[start], i - start);
|
||||
}
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
@ -2665,7 +2621,6 @@ FoundFont:
|
||||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
@ -2680,31 +2635,13 @@ FoundFont:
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, str, 1, mb,
|
||||
sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
prevFont->DrawString(mDC, x, y, str, 1);
|
||||
aX += *aSpacing++;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0,
|
||||
&aString[start], i - start, mb, sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
prevFont->DrawString(mDC, x, y, &aString[start], i - start);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user