зеркало из https://github.com/mozilla/gecko-dev.git
#support unicode beyond BMP plane in Compressed charmap
r=bstell, sr=brendan
This commit is contained in:
Родитель
ed39cb8438
Коммит
4a4b2f6c1e
|
@ -69,6 +69,10 @@ extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
|||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
|
||||
// surrogate support extension
|
||||
extern PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum);
|
||||
|
||||
//
|
||||
// nsCompressedCharMap
|
||||
//
|
||||
|
@ -97,7 +101,8 @@ public:
|
|||
nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
void FreeCCMap(PRUint16*);
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
|
@ -172,6 +177,7 @@ protected:
|
|||
// One minor note: for a completely empty map it is actually
|
||||
// possible to fold the upper, empty mid, and empty page
|
||||
// on top of each other and make a map of only 32 bytes.
|
||||
#define CCMAP_EMPTY_SIZE_PER_INT16 16
|
||||
|
||||
// offsets to the empty mid and empty page
|
||||
#define CCMAP_EMPTY_MID CCMAP_NUM_UPPER_POINTERS
|
||||
|
@ -183,9 +189,50 @@ protected:
|
|||
// the actual needed size and simply copy over the data.
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Compressed Char map surrogate extension
|
||||
//
|
||||
// The design goal of surrogate support extension is to keep efficiency
|
||||
// and compatibility of existing compressed charmap operations. Most of
|
||||
// existing operation are untouched. For BMP support, very little memory
|
||||
// overhead (4 bytes) is added. Runtime efficiency of BMP support is
|
||||
// unchanged.
|
||||
//
|
||||
// structure of extended charmap:
|
||||
// ccmap flag 1 PRUint16 , indication if this is extended one or not
|
||||
// bmp ccmap size 1 PRUint16 , the size of BMP ccmap,
|
||||
// BMP ccmap size varies,
|
||||
// plane index 16 PRUint32, use to index ccmap for non-BMP plane
|
||||
// empty ccmap 16 PRUint16, a total empty ccmap
|
||||
// non-BMP ccmaps size varies, other non-empty, non-BMP ccmap
|
||||
//
|
||||
// Changes to basic ccmap
|
||||
// 2 PRUint16 are added in the very beginning. One is used to descript the size
|
||||
// of the ccmap, the other is used as a flag. But these 2 fields are indexed
|
||||
// negatively so that all other operation remain unchanged to keep efficiency.
|
||||
// ccmap memory allocation is moved from nsCompressedCharMap::NewCCMap to
|
||||
// MapToCCMap.
|
||||
//
|
||||
// Extended ccmap
|
||||
// A 16*PRUint32 array was put at the end of basic ccmap, each PRUint32 either
|
||||
// pointed to the empty ccmap or a independent plane ccmap. Directly after this
|
||||
// array is a empty ccmap. All planes that has no character will share this ccmap.
|
||||
// All non-empty plane will have a ccmap.
|
||||
// "MapToCCMapExt" is added to created an extended ccmap, each plane ccmap is
|
||||
// created the same as basic one, but without 2 additional fields.
|
||||
// "HasGlyphExt" is used to access extended ccmap, it first need to locate the
|
||||
// plane ccmap, and then operated the same way as "HasGlyph".
|
||||
//
|
||||
// Compatibility between old and new one
|
||||
// Because extended ccmap includes an exactly identical basic ccmap in its head,
|
||||
// basic ccmap operation (HasGlyph) can be applied on extended ccmap without
|
||||
// problem.
|
||||
// Because basic ccmap now has a flag to indicate if it is a extended one,
|
||||
// Extended ccmap operation (HasGlyphExt) can check the flag before it does
|
||||
// extended ccmap specific operation. So HasGlyphExt can be applied to basic ccmap
|
||||
// too.
|
||||
//
|
||||
|
||||
// Page bits
|
||||
//
|
||||
#define CCMAP_BITS_PER_PAGE_LOG2 8
|
||||
|
@ -264,4 +311,23 @@ protected:
|
|||
// unset the bit
|
||||
#define CCMAP_UNSET_CHAR(m,c) (CCMAP_TO_ALU(m,c) &= ~(CCMAP_POW2(CCMAP_BIT_INDEX(c))))
|
||||
|
||||
#define CCMAP_SIZE(m) (*((m)-1))
|
||||
#define CCMAP_FLAG(m) (*((m)-2))
|
||||
#define CCMAP_EXTRA (sizeof(ALU_TYPE)/sizeof(PRUint16)>2? sizeof(ALU_TYPE)/sizeof(PRUint16): 2)
|
||||
#define CCMAP_SURROGATE_FLAG 0X0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6)
|
||||
|
||||
// scalar value inside the plane
|
||||
#define CCMAP_INPLANE_OFFSET(h, l) (((((PRUint16)(h) - (PRUint16)0xd800) & 0x3f) << 10) + ((PRUint16)(l) - (PRUint16)0xdc00))
|
||||
|
||||
// get ccmap for that plane
|
||||
#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[i])
|
||||
|
||||
// test the bit for surrogate pair
|
||||
#define CCMAP_HAS_CHAR_EXT(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(h)), CCMAP_INPLANE_OFFSET(h, l)))
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
|
@ -47,7 +47,7 @@ FreeCCMap(PRUint16* &aMap)
|
|||
{
|
||||
if (!aMap)
|
||||
return;
|
||||
PR_Free(aMap);
|
||||
PR_Free(aMap - CCMAP_EXTRA);
|
||||
aMap = nsnull;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
nsCompressedCharMap ccmapObj;
|
||||
ccmapObj.SetChars(aMap);
|
||||
|
||||
// make a copy of the map
|
||||
PRUint16* ccmap = ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + (ccmapObj.GetSize()) * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = ccmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
|
||||
ccmapObj.FillCCMap(ccmap);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int i=0; i<NUM_UNICODE_CHARS; i++) {
|
||||
|
@ -75,8 +84,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
|
||||
PRUint16* CreateEmptyCCMap()
|
||||
{
|
||||
nsCompressedCharMap ccmapObj;
|
||||
return ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + 16 * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
memset(ccmap, '\0', CCMAP_EMPTY_SIZE_PER_INT16 * sizeof(PRUint16)+ CCMAP_EXTRA);
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
return ccmap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
|
@ -104,37 +122,14 @@ MapperToCCMap(nsICharRepresentable *aMapper)
|
|||
***********************************************************************************/
|
||||
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;
|
||||
PRUint16 len1 = CCMAP_SIZE(ccmap1);
|
||||
PRUint16 len2 = CCMAP_SIZE(ccmap2);
|
||||
|
||||
if (len1 != len2)
|
||||
return PR_FALSE;
|
||||
|
||||
if (memcmp(ccmap1, ccmap2, sizeof(PRUint16)*len1))
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -145,12 +140,18 @@ nsCompressedCharMap::NewCCMap()
|
|||
NS_ASSERTION(newMap, "failed to alloc new CCMap");
|
||||
if (!newMap)
|
||||
return nsnull;
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
// transfer the data
|
||||
for (int i=0; i<mUsedLen; i++)
|
||||
newMap[i] = u.mCCMap[i];
|
||||
aCCMap[i] = u.mCCMap[i];
|
||||
|
||||
return newMap;
|
||||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
|
@ -349,3 +350,107 @@ nsCompressedCharMap::SetChars(PRUint32* aMap)
|
|||
}
|
||||
}
|
||||
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// Non-BMP unicode support extension, create ccmap for both BMP and extended planes
|
||||
PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum)
|
||||
{
|
||||
nsCompressedCharMap otherPlaneObj[16];
|
||||
PRUint32 totalSize;
|
||||
PRUint16 i;
|
||||
PRUint32 *planeCCMapOffsets;
|
||||
PRUint32 currOffset;
|
||||
|
||||
NS_ASSERTION(aOtherPlaneNum <= EXTENDED_UNICODE_PLANES, "illegal argument value");
|
||||
if (aOtherPlaneNum > EXTENDED_UNICODE_PLANES)
|
||||
return nsnull;
|
||||
|
||||
// Put the data into a temp map
|
||||
nsCompressedCharMap bmpCcmapObj;
|
||||
bmpCcmapObj.SetChars(aBmpPlaneMap);
|
||||
|
||||
// Add bmp size
|
||||
totalSize = bmpCcmapObj.GetSize();
|
||||
|
||||
// Add bmp length field
|
||||
totalSize += CCMAP_EXTRA;
|
||||
|
||||
// Add Plane array
|
||||
totalSize += EXTENDED_UNICODE_PLANES * sizeof(PRUint32)/sizeof(PRUint16);
|
||||
|
||||
// Add an empty plane ccmap
|
||||
// A totally empty plane ccmap can be represented by 16 *(PRUint16)0.
|
||||
totalSize += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Create ccmap for other planes
|
||||
for (i = 0; i < aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
otherPlaneObj[i].SetChars(aOtherPlaneMaps[i]);
|
||||
totalSize += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(totalSize * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
// Assign BMP ccmap size
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = bmpCcmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_SURROGATE_FLAG;
|
||||
|
||||
// Fill bmp plane ccmap
|
||||
bmpCcmapObj.FillCCMap(ccmap);
|
||||
|
||||
// Get pointer for plane ccmap offset array
|
||||
currOffset = bmpCcmapObj.GetSize();
|
||||
planeCCMapOffsets = (PRUint32*)(ccmap+currOffset);
|
||||
currOffset += sizeof(PRUint32)/sizeof(PRUint16)*EXTENDED_UNICODE_PLANES;
|
||||
|
||||
// Put a empty ccmap there
|
||||
memset(ccmap+currOffset, '\0', sizeof(PRUint16)*16);
|
||||
PRUint32 emptyCCMapOffset = currOffset;
|
||||
currOffset += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Now fill all rest of the planes' ccmap and put off in array
|
||||
for (i = 0; i <aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
*(planeCCMapOffsets+i) = currOffset;
|
||||
otherPlaneObj[i].FillCCMap(ccmap+currOffset);
|
||||
currOffset += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
else
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
for (; i < EXTENDED_UNICODE_PLANES; i++) {
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRUint32 k, h, l, plane, offset;
|
||||
PRBool oldb;
|
||||
PRBool newb;
|
||||
|
||||
// testing for BMP plane
|
||||
for (k=0; k<NUM_UNICODE_CHARS; k++) {
|
||||
oldb = IS_REPRESENTABLE(aBmpPlaneMap, k);
|
||||
newb = CCMAP_HAS_CHAR(ccmap, k);
|
||||
NS_ASSERTION(oldb==newb,"failed to generate map correctly");
|
||||
}
|
||||
|
||||
// testing for non-BMP plane
|
||||
for (h = 0; h < 0x400; h++) {
|
||||
for (l = 0; l < 0x400; l++) {
|
||||
plane = h >> 6;
|
||||
offset = (h*0x400 + l) & 0xffff;
|
||||
oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset);
|
||||
newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00);
|
||||
NS_ASSERTION(oldb==newb, "failed to generate extension map correctly");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ccmap;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ FreeCCMap(PRUint16* &aMap)
|
|||
{
|
||||
if (!aMap)
|
||||
return;
|
||||
PR_Free(aMap);
|
||||
PR_Free(aMap - CCMAP_EXTRA);
|
||||
aMap = nsnull;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
nsCompressedCharMap ccmapObj;
|
||||
ccmapObj.SetChars(aMap);
|
||||
|
||||
// make a copy of the map
|
||||
PRUint16* ccmap = ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + (ccmapObj.GetSize()) * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = ccmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
|
||||
ccmapObj.FillCCMap(ccmap);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int i=0; i<NUM_UNICODE_CHARS; i++) {
|
||||
|
@ -75,8 +84,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
|
||||
PRUint16* CreateEmptyCCMap()
|
||||
{
|
||||
nsCompressedCharMap ccmapObj;
|
||||
return ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + 16 * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
memset(ccmap, '\0', CCMAP_EMPTY_SIZE_PER_INT16 * sizeof(PRUint16)+ CCMAP_EXTRA);
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
return ccmap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
|
@ -104,37 +122,14 @@ MapperToCCMap(nsICharRepresentable *aMapper)
|
|||
***********************************************************************************/
|
||||
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;
|
||||
PRUint16 len1 = CCMAP_SIZE(ccmap1);
|
||||
PRUint16 len2 = CCMAP_SIZE(ccmap2);
|
||||
|
||||
if (len1 != len2)
|
||||
return PR_FALSE;
|
||||
|
||||
if (memcmp(ccmap1, ccmap2, sizeof(PRUint16)*len1))
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -145,12 +140,18 @@ nsCompressedCharMap::NewCCMap()
|
|||
NS_ASSERTION(newMap, "failed to alloc new CCMap");
|
||||
if (!newMap)
|
||||
return nsnull;
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
// transfer the data
|
||||
for (int i=0; i<mUsedLen; i++)
|
||||
newMap[i] = u.mCCMap[i];
|
||||
aCCMap[i] = u.mCCMap[i];
|
||||
|
||||
return newMap;
|
||||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
|
@ -349,3 +350,107 @@ nsCompressedCharMap::SetChars(PRUint32* aMap)
|
|||
}
|
||||
}
|
||||
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// Non-BMP unicode support extension, create ccmap for both BMP and extended planes
|
||||
PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum)
|
||||
{
|
||||
nsCompressedCharMap otherPlaneObj[16];
|
||||
PRUint32 totalSize;
|
||||
PRUint16 i;
|
||||
PRUint32 *planeCCMapOffsets;
|
||||
PRUint32 currOffset;
|
||||
|
||||
NS_ASSERTION(aOtherPlaneNum <= EXTENDED_UNICODE_PLANES, "illegal argument value");
|
||||
if (aOtherPlaneNum > EXTENDED_UNICODE_PLANES)
|
||||
return nsnull;
|
||||
|
||||
// Put the data into a temp map
|
||||
nsCompressedCharMap bmpCcmapObj;
|
||||
bmpCcmapObj.SetChars(aBmpPlaneMap);
|
||||
|
||||
// Add bmp size
|
||||
totalSize = bmpCcmapObj.GetSize();
|
||||
|
||||
// Add bmp length field
|
||||
totalSize += CCMAP_EXTRA;
|
||||
|
||||
// Add Plane array
|
||||
totalSize += EXTENDED_UNICODE_PLANES * sizeof(PRUint32)/sizeof(PRUint16);
|
||||
|
||||
// Add an empty plane ccmap
|
||||
// A totally empty plane ccmap can be represented by 16 *(PRUint16)0.
|
||||
totalSize += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Create ccmap for other planes
|
||||
for (i = 0; i < aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
otherPlaneObj[i].SetChars(aOtherPlaneMaps[i]);
|
||||
totalSize += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(totalSize * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
// Assign BMP ccmap size
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = bmpCcmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_SURROGATE_FLAG;
|
||||
|
||||
// Fill bmp plane ccmap
|
||||
bmpCcmapObj.FillCCMap(ccmap);
|
||||
|
||||
// Get pointer for plane ccmap offset array
|
||||
currOffset = bmpCcmapObj.GetSize();
|
||||
planeCCMapOffsets = (PRUint32*)(ccmap+currOffset);
|
||||
currOffset += sizeof(PRUint32)/sizeof(PRUint16)*EXTENDED_UNICODE_PLANES;
|
||||
|
||||
// Put a empty ccmap there
|
||||
memset(ccmap+currOffset, '\0', sizeof(PRUint16)*16);
|
||||
PRUint32 emptyCCMapOffset = currOffset;
|
||||
currOffset += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Now fill all rest of the planes' ccmap and put off in array
|
||||
for (i = 0; i <aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
*(planeCCMapOffsets+i) = currOffset;
|
||||
otherPlaneObj[i].FillCCMap(ccmap+currOffset);
|
||||
currOffset += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
else
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
for (; i < EXTENDED_UNICODE_PLANES; i++) {
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRUint32 k, h, l, plane, offset;
|
||||
PRBool oldb;
|
||||
PRBool newb;
|
||||
|
||||
// testing for BMP plane
|
||||
for (k=0; k<NUM_UNICODE_CHARS; k++) {
|
||||
oldb = IS_REPRESENTABLE(aBmpPlaneMap, k);
|
||||
newb = CCMAP_HAS_CHAR(ccmap, k);
|
||||
NS_ASSERTION(oldb==newb,"failed to generate map correctly");
|
||||
}
|
||||
|
||||
// testing for non-BMP plane
|
||||
for (h = 0; h < 0x400; h++) {
|
||||
for (l = 0; l < 0x400; l++) {
|
||||
plane = h >> 6;
|
||||
offset = (h*0x400 + l) & 0xffff;
|
||||
oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset);
|
||||
newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00);
|
||||
NS_ASSERTION(oldb==newb, "failed to generate extension map correctly");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ccmap;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,10 @@ extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
|||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
|
||||
// surrogate support extension
|
||||
extern PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum);
|
||||
|
||||
//
|
||||
// nsCompressedCharMap
|
||||
//
|
||||
|
@ -97,7 +101,8 @@ public:
|
|||
nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
void FreeCCMap(PRUint16*);
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
|
@ -172,6 +177,7 @@ protected:
|
|||
// One minor note: for a completely empty map it is actually
|
||||
// possible to fold the upper, empty mid, and empty page
|
||||
// on top of each other and make a map of only 32 bytes.
|
||||
#define CCMAP_EMPTY_SIZE_PER_INT16 16
|
||||
|
||||
// offsets to the empty mid and empty page
|
||||
#define CCMAP_EMPTY_MID CCMAP_NUM_UPPER_POINTERS
|
||||
|
@ -183,9 +189,50 @@ protected:
|
|||
// the actual needed size and simply copy over the data.
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Compressed Char map surrogate extension
|
||||
//
|
||||
// The design goal of surrogate support extension is to keep efficiency
|
||||
// and compatibility of existing compressed charmap operations. Most of
|
||||
// existing operation are untouched. For BMP support, very little memory
|
||||
// overhead (4 bytes) is added. Runtime efficiency of BMP support is
|
||||
// unchanged.
|
||||
//
|
||||
// structure of extended charmap:
|
||||
// ccmap flag 1 PRUint16 , indication if this is extended one or not
|
||||
// bmp ccmap size 1 PRUint16 , the size of BMP ccmap,
|
||||
// BMP ccmap size varies,
|
||||
// plane index 16 PRUint32, use to index ccmap for non-BMP plane
|
||||
// empty ccmap 16 PRUint16, a total empty ccmap
|
||||
// non-BMP ccmaps size varies, other non-empty, non-BMP ccmap
|
||||
//
|
||||
// Changes to basic ccmap
|
||||
// 2 PRUint16 are added in the very beginning. One is used to descript the size
|
||||
// of the ccmap, the other is used as a flag. But these 2 fields are indexed
|
||||
// negatively so that all other operation remain unchanged to keep efficiency.
|
||||
// ccmap memory allocation is moved from nsCompressedCharMap::NewCCMap to
|
||||
// MapToCCMap.
|
||||
//
|
||||
// Extended ccmap
|
||||
// A 16*PRUint32 array was put at the end of basic ccmap, each PRUint32 either
|
||||
// pointed to the empty ccmap or a independent plane ccmap. Directly after this
|
||||
// array is a empty ccmap. All planes that has no character will share this ccmap.
|
||||
// All non-empty plane will have a ccmap.
|
||||
// "MapToCCMapExt" is added to created an extended ccmap, each plane ccmap is
|
||||
// created the same as basic one, but without 2 additional fields.
|
||||
// "HasGlyphExt" is used to access extended ccmap, it first need to locate the
|
||||
// plane ccmap, and then operated the same way as "HasGlyph".
|
||||
//
|
||||
// Compatibility between old and new one
|
||||
// Because extended ccmap includes an exactly identical basic ccmap in its head,
|
||||
// basic ccmap operation (HasGlyph) can be applied on extended ccmap without
|
||||
// problem.
|
||||
// Because basic ccmap now has a flag to indicate if it is a extended one,
|
||||
// Extended ccmap operation (HasGlyphExt) can check the flag before it does
|
||||
// extended ccmap specific operation. So HasGlyphExt can be applied to basic ccmap
|
||||
// too.
|
||||
//
|
||||
|
||||
// Page bits
|
||||
//
|
||||
#define CCMAP_BITS_PER_PAGE_LOG2 8
|
||||
|
@ -264,4 +311,23 @@ protected:
|
|||
// unset the bit
|
||||
#define CCMAP_UNSET_CHAR(m,c) (CCMAP_TO_ALU(m,c) &= ~(CCMAP_POW2(CCMAP_BIT_INDEX(c))))
|
||||
|
||||
#define CCMAP_SIZE(m) (*((m)-1))
|
||||
#define CCMAP_FLAG(m) (*((m)-2))
|
||||
#define CCMAP_EXTRA (sizeof(ALU_TYPE)/sizeof(PRUint16)>2? sizeof(ALU_TYPE)/sizeof(PRUint16): 2)
|
||||
#define CCMAP_SURROGATE_FLAG 0X0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6)
|
||||
|
||||
// scalar value inside the plane
|
||||
#define CCMAP_INPLANE_OFFSET(h, l) (((((PRUint16)(h) - (PRUint16)0xd800) & 0x3f) << 10) + ((PRUint16)(l) - (PRUint16)0xdc00))
|
||||
|
||||
// get ccmap for that plane
|
||||
#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[i])
|
||||
|
||||
// test the bit for surrogate pair
|
||||
#define CCMAP_HAS_CHAR_EXT(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(h)), CCMAP_INPLANE_OFFSET(h, l)))
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
|
@ -47,7 +47,7 @@ FreeCCMap(PRUint16* &aMap)
|
|||
{
|
||||
if (!aMap)
|
||||
return;
|
||||
PR_Free(aMap);
|
||||
PR_Free(aMap - CCMAP_EXTRA);
|
||||
aMap = nsnull;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
nsCompressedCharMap ccmapObj;
|
||||
ccmapObj.SetChars(aMap);
|
||||
|
||||
// make a copy of the map
|
||||
PRUint16* ccmap = ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + (ccmapObj.GetSize()) * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = ccmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
|
||||
ccmapObj.FillCCMap(ccmap);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int i=0; i<NUM_UNICODE_CHARS; i++) {
|
||||
|
@ -75,8 +84,17 @@ MapToCCMap(PRUint32* aMap)
|
|||
|
||||
PRUint16* CreateEmptyCCMap()
|
||||
{
|
||||
nsCompressedCharMap ccmapObj;
|
||||
return ccmapObj.NewCCMap();
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(CCMAP_EXTRA + 16 * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
memset(ccmap, '\0', CCMAP_EMPTY_SIZE_PER_INT16 * sizeof(PRUint16)+ CCMAP_EXTRA);
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
CCMAP_FLAG(ccmap) = CCMAP_NONE_FLAG;
|
||||
return ccmap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
|
@ -104,37 +122,14 @@ MapperToCCMap(nsICharRepresentable *aMapper)
|
|||
***********************************************************************************/
|
||||
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;
|
||||
PRUint16 len1 = CCMAP_SIZE(ccmap1);
|
||||
PRUint16 len2 = CCMAP_SIZE(ccmap2);
|
||||
|
||||
if (len1 != len2)
|
||||
return PR_FALSE;
|
||||
|
||||
if (memcmp(ccmap1, ccmap2, sizeof(PRUint16)*len1))
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -145,12 +140,18 @@ nsCompressedCharMap::NewCCMap()
|
|||
NS_ASSERTION(newMap, "failed to alloc new CCMap");
|
||||
if (!newMap)
|
||||
return nsnull;
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
// transfer the data
|
||||
for (int i=0; i<mUsedLen; i++)
|
||||
newMap[i] = u.mCCMap[i];
|
||||
aCCMap[i] = u.mCCMap[i];
|
||||
|
||||
return newMap;
|
||||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
|
@ -349,3 +350,107 @@ nsCompressedCharMap::SetChars(PRUint32* aMap)
|
|||
}
|
||||
}
|
||||
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// Non-BMP unicode support extension, create ccmap for both BMP and extended planes
|
||||
PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum)
|
||||
{
|
||||
nsCompressedCharMap otherPlaneObj[16];
|
||||
PRUint32 totalSize;
|
||||
PRUint16 i;
|
||||
PRUint32 *planeCCMapOffsets;
|
||||
PRUint32 currOffset;
|
||||
|
||||
NS_ASSERTION(aOtherPlaneNum <= EXTENDED_UNICODE_PLANES, "illegal argument value");
|
||||
if (aOtherPlaneNum > EXTENDED_UNICODE_PLANES)
|
||||
return nsnull;
|
||||
|
||||
// Put the data into a temp map
|
||||
nsCompressedCharMap bmpCcmapObj;
|
||||
bmpCcmapObj.SetChars(aBmpPlaneMap);
|
||||
|
||||
// Add bmp size
|
||||
totalSize = bmpCcmapObj.GetSize();
|
||||
|
||||
// Add bmp length field
|
||||
totalSize += CCMAP_EXTRA;
|
||||
|
||||
// Add Plane array
|
||||
totalSize += EXTENDED_UNICODE_PLANES * sizeof(PRUint32)/sizeof(PRUint16);
|
||||
|
||||
// Add an empty plane ccmap
|
||||
// A totally empty plane ccmap can be represented by 16 *(PRUint16)0.
|
||||
totalSize += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Create ccmap for other planes
|
||||
for (i = 0; i < aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
otherPlaneObj[i].SetChars(aOtherPlaneMaps[i]);
|
||||
totalSize += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
PRUint16 *ccmap = (PRUint16*)PR_Malloc(totalSize * sizeof(PRUint16));
|
||||
NS_ASSERTION(ccmap, "failed to alloc new CCMap");
|
||||
|
||||
if (!ccmap)
|
||||
return nsnull;
|
||||
|
||||
// Assign BMP ccmap size
|
||||
ccmap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(ccmap) = bmpCcmapObj.GetSize();
|
||||
CCMAP_FLAG(ccmap) = CCMAP_SURROGATE_FLAG;
|
||||
|
||||
// Fill bmp plane ccmap
|
||||
bmpCcmapObj.FillCCMap(ccmap);
|
||||
|
||||
// Get pointer for plane ccmap offset array
|
||||
currOffset = bmpCcmapObj.GetSize();
|
||||
planeCCMapOffsets = (PRUint32*)(ccmap+currOffset);
|
||||
currOffset += sizeof(PRUint32)/sizeof(PRUint16)*EXTENDED_UNICODE_PLANES;
|
||||
|
||||
// Put a empty ccmap there
|
||||
memset(ccmap+currOffset, '\0', sizeof(PRUint16)*16);
|
||||
PRUint32 emptyCCMapOffset = currOffset;
|
||||
currOffset += CCMAP_EMPTY_SIZE_PER_INT16;
|
||||
|
||||
// Now fill all rest of the planes' ccmap and put off in array
|
||||
for (i = 0; i <aOtherPlaneNum; i++) {
|
||||
if (aOtherPlaneMaps[i]) {
|
||||
*(planeCCMapOffsets+i) = currOffset;
|
||||
otherPlaneObj[i].FillCCMap(ccmap+currOffset);
|
||||
currOffset += otherPlaneObj[i].GetSize();
|
||||
}
|
||||
else
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
for (; i < EXTENDED_UNICODE_PLANES; i++) {
|
||||
*(planeCCMapOffsets+i) = emptyCCMapOffset;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRUint32 k, h, l, plane, offset;
|
||||
PRBool oldb;
|
||||
PRBool newb;
|
||||
|
||||
// testing for BMP plane
|
||||
for (k=0; k<NUM_UNICODE_CHARS; k++) {
|
||||
oldb = IS_REPRESENTABLE(aBmpPlaneMap, k);
|
||||
newb = CCMAP_HAS_CHAR(ccmap, k);
|
||||
NS_ASSERTION(oldb==newb,"failed to generate map correctly");
|
||||
}
|
||||
|
||||
// testing for non-BMP plane
|
||||
for (h = 0; h < 0x400; h++) {
|
||||
for (l = 0; l < 0x400; l++) {
|
||||
plane = h >> 6;
|
||||
offset = (h*0x400 + l) & 0xffff;
|
||||
oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset);
|
||||
newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00);
|
||||
NS_ASSERTION(oldb==newb, "failed to generate extension map correctly");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ccmap;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,10 @@ extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
|||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
|
||||
// surrogate support extension
|
||||
extern PRUint16*
|
||||
MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum);
|
||||
|
||||
//
|
||||
// nsCompressedCharMap
|
||||
//
|
||||
|
@ -97,7 +101,8 @@ public:
|
|||
nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
void FreeCCMap(PRUint16*);
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
|
@ -172,6 +177,7 @@ protected:
|
|||
// One minor note: for a completely empty map it is actually
|
||||
// possible to fold the upper, empty mid, and empty page
|
||||
// on top of each other and make a map of only 32 bytes.
|
||||
#define CCMAP_EMPTY_SIZE_PER_INT16 16
|
||||
|
||||
// offsets to the empty mid and empty page
|
||||
#define CCMAP_EMPTY_MID CCMAP_NUM_UPPER_POINTERS
|
||||
|
@ -183,9 +189,50 @@ protected:
|
|||
// the actual needed size and simply copy over the data.
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Compressed Char map surrogate extension
|
||||
//
|
||||
// The design goal of surrogate support extension is to keep efficiency
|
||||
// and compatibility of existing compressed charmap operations. Most of
|
||||
// existing operation are untouched. For BMP support, very little memory
|
||||
// overhead (4 bytes) is added. Runtime efficiency of BMP support is
|
||||
// unchanged.
|
||||
//
|
||||
// structure of extended charmap:
|
||||
// ccmap flag 1 PRUint16 , indication if this is extended one or not
|
||||
// bmp ccmap size 1 PRUint16 , the size of BMP ccmap,
|
||||
// BMP ccmap size varies,
|
||||
// plane index 16 PRUint32, use to index ccmap for non-BMP plane
|
||||
// empty ccmap 16 PRUint16, a total empty ccmap
|
||||
// non-BMP ccmaps size varies, other non-empty, non-BMP ccmap
|
||||
//
|
||||
// Changes to basic ccmap
|
||||
// 2 PRUint16 are added in the very beginning. One is used to descript the size
|
||||
// of the ccmap, the other is used as a flag. But these 2 fields are indexed
|
||||
// negatively so that all other operation remain unchanged to keep efficiency.
|
||||
// ccmap memory allocation is moved from nsCompressedCharMap::NewCCMap to
|
||||
// MapToCCMap.
|
||||
//
|
||||
// Extended ccmap
|
||||
// A 16*PRUint32 array was put at the end of basic ccmap, each PRUint32 either
|
||||
// pointed to the empty ccmap or a independent plane ccmap. Directly after this
|
||||
// array is a empty ccmap. All planes that has no character will share this ccmap.
|
||||
// All non-empty plane will have a ccmap.
|
||||
// "MapToCCMapExt" is added to created an extended ccmap, each plane ccmap is
|
||||
// created the same as basic one, but without 2 additional fields.
|
||||
// "HasGlyphExt" is used to access extended ccmap, it first need to locate the
|
||||
// plane ccmap, and then operated the same way as "HasGlyph".
|
||||
//
|
||||
// Compatibility between old and new one
|
||||
// Because extended ccmap includes an exactly identical basic ccmap in its head,
|
||||
// basic ccmap operation (HasGlyph) can be applied on extended ccmap without
|
||||
// problem.
|
||||
// Because basic ccmap now has a flag to indicate if it is a extended one,
|
||||
// Extended ccmap operation (HasGlyphExt) can check the flag before it does
|
||||
// extended ccmap specific operation. So HasGlyphExt can be applied to basic ccmap
|
||||
// too.
|
||||
//
|
||||
|
||||
// Page bits
|
||||
//
|
||||
#define CCMAP_BITS_PER_PAGE_LOG2 8
|
||||
|
@ -264,4 +311,23 @@ protected:
|
|||
// unset the bit
|
||||
#define CCMAP_UNSET_CHAR(m,c) (CCMAP_TO_ALU(m,c) &= ~(CCMAP_POW2(CCMAP_BIT_INDEX(c))))
|
||||
|
||||
#define CCMAP_SIZE(m) (*((m)-1))
|
||||
#define CCMAP_FLAG(m) (*((m)-2))
|
||||
#define CCMAP_EXTRA (sizeof(ALU_TYPE)/sizeof(PRUint16)>2? sizeof(ALU_TYPE)/sizeof(PRUint16): 2)
|
||||
#define CCMAP_SURROGATE_FLAG 0X0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6)
|
||||
|
||||
// scalar value inside the plane
|
||||
#define CCMAP_INPLANE_OFFSET(h, l) (((((PRUint16)(h) - (PRUint16)0xd800) & 0x3f) << 10) + ((PRUint16)(l) - (PRUint16)0xdc00))
|
||||
|
||||
// get ccmap for that plane
|
||||
#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[i])
|
||||
|
||||
// test the bit for surrogate pair
|
||||
#define CCMAP_HAS_CHAR_EXT(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(h)), CCMAP_INPLANE_OFFSET(h, l)))
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
Загрузка…
Ссылка в новой задаче