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; }
void nsCompressedCharMap::SetChar(PRUint32 aChar) { if (mExtended) { PRUint32 plane_num = CCMAP_PLANE(aChar); NS_ASSERTION(plane_num <= EXTENDED_UNICODE_PLANES,"invalid plane"); if (plane_num <= EXTENDED_UNICODE_PLANES) { if (mExtMap[plane_num] == 0) { mExtMap[plane_num] = (PRUint32*)PR_Malloc(sizeof(PRUint32)*UCS2_MAP_LEN); NS_ASSERTION(mExtMap[plane_num], "failed to alloc new mExtMap"); if (!mExtMap[plane_num]) { return; } memset(mExtMap[plane_num], 0, sizeof(PRUint32)*UCS2_MAP_LEN); } SET_REPRESENTABLE(mExtMap[plane_num], aChar & 0xffff); } } else { NS_ASSERTION(aChar <= 0xffff, "extended char is passed"); unsigned int i; unsigned int upper_index = CCMAP_UPPER_INDEX(aChar); unsigned int mid_index = CCMAP_MID_INDEX(aChar); PRUint16 mid_offset = u.mCCMap[upper_index]; if (mid_offset == CCMAP_EMPTY_MID) { mid_offset = u.mCCMap[upper_index] = mUsedLen; mUsedLen += CCMAP_NUM_MID_POINTERS; NS_ASSERTION(mUsedLen<=CCMAP_MAX_LEN,"length too long"); // init the mid PRUint16 *mid = &u.mCCMap[mid_offset]; for (i=0; i<CCMAP_NUM_MID_POINTERS; i++) { NS_ASSERTION(mid[i]==0, "this mid pointer should be unused"); mid[i] = CCMAP_EMPTY_PAGE; } } PRUint16 page_offset = u.mCCMap[mid_offset+mid_index]; if (page_offset == CCMAP_EMPTY_PAGE) { page_offset = u.mCCMap[mid_offset+mid_index] = mUsedLen; mUsedLen += CCMAP_NUM_PRUINT16S_PER_PAGE; NS_ASSERTION(mUsedLen<=CCMAP_MAX_LEN,"length too long"); // init the page PRUint16 *page = &u.mCCMap[page_offset]; for (i=0; i<CCMAP_NUM_PRUINT16S_PER_PAGE; i++) { NS_ASSERTION(page[i]==0, "this page should be unused"); page[i] = 0; } } #undef CCMAP_SET_CHAR #define CCMAP_SET_CHAR(m,c) (CCMAP_TO_ALU(m,c) |= (CCMAP_POW2(CCMAP_BIT_INDEX(c)))) CCMAP_SET_CHAR(u.mCCMap,aChar); #undef CCMAP_SET_CHAR NS_ASSERTION(CCMAP_HAS_CHAR(u.mCCMap,aChar), "failed to set bit"); } }
short nsUnicodeFontMappingMac::GetFontID(PRUnichar aChar) { // initialize to bogus values short firstSymbolicFont = BAD_FONT_NUM, firstNonSymbolicFont = BAD_FONT_NUM; PRInt32 firstSymbolicFontIndex = -1; // Trap invisible chars if (CCMAP_HAS_CHAR_EXT(gIgnorableCCMapExt, aChar)) { return IGNORABLE_FONT_NUM; } // find the first symbolic font that has a glyph for aChar // and if there is one, remember it's index in the font list for(PRInt32 i = 0; i < mFontList.Count(); i++) { nsUnicodeFontMappingEntry* entry = (nsUnicodeFontMappingEntry*) mFontList[i]; PRUint16 *ccmap = entry->GetCCMap(); if(ccmap && CCMAP_HAS_CHAR(ccmap, aChar)) { firstSymbolicFontIndex = i; firstSymbolicFont = entry->GetFontNum(); break; } } // find the first non-symbolic font that has a glyph for aChar nsUnicodeBlock block = GetBlock(aChar); if(block < kUnicodeBlockFixedScriptMax) { firstNonSymbolicFont = mScriptFallbackFontIDs[gUtil->BlockToScript(block)]; // if there was no symbolic font we don't need to loop through the list again if(firstSymbolicFont == BAD_FONT_NUM) return firstNonSymbolicFont; // find the index of the first non symbolic font in the list and return the // first font (symbolic or non symbolic) in the list that has a glyph for this char for(PRInt32 i = 0; i < mFontList.Count(); i++) { nsUnicodeFontMappingEntry* entry = (nsUnicodeFontMappingEntry*) mFontList[i]; if(entry->GetFontNum() == firstNonSymbolicFont) { return (firstSymbolicFontIndex < i ? firstSymbolicFont : firstNonSymbolicFont); } } return firstNonSymbolicFont; } return (firstSymbolicFont != BAD_FONT_NUM ? firstSymbolicFont : mScriptFallbackFontIDs[ mPrivBlockToScript[ block - kUnicodeBlockFixedScriptMax] ]); }
void printCCMap(PRUint16* aCCMap) { PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP; while (NextNonEmptyCCMapPage(aCCMap, &page)) { //FONT_SCAN_PRINTF(("page starting at 0x%04x has chars", page)); int i; PRUint32 pagechar = page; printf("CCMap:0x%04lx=", (long)page); for (i=0; i<(CCMAP_BITS_PER_PAGE/8); i++) { unsigned char val = 0; for (int j=0; j<8; j++) { if (CCMAP_HAS_CHAR(aCCMap, pagechar)) { val |= 1 << j; } pagechar++; } printf("%02x", val); } printf("\n"); } }