#102706 change nsFontMetricsWin.cpp to use nsCompressedCharMap

r=rbs sr=attinasi

Most of the charmap were replaced by compressed charmap, only very few
left for direct operation. Some optimization also get in as problem
found when testing this patch.
This commit is contained in:
shanjian%netscape.com 2001-10-22 23:20:24 +00:00
Родитель db74eb0cfe
Коммит c0114a1447
10 изменённых файлов: 565 добавлений и 514 удалений

Просмотреть файл

@ -45,6 +45,7 @@ EXPORTS = \
nsIDeviceContextSpec.h \
nsIDeviceContextSpecFactory.h \
nsIDrawingSurface.h \
nsCompressedCharMap.h \
$(NULL)
MODULE=gfx

Просмотреть файл

@ -63,9 +63,11 @@
class nsICharRepresentable;
extern PRUint16* CreateEmptyCCMap();
extern PRUint16* MapToCCMap(PRUint32* aMap);
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
extern void FreeCCMap(PRUint16* &aMap);
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
//
// nsCompressedCharMap

Просмотреть файл

@ -73,6 +73,12 @@ MapToCCMap(PRUint32* aMap)
return ccmap;
}
PRUint16* CreateEmptyCCMap()
{
nsCompressedCharMap ccmapObj;
return ccmapObj.NewCCMap();
}
PRUint16*
MapperToCCMap(nsICharRepresentable *aMapper)
{
@ -86,6 +92,52 @@ MapperToCCMap(nsICharRepresentable *aMapper)
return ccMap;
}
#define CCMAP_MID_OFFSET(m, i) ((m)[i])
#define CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(m, midoffset, i) ((m)[(i) + (midoffset)])
/***********************************************************************************
*compare 2 ccmap and see if they are exactly the same
* Here I assume both ccmap is generated by
* nsCompressedCharMap::SetChars(PRUint32* aMap)
* This funtion rely on current implementation of above function. The that changed,
* we might need to revisit this implementation.
***********************************************************************************/
PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2)
{
PRUint16 i, tmp;
PRUint16 maxMidOffset = CCMAP_EMPTY_MID;
PRUint16 maxOffset = 0;
//find out the midOffset which itself has the largest offset among all midOffset
for (i = 0; i < CCMAP_NUM_UPPER_POINTERS; i++) {
tmp = CCMAP_MID_OFFSET(ccmap1, i);
if ( tmp > maxMidOffset)
maxMidOffset = tmp;
}
//find out the larget page offset among maxMidOffset
for (i = 0; i < CCMAP_NUM_MID_POINTERS; i++) {
tmp = CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(ccmap1, maxMidOffset, i);
if (tmp > maxOffset)
maxOffset = tmp;
}
//if the page offset is allocated later than maxMidOffset, add page size
if (maxOffset)
maxOffset += CCMAP_NUM_PRUINT16S_PER_PAGE;
else
maxOffset = maxMidOffset;
//now maxOffset is the size of ccmap1, though ccmap2 might be smaller than
//ccmap1, the following comparison is still safe. That is because it will
//return false before the limit of ccmap2 is reached.
for (i = 0; i < maxOffset; i++)
if (ccmap1[i] != ccmap2[i])
return PR_FALSE;
return PR_TRUE;
}
PRUint16*
nsCompressedCharMap::NewCCMap()
{

Просмотреть файл

@ -73,6 +73,12 @@ MapToCCMap(PRUint32* aMap)
return ccmap;
}
PRUint16* CreateEmptyCCMap()
{
nsCompressedCharMap ccmapObj;
return ccmapObj.NewCCMap();
}
PRUint16*
MapperToCCMap(nsICharRepresentable *aMapper)
{
@ -86,6 +92,52 @@ MapperToCCMap(nsICharRepresentable *aMapper)
return ccMap;
}
#define CCMAP_MID_OFFSET(m, i) ((m)[i])
#define CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(m, midoffset, i) ((m)[(i) + (midoffset)])
/***********************************************************************************
*compare 2 ccmap and see if they are exactly the same
* Here I assume both ccmap is generated by
* nsCompressedCharMap::SetChars(PRUint32* aMap)
* This funtion rely on current implementation of above function. The that changed,
* we might need to revisit this implementation.
***********************************************************************************/
PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2)
{
PRUint16 i, tmp;
PRUint16 maxMidOffset = CCMAP_EMPTY_MID;
PRUint16 maxOffset = 0;
//find out the midOffset which itself has the largest offset among all midOffset
for (i = 0; i < CCMAP_NUM_UPPER_POINTERS; i++) {
tmp = CCMAP_MID_OFFSET(ccmap1, i);
if ( tmp > maxMidOffset)
maxMidOffset = tmp;
}
//find out the larget page offset among maxMidOffset
for (i = 0; i < CCMAP_NUM_MID_POINTERS; i++) {
tmp = CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(ccmap1, maxMidOffset, i);
if (tmp > maxOffset)
maxOffset = tmp;
}
//if the page offset is allocated later than maxMidOffset, add page size
if (maxOffset)
maxOffset += CCMAP_NUM_PRUINT16S_PER_PAGE;
else
maxOffset = maxMidOffset;
//now maxOffset is the size of ccmap1, though ccmap2 might be smaller than
//ccmap1, the following comparison is still safe. That is because it will
//return false before the limit of ccmap2 is reached.
for (i = 0; i < maxOffset; i++)
if (ccmap1[i] != ccmap2[i])
return PR_FALSE;
return PR_TRUE;
}
PRUint16*
nsCompressedCharMap::NewCCMap()
{

Просмотреть файл

@ -63,9 +63,11 @@
class nsICharRepresentable;
extern PRUint16* CreateEmptyCCMap();
extern PRUint16* MapToCCMap(PRUint32* aMap);
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
extern void FreeCCMap(PRUint16* &aMap);
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
//
// nsCompressedCharMap

Просмотреть файл

@ -54,8 +54,9 @@ OBJS = \
.\$(OBJDIR)\nsDeviceContextSpecFactoryW.obj \
.\$(OBJDIR)\nsScreenWin.obj \
.\$(OBJDIR)\nsScreenManagerWin.obj \
.\$(OBJDIR)\nsPrintOptionsWin.obj \
.\$(OBJDIR)\nsPrintOptionsWin.obj \
.\$(OBJDIR)\nsGfxFactoryWin.obj \
.\$(OBJDIR)\nsCompressedCharMap.obj \
$(NULL)
EXPORTS= nsIRenderingContextWin.h \
@ -97,6 +98,9 @@ WIN_LIBS= \
LLFLAGS = $(LLFLAGS)
include <$(DEPTH)\config\rules.mak>
export::
$(MAKE_INSTALL) ..\nsCompressedCharMap.cpp .
install::
$(MAKE_INSTALL) fontEncoding.properties $(DIST)\bin\res\fonts

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -32,6 +32,8 @@
#include "nsDeviceContextWin.h"
#include "nsCOMPtr.h"
#include "nsVoidArray.h"
#include "nsICharRepresentable.h"
#include "nsCompressedCharMap.h"
#ifdef FONT_HAS_GLYPH
#undef FONT_HAS_GLYPH
@ -60,7 +62,7 @@ struct nsGlobalFont
{
nsString name;
LOGFONT logFont;
PRUint32* map;
PRUint16* ccmap;
FONTSIGNATURE signature;
eFontType fonttype;
PRUint32 flags;
@ -79,7 +81,7 @@ class nsFontWin
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
nsFontWin(LOGFONT* aLogFont, HFONT aFont, PRUint32* aMap);
nsFontWin(LOGFONT* aLogFont, HFONT aFont, PRUint16* aCCMap);
virtual ~nsFontWin();
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString,
@ -89,6 +91,7 @@ public:
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength) = 0;
virtual PRBool HasGlyph(PRUnichar ch) {return CCMAP_HAS_CHAR(mCCMap, ch);};
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
@ -102,7 +105,7 @@ public:
char mName[LF_FACESIZE];
HFONT mFont;
PRUint32* mMap;
PRUint16* mCCMap;
#ifdef MOZ_MATHML
nsCharacterMap* mCMAP;
#endif
@ -111,6 +114,37 @@ public:
nscoord mMaxDescent;
};
// A "substitute font" to deal with missing glyphs -- see bug 6585
// We now use transliteration+fallback to the REPLACEMENT CHAR +
// HEX representation to handle this issue.
class nsFontWinSubstitute : public nsFontWin
{
public:
nsFontWinSubstitute(LOGFONT* aLogFont, HFONT aFont, PRUint16* aCCMap, PRBool aDisplayUnicode);
virtual ~nsFontWinSubstitute();
virtual PRBool HasGlyph(PRUnichar ch) {return IS_REPRESENTABLE(mRepresentableCharMap, ch);};
virtual void SetRepresentable(PRUnichar ch) {SET_REPRESENTABLE(mRepresentableCharMap, ch);};
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString, PRUint32 aLength);
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength);
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics);
#ifdef NS_DEBUG
virtual void DumpFontInfo();
#endif // NS_DEBUG
#endif
private:
PRBool mDisplayUnicode;
//We need to have a easily operatable charmap for substitute font
PRUint32 mRepresentableCharMap[UCS2_MAP_LEN];
};
/**
* nsFontSwitchCallback
*
@ -211,7 +245,7 @@ public:
PRBool mTriedAllGenerics;
PRBool mIsUserDefined;
static PRUint32* gEmptyMap;
static PRUint16* gEmptyCCMap;
static PLHashTable* gFontMaps;
static PLHashTable* gFamilyNames;
static PLHashTable* gFontWeights;
@ -222,7 +256,8 @@ public:
static void SetFontWeight(PRInt32 aWeight, PRUint16* aWeightTable);
static PRBool IsFontWeightAvailable(PRInt32 aWeight, PRUint16 aWeightTable);
static PRUint32* GetCMAP(HDC aDC, const char* aShortName, eFontType* aFontType, PRUint8* aCharset);
static PRUint16* GetFontCCMAP(HDC aDC, const char* aShortName, eFontType* aFontType, PRUint8* aCharset);
static PRUint16* GetCCMAP(HDC aDC, const char* aShortName, eFontType* aFontType, PRUint8* aCharset);
static int SameAsPreviousMap(int aIndex);
@ -331,13 +366,14 @@ public:
class nsFontWinA : public nsFontWin
{
public:
nsFontWinA(LOGFONT* aLogFont, HFONT aFont, PRUint32* aMap);
nsFontWinA(LOGFONT* aLogFont, HFONT aFont, PRUint16* aCCMap);
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);
virtual nsFontSubset* FindSubset(HDC aDC, PRUnichar aChar, nsFontMetricsWinA* aFontMetrics);
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
@ -356,6 +392,21 @@ public:
PRUint16 mSubsetsCount;
};
class nsFontWinSubstituteA : public nsFontWinA
{
public:
nsFontWinSubstituteA(LOGFONT* aLogFont, HFONT aFont, PRUint16* aCCMap);
virtual ~nsFontWinSubstituteA();
virtual PRBool HasGlyph(PRUnichar ch) {return IS_REPRESENTABLE(mRepresentableCharMap, ch);};
virtual void SetRepresentable(PRUnichar ch) {SET_REPRESENTABLE(mRepresentableCharMap, ch);};
virtual nsFontSubset* FindSubset(HDC aDC, PRUnichar aChar, nsFontMetricsWinA* aFontMetrics) {return mSubsets[0];};
//We need to have a easily operatable charmap for substitute font
PRUint32 mRepresentableCharMap[UCS2_MAP_LEN];
};
class nsFontMetricsWinA : public nsFontMetricsWin
{
public:

Просмотреть файл

@ -73,6 +73,12 @@ MapToCCMap(PRUint32* aMap)
return ccmap;
}
PRUint16* CreateEmptyCCMap()
{
nsCompressedCharMap ccmapObj;
return ccmapObj.NewCCMap();
}
PRUint16*
MapperToCCMap(nsICharRepresentable *aMapper)
{
@ -86,6 +92,52 @@ MapperToCCMap(nsICharRepresentable *aMapper)
return ccMap;
}
#define CCMAP_MID_OFFSET(m, i) ((m)[i])
#define CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(m, midoffset, i) ((m)[(i) + (midoffset)])
/***********************************************************************************
*compare 2 ccmap and see if they are exactly the same
* Here I assume both ccmap is generated by
* nsCompressedCharMap::SetChars(PRUint32* aMap)
* This funtion rely on current implementation of above function. The that changed,
* we might need to revisit this implementation.
***********************************************************************************/
PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2)
{
PRUint16 i, tmp;
PRUint16 maxMidOffset = CCMAP_EMPTY_MID;
PRUint16 maxOffset = 0;
//find out the midOffset which itself has the largest offset among all midOffset
for (i = 0; i < CCMAP_NUM_UPPER_POINTERS; i++) {
tmp = CCMAP_MID_OFFSET(ccmap1, i);
if ( tmp > maxMidOffset)
maxMidOffset = tmp;
}
//find out the larget page offset among maxMidOffset
for (i = 0; i < CCMAP_NUM_MID_POINTERS; i++) {
tmp = CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(ccmap1, maxMidOffset, i);
if (tmp > maxOffset)
maxOffset = tmp;
}
//if the page offset is allocated later than maxMidOffset, add page size
if (maxOffset)
maxOffset += CCMAP_NUM_PRUINT16S_PER_PAGE;
else
maxOffset = maxMidOffset;
//now maxOffset is the size of ccmap1, though ccmap2 might be smaller than
//ccmap1, the following comparison is still safe. That is because it will
//return false before the limit of ccmap2 is reached.
for (i = 0; i < maxOffset; i++)
if (ccmap1[i] != ccmap2[i])
return PR_FALSE;
return PR_TRUE;
}
PRUint16*
nsCompressedCharMap::NewCCMap()
{

Просмотреть файл

@ -63,9 +63,11 @@
class nsICharRepresentable;
extern PRUint16* CreateEmptyCCMap();
extern PRUint16* MapToCCMap(PRUint32* aMap);
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
extern void FreeCCMap(PRUint16* &aMap);
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
//
// nsCompressedCharMap