diff --git a/gfx/public/nsCompressedCharMap.h b/gfx/public/nsCompressedCharMap.h index c4128e695cd..6e5ccfb0b7b 100644 --- a/gfx/public/nsCompressedCharMap.h +++ b/gfx/public/nsCompressedCharMap.h @@ -327,15 +327,22 @@ protected: #define EXTENDED_UNICODE_PLANES 16 // get plane number from ccmap, bmp excluded, so plane 1's number is 0. -#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6) +#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1) + +// same as above, but get plane number from a ucs4 char +#define CCMAP_PLANE(u) ((((PRUint32)(u))>>16)) // 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]) +#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[(i)-1]) // 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))) +#define CCMAP_HAS_CHAR_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \ + CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE_FROM_SURROGATE(h)), CCMAP_INPLANE_OFFSET(h, l))) +// test the bit for a character in UCS4 +#define CCMAP_HAS_CHAR_EXT(m, ucs4) (!((ucs4)&0xffff0000) && CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) || \ + CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4)&0xffff)) #endif // NSCOMPRESSEDCHARMAP_H diff --git a/gfx/src/nsCompressedCharMap.cpp b/gfx/src/nsCompressedCharMap.cpp index db4024256cd..b2e76ff0450 100644 --- a/gfx/src/nsCompressedCharMap.cpp +++ b/gfx/src/nsCompressedCharMap.cpp @@ -359,7 +359,6 @@ void nsCompressedCharMap::SetChars(PRUint16* aCCMap) { int i, j; - unsigned int k; // // Copy the input CCMap @@ -459,7 +458,6 @@ printCCMap(PRUint16* aCCMap) } #endif - // Non-BMP unicode support extension, create ccmap for both BMP and extended planes PRUint16* MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum) @@ -561,6 +559,20 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe NS_ASSERTION(oldb==newb,"failed to generate map correctly"); } + //testing for extension plane + for (k = 0x10000; k < 0x100000; k++) { + plane = k/0x10000; + if (plane > aOtherPlaneNum) + break; + if (aOtherPlaneMaps[plane-1]) + oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane-1], k&0xffff); + else + oldb = 0; + newb = CCMAP_HAS_CHAR_EXT(ccmap, k); + NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); + } + + // testing for non-BMP plane for (h = 0; h < 0x400; h++) { for (l = 0; l < 0x400; l++) { @@ -570,7 +582,7 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset); else oldb = 0; - newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00); + newb = CCMAP_HAS_CHAR_EXT2(ccmap, h+0xd800, l+0xdc00); NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); } } diff --git a/gfx/src/shared/nsCompressedCharMap.cpp b/gfx/src/shared/nsCompressedCharMap.cpp index db4024256cd..b2e76ff0450 100644 --- a/gfx/src/shared/nsCompressedCharMap.cpp +++ b/gfx/src/shared/nsCompressedCharMap.cpp @@ -359,7 +359,6 @@ void nsCompressedCharMap::SetChars(PRUint16* aCCMap) { int i, j; - unsigned int k; // // Copy the input CCMap @@ -459,7 +458,6 @@ printCCMap(PRUint16* aCCMap) } #endif - // Non-BMP unicode support extension, create ccmap for both BMP and extended planes PRUint16* MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum) @@ -561,6 +559,20 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe NS_ASSERTION(oldb==newb,"failed to generate map correctly"); } + //testing for extension plane + for (k = 0x10000; k < 0x100000; k++) { + plane = k/0x10000; + if (plane > aOtherPlaneNum) + break; + if (aOtherPlaneMaps[plane-1]) + oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane-1], k&0xffff); + else + oldb = 0; + newb = CCMAP_HAS_CHAR_EXT(ccmap, k); + NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); + } + + // testing for non-BMP plane for (h = 0; h < 0x400; h++) { for (l = 0; l < 0x400; l++) { @@ -570,7 +582,7 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset); else oldb = 0; - newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00); + newb = CCMAP_HAS_CHAR_EXT2(ccmap, h+0xd800, l+0xdc00); NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); } } diff --git a/gfx/src/shared/nsCompressedCharMap.h b/gfx/src/shared/nsCompressedCharMap.h index c4128e695cd..6e5ccfb0b7b 100644 --- a/gfx/src/shared/nsCompressedCharMap.h +++ b/gfx/src/shared/nsCompressedCharMap.h @@ -327,15 +327,22 @@ protected: #define EXTENDED_UNICODE_PLANES 16 // get plane number from ccmap, bmp excluded, so plane 1's number is 0. -#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6) +#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1) + +// same as above, but get plane number from a ucs4 char +#define CCMAP_PLANE(u) ((((PRUint32)(u))>>16)) // 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]) +#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[(i)-1]) // 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))) +#define CCMAP_HAS_CHAR_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \ + CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE_FROM_SURROGATE(h)), CCMAP_INPLANE_OFFSET(h, l))) +// test the bit for a character in UCS4 +#define CCMAP_HAS_CHAR_EXT(m, ucs4) (!((ucs4)&0xffff0000) && CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) || \ + CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4)&0xffff)) #endif // NSCOMPRESSEDCHARMAP_H diff --git a/gfx/src/windows/nsFontMetricsWin.cpp b/gfx/src/windows/nsFontMetricsWin.cpp index a0730c07e61..1a620e9d4a2 100644 --- a/gfx/src/windows/nsFontMetricsWin.cpp +++ b/gfx/src/windows/nsFontMetricsWin.cpp @@ -2274,7 +2274,7 @@ nsFontMetricsWin::SameAsPreviousMap(int aIndex) } nsFontWin* -nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c) +nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUint32 c) { //now try global font if (!gGlobalFonts) { @@ -2307,7 +2307,7 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c) continue; } } - if (CCMAP_HAS_CHAR(font->ccmap, c)) { + if (CCMAP_HAS_CHAR_EXT(font->ccmap, c)) { return LoadGlobalFont(aDC, font); } } @@ -2318,7 +2318,7 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c) // map to see if we can skip the lookup in FindGlobalFont(), and remember // to clear the map in UpdateFontList() when new fonts are installed nsFontWin* -nsFontMetricsWin::FindSubstituteFont(HDC aDC, PRUnichar c) +nsFontMetricsWin::FindSubstituteFont(HDC aDC, PRUint32 c) { /* When this function is called, it means all other alternatives have @@ -2798,7 +2798,7 @@ nsFontMetricsWin::LookForFontWeightTable(HDC aDC, nsString* aName) // ------------ End of font weight utilities nsFontWin* -nsFontMetricsWin::FindUserDefinedFont(HDC aDC, PRUnichar aChar) +nsFontMetricsWin::FindUserDefinedFont(HDC aDC, PRUint32 aChar) { if (mIsUserDefined) { // the user-defined font is always loaded as the first font @@ -2899,7 +2899,7 @@ nsFontMetricsWin::InitializeFamilyNames(void) } nsFontWin* -nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar) +nsFontMetricsWin::FindLocalFont(HDC aDC, PRUint32 aChar) { if (!gFamilyNames) { if (!InitializeFamilyNames()) { @@ -2927,7 +2927,7 @@ nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar) } nsFontWin* -nsFontMetricsWin::LoadGenericFont(HDC aDC, PRUnichar aChar, nsString* aName) +nsFontMetricsWin::LoadGenericFont(HDC aDC, PRUint32 aChar, nsString* aName) { for (int i = mLoadedFonts.Count()-1; i >= 0; --i) { if (aName->EqualsIgnoreCase(((nsFontWin*)mLoadedFonts[i])->mName)) { @@ -2944,7 +2944,7 @@ nsFontMetricsWin::LoadGenericFont(HDC aDC, PRUnichar aChar, nsString* aName) struct GenericFontEnumContext { HDC mDC; - PRUnichar mChar; + PRUint32 mChar; nsFontWin* mFont; nsFontMetricsWin* mMetrics; }; @@ -2954,7 +2954,7 @@ GenericFontEnumCallback(const nsString& aFamily, PRBool aGeneric, void* aData) { GenericFontEnumContext* context = (GenericFontEnumContext*)aData; HDC dc = context->mDC; - PRUnichar ch = context->mChar; + PRUint32 ch = context->mChar; nsFontMetricsWin* metrics = context->mMetrics; context->mFont = metrics->LoadGenericFont(dc, ch, (nsString*)&aFamily); if (context->mFont) { @@ -3003,7 +3003,7 @@ AppendGenericFontFromPref(nsString& aFontname, } nsFontWin* -nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar) +nsFontMetricsWin::FindGenericFont(HDC aDC, PRUint32 aChar) { if (mTriedAllGenerics) { // don't bother anymore because mLoadedFonts[] already has all our generic fonts @@ -3044,7 +3044,7 @@ nsFontMetricsWin::FindGenericFont(HDC aDC, PRUnichar aChar) } nsFontWin* -nsFontMetricsWin::FindPrefFont(HDC aDC, PRUnichar aChar) +nsFontMetricsWin::FindPrefFont(HDC aDC, PRUint32 aChar) { if (mTriedAllPref) { // don't bother anymore because mLoadedFonts[] already has all our pref fonts @@ -3092,7 +3092,7 @@ nsFontMetricsWin::FindPrefFont(HDC aDC, PRUnichar aChar) } nsFontWin* -nsFontMetricsWin::FindFont(HDC aDC, PRUnichar aChar) +nsFontMetricsWin::FindFont(HDC aDC, PRUint32 aChar) { nsFontWin* font = FindUserDefinedFont(aDC, aChar); if (!font) { @@ -3433,7 +3433,7 @@ nsFontMetricsWin::GetFontHandle(nsFontHandle &aHandle) } nsFontWin* -nsFontMetricsWin::LocateFont(HDC aDC, PRUnichar aChar, PRInt32 & aCount) +nsFontMetricsWin::LocateFont(HDC aDC, PRUint32 aChar, PRInt32 & aCount) { nsFontWin *font; PRInt32 i; @@ -3452,6 +3452,10 @@ nsFontMetricsWin::LocateFont(HDC aDC, PRUnichar aChar, PRInt32 & aCount) return font; } +#define IS_HIGH_SURROGATE(u) ((PRUnichar)(u) >= (PRUnichar)0xd800 && (PRUnichar)(u) <= (PRUnichar)0xdbff) +#define IS_LOW_SURROGATE(u) ((PRUnichar)(u) >= (PRUnichar)0xdc00 && (PRUnichar)(u) <= (PRUnichar)0xdfff) +#define SURROGATE_TO_UCS4(h, l) ((((PRUint32)(h)-(PRUint32)0xd800) << 10) + \ + (PRUint32)(l) - (PRUint32)(0xdc00) + 0x10000) nsresult nsFontMetricsWin::ResolveForwards(HDC aDC, const PRUnichar* aString, @@ -3473,12 +3477,20 @@ nsFontMetricsWin::ResolveForwards(HDC aDC, count = mLoadedFonts.Count(); - currFont = LocateFont(aDC, *currChar, count); + if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) { + currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); + currChar += 2; + } + else { + currFont = LocateFont(aDC, *currChar, count); + ++currChar; + } //This if block is mean to speedup the process in normal situation, when //most characters can be found in first font if (currFont == mLoadedFonts[0]) { - while (++currChar < lastChar && currFont->HasGlyph(*currChar)) ; + while (currChar < lastChar && (currFont->HasGlyph(*currChar))) + ++currChar; fontSwitch.mFontWin = currFont; if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData)) return NS_OK; @@ -3486,12 +3498,26 @@ nsFontMetricsWin::ResolveForwards(HDC aDC, return NS_OK; // continue with the next substring, re-using the available loaded fonts firstChar = currChar; - currFont = LocateFont(aDC, *currChar, count); + if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) { + currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); + currChar += 2; + } + else { + currFont = LocateFont(aDC, *currChar, count); + ++currChar; + } } // see if we can keep the same font for adjacent characters - while (++currChar < lastChar) { - nextFont = LocateFont(aDC, *currChar, count); + while (currChar < lastChar) { + if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) { + nextFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); + currChar += 2; + } + else { + nextFont = LocateFont(aDC, *currChar, count); + ++currChar; + } if (nextFont != currFont) { // We have a substring that can be represented with the same font, and // we are about to switch fonts, it is time to notify our caller. diff --git a/gfx/src/windows/nsFontMetricsWin.h b/gfx/src/windows/nsFontMetricsWin.h index a47e069716e..4038a1e6d17 100644 --- a/gfx/src/windows/nsFontMetricsWin.h +++ b/gfx/src/windows/nsFontMetricsWin.h @@ -35,18 +35,16 @@ #include "nsICharRepresentable.h" #include "nsCompressedCharMap.h" -#ifdef FONT_HAS_GLYPH -#undef FONT_HAS_GLYPH -#endif -//#define FONT_HAS_GLYPH(map, g) (((map)[(g) >> 3] >> ((g) & 7)) & 1) -#define FONT_HAS_GLYPH(map, g) IS_REPRESENTABLE(map, g) - #ifdef ADD_GLYPH #undef ADD_GLYPH #endif -//#define ADD_GLYPH(map, g) (map)[(g) >> 3] |= (1 << ((g) & 7)) #define ADD_GLYPH(map, g) SET_REPRESENTABLE(map, g) +#ifdef IS_IN_BMP +#undef IS_IN_BMP +#endif +#define IS_IN_BMP(ucs4) ((ucs4) < 0x10000) + enum eFontType { eFontType_UNKNOWN = -1, eFontType_Unicode, @@ -91,7 +89,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);}; + virtual PRBool HasGlyph(PRUint32 ch) {return CCMAP_HAS_CHAR_EXT(mCCMap, ch);}; #ifdef MOZ_MATHML virtual nsresult GetBoundingMetrics(HDC aDC, @@ -123,8 +121,8 @@ 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 PRBool HasGlyph(PRUint32 ch) {return IS_IN_BMP(ch) && IS_REPRESENTABLE(mRepresentableCharMap, ch);}; + virtual void SetRepresentable(PRUint32 ch) { if (IS_IN_BMP(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); @@ -217,16 +215,16 @@ public: nsFontSwitchCallback aFunc, void* aData); - nsFontWin* FindFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindUserDefinedFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindGenericFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindPrefFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar); - virtual nsFontWin* FindSubstituteFont(HDC aDC, PRUnichar aChar); + nsFontWin* FindFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindUserDefinedFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindLocalFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindGenericFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindPrefFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindGlobalFont(HDC aDC, PRUint32 aChar); + virtual nsFontWin* FindSubstituteFont(HDC aDC, PRUint32 aChar); virtual nsFontWin* LoadFont(HDC aDC, nsString* aName); - virtual nsFontWin* LoadGenericFont(HDC aDC, PRUnichar aChar, nsString* aName); + virtual nsFontWin* LoadGenericFont(HDC aDC, PRUint32 aChar, nsString* aName); virtual nsFontWin* LoadGlobalFont(HDC aDC, nsGlobalFont* aGlobalFontItem); virtual nsFontWin* LoadSubstituteFont(HDC aDC, nsString* aName); @@ -291,7 +289,7 @@ protected: PRInt32 GetFontWeight(PRInt32 aWeight, PRUint16 aWeightTable); PRInt32 GetClosestWeight(PRInt32 aWeight, PRUint16 aWeightTable); PRUint16 GetFontWeightTable(HDC aDC, nsString* aFontName); - nsFontWin* LocateFont(HDC aDC, PRUnichar aChar, PRInt32 & aCount); + nsFontWin* LocateFont(HDC aDC, PRUint32 aChar, PRInt32 & aCount); nsresult RealizeFont(); void FillLogFont(LOGFONT* aLogFont, PRInt32 aWeight, @@ -403,8 +401,8 @@ 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 PRBool HasGlyph(PRUint32 ch) {return IS_IN_BMP(ch) && IS_REPRESENTABLE(mRepresentableCharMap, ch);}; + virtual void SetRepresentable(PRUint32 ch) { if (IS_IN_BMP(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 diff --git a/intl/unicharutil/util/nsCompressedCharMap.cpp b/intl/unicharutil/util/nsCompressedCharMap.cpp index db4024256cd..b2e76ff0450 100644 --- a/intl/unicharutil/util/nsCompressedCharMap.cpp +++ b/intl/unicharutil/util/nsCompressedCharMap.cpp @@ -359,7 +359,6 @@ void nsCompressedCharMap::SetChars(PRUint16* aCCMap) { int i, j; - unsigned int k; // // Copy the input CCMap @@ -459,7 +458,6 @@ printCCMap(PRUint16* aCCMap) } #endif - // Non-BMP unicode support extension, create ccmap for both BMP and extended planes PRUint16* MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum) @@ -561,6 +559,20 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe NS_ASSERTION(oldb==newb,"failed to generate map correctly"); } + //testing for extension plane + for (k = 0x10000; k < 0x100000; k++) { + plane = k/0x10000; + if (plane > aOtherPlaneNum) + break; + if (aOtherPlaneMaps[plane-1]) + oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane-1], k&0xffff); + else + oldb = 0; + newb = CCMAP_HAS_CHAR_EXT(ccmap, k); + NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); + } + + // testing for non-BMP plane for (h = 0; h < 0x400; h++) { for (l = 0; l < 0x400; l++) { @@ -570,7 +582,7 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset); else oldb = 0; - newb = CCMAP_HAS_CHAR_EXT(ccmap, h+0xd800, l+0xdc00); + newb = CCMAP_HAS_CHAR_EXT2(ccmap, h+0xd800, l+0xdc00); NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); } } diff --git a/intl/unicharutil/util/nsCompressedCharMap.h b/intl/unicharutil/util/nsCompressedCharMap.h index c4128e695cd..6e5ccfb0b7b 100644 --- a/intl/unicharutil/util/nsCompressedCharMap.h +++ b/intl/unicharutil/util/nsCompressedCharMap.h @@ -327,15 +327,22 @@ protected: #define EXTENDED_UNICODE_PLANES 16 // get plane number from ccmap, bmp excluded, so plane 1's number is 0. -#define CCMAP_PLANE(h) (((PRUint16)(h) - (PRUint16)0xd800) >> 6) +#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1) + +// same as above, but get plane number from a ucs4 char +#define CCMAP_PLANE(u) ((((PRUint32)(u))>>16)) // 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]) +#define CCMAP_FOR_PLANE_EXT(m, i) ((m) + ((PRUint32*)((m) + CCMAP_SIZE(m)))[(i)-1]) // 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))) +#define CCMAP_HAS_CHAR_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \ + CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE_FROM_SURROGATE(h)), CCMAP_INPLANE_OFFSET(h, l))) +// test the bit for a character in UCS4 +#define CCMAP_HAS_CHAR_EXT(m, ucs4) (!((ucs4)&0xffff0000) && CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) || \ + CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4)&0xffff)) #endif // NSCOMPRESSEDCHARMAP_H