PRUint16* MapToCCMap(PRUint32* aMap) { // put the data into a temp map nsCompressedCharMap ccmapObj; ccmapObj.SetChars(aMap); 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++) { PRBool oldb = IS_REPRESENTABLE(aMap, i); PRBool newb = CCMAP_HAS_CHAR(ccmap, i); if ((oldb) != (newb)) { NS_ASSERTION(oldb==newb,"failed to generate map correctly"); } } #endif return ccmap; }
FcCharSet * mozilla_decoder_get_charset (PangoFcDecoder *decoder, PangoFcFont *fcfont) { MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); if (priv->charset) return priv->charset; // First time this has been accessed. Populate the charset. priv->charset = FcCharSetCreate(); if (!gCharsetManager) { CallGetService(kCharsetConverterManagerCID, &gCharsetManager); } nsCOMPtr<nsIUnicodeEncoder> encoder; nsCOMPtr<nsICharRepresentable> represent; if (!gCharsetManager) goto end; gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder)); if (!encoder) goto end; encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?'); priv->uEncoder = encoder; represent = do_QueryInterface(encoder); if (!represent) goto end; PRUint32 map[UCS2_MAP_LEN]; memset(map, 0, sizeof(map)); represent->FillInfo(map); for (int i = 0; i < NUM_UNICODE_CHARS; i++) { if (IS_REPRESENTABLE(map, i)) FcCharSetAddChar(priv->charset, i); } end: return priv->charset; }
// Non-BMP unicode support extension, create ccmap for both BMP and extended planes PRUint16* MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOtherPlaneNum) { nsCompressedCharMap* otherPlaneObj[EXTENDED_UNICODE_PLANES]; 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] = new nsCompressedCharMap(); NS_ASSERTION(otherPlaneObj, "unable to create new nsCompressedCharMap"); if(otherPlaneObj) { otherPlaneObj[i]->SetChars(aOtherPlaneMaps[i]); totalSize += otherPlaneObj[i]->GetSize(); } } else { otherPlaneObj[i] = nsnull; } } 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] && otherPlaneObj[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; } // remove all nsCompressedCharMap objects allocated for (i = 0; i < aOtherPlaneNum; i++) { if (otherPlaneObj[i]) delete otherPlaneObj[i]; } #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_EXT(ccmap, k); 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++) { plane = h >> 6; offset = (h*0x400 + l) & 0xffff; if (aOtherPlaneMaps[plane]) oldb = IS_REPRESENTABLE(aOtherPlaneMaps[plane], offset); else oldb = 0; newb = CCMAP_HAS_CHAR_EXT2(ccmap, h+0xd800, l+0xdc00); NS_ASSERTION(oldb==newb, "failed to generate extension map correctly"); } } #endif return ccmap; }