зеркало из https://github.com/mozilla/pjs.git
#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:
Родитель
db74eb0cfe
Коммит
c0114a1447
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче