зеркало из https://github.com/mozilla/pjs.git
#120348 crash in macro CCMAP_HAS_CHAR_EXT
rewrite CCMAP_HAS_CHAR_EXT macro r=ftang, sr=attinasi
This commit is contained in:
Родитель
5adcad4348
Коммит
ab29096262
|
@ -320,7 +320,7 @@ protected:
|
|||
#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_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
|
@ -339,10 +339,11 @@ protected:
|
|||
#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_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \
|
||||
#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))
|
||||
#define CCMAP_HAS_CHAR_EXT(m, ucs4) (((ucs4)&0xffff0000) ? \
|
||||
(CCMAP_FLAG(m) & CCMAP_SURROGATE_FLAG) && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4) & 0xffff) : \
|
||||
CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) )
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
|
@ -555,7 +555,7 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe
|
|||
// testing for BMP plane
|
||||
for (k=0; k<NUM_UNICODE_CHARS; k++) {
|
||||
oldb = IS_REPRESENTABLE(aBmpPlaneMap, k);
|
||||
newb = CCMAP_HAS_CHAR(ccmap, k);
|
||||
newb = CCMAP_HAS_CHAR_EXT(ccmap, k);
|
||||
NS_ASSERTION(oldb==newb,"failed to generate map correctly");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,592 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Stell <bstell@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
|
||||
void
|
||||
FreeCCMap(PRUint16* &aMap)
|
||||
{
|
||||
if (!aMap)
|
||||
return;
|
||||
PR_Free(aMap - CCMAP_EXTRA);
|
||||
aMap = nsnull;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
PRUint16* CreateEmptyCCMap()
|
||||
{
|
||||
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*
|
||||
MapperToCCMap(nsICharRepresentable *aMapper)
|
||||
{
|
||||
PRUint32 map[UCS2_MAP_LEN];
|
||||
memset(map, 0, sizeof(map));
|
||||
nsresult res = aMapper->FillInfo(map);
|
||||
if (NS_FAILED(res))
|
||||
return nsnull;
|
||||
PRUint16* ccMap = MapToCCMap(map);
|
||||
|
||||
return ccMap;
|
||||
}
|
||||
|
||||
PRBool
|
||||
NextNonEmptyCCMapPage(PRUint16* aCCMap, PRUint16 *aPageStart)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int k;
|
||||
|
||||
//
|
||||
// Point to the next page
|
||||
//
|
||||
unsigned int upper_index;
|
||||
unsigned int mid_index;
|
||||
if (*aPageStart == CCMAP_BEGIN_AT_START_OF_MAP) {
|
||||
upper_index = 0;
|
||||
mid_index = 0;
|
||||
}
|
||||
else {
|
||||
upper_index = CCMAP_UPPER_INDEX(*aPageStart);
|
||||
mid_index = CCMAP_MID_INDEX(*aPageStart) + 1;
|
||||
}
|
||||
|
||||
|
||||
// walk thru the upper pointers
|
||||
PRUint16 *upper = &aCCMap[0];
|
||||
for (i=upper_index; i<CCMAP_NUM_UPPER_POINTERS; i++, mid_index=0) {
|
||||
if (upper[i] == CCMAP_EMPTY_MID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// walk the mid array
|
||||
PRUint16 *mid = &aCCMap[upper[i]];
|
||||
for (j=mid_index; j<CCMAP_NUM_MID_POINTERS; j++) {
|
||||
if (mid[j] == CCMAP_EMPTY_PAGE)
|
||||
continue;
|
||||
|
||||
// walk the page
|
||||
ALU_TYPE *page = (ALU_TYPE*)&aCCMap[mid[j]];
|
||||
for (k=0; k<CCMAP_NUM_ALUS_PER_PAGE; k++) {
|
||||
if (page[k] != 0) {
|
||||
PRUint32 base = (i*CCMAP_NUM_UCHARS_PER_MID) + (j*CCMAP_NUM_UCHARS_PER_PAGE);
|
||||
NS_ASSERTION(base<NUM_UNICODE_CHARS, "invalid page address");
|
||||
*aPageStart = (PRUint16)base;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#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 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;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
nsCompressedCharMap::NewCCMap()
|
||||
{
|
||||
PRUint16 *newMap = (PRUint16*)PR_Malloc((CCMAP_EXTRA + mUsedLen) * sizeof(PRUint16));
|
||||
NS_ASSERTION(newMap, "failed to alloc new CCMap");
|
||||
if (!newMap)
|
||||
return nsnull;
|
||||
|
||||
newMap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(newMap) = GetSize();
|
||||
CCMAP_FLAG(newMap) = CCMAP_NONE_FLAG;
|
||||
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
// transfer the data
|
||||
for (int i=0; i<mUsedLen; i++)
|
||||
aCCMap[i] = u.mCCMap[i];
|
||||
|
||||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
{
|
||||
// initialize map to have:
|
||||
// 1 upper pointer array
|
||||
// 1 empty mid pointer array
|
||||
// 1 empty page
|
||||
|
||||
int i;
|
||||
memset(u.mCCMap, 0, sizeof(u.mCCMap));
|
||||
mUsedLen = 0;
|
||||
mAllOnesPage = 0;
|
||||
|
||||
// init the upper pointers
|
||||
PRUint16 *upper = &u.mCCMap[0];
|
||||
for (i=0; i<CCMAP_NUM_UPPER_POINTERS; i++) {
|
||||
upper[i] = CCMAP_EMPTY_MID;
|
||||
}
|
||||
mUsedLen += CCMAP_NUM_UPPER_POINTERS;
|
||||
|
||||
// init the empty mid
|
||||
NS_ASSERTION(mUsedLen==CCMAP_EMPTY_MID, "empty mid offset misconfigured");
|
||||
PRUint16 *mid = &u.mCCMap[CCMAP_EMPTY_MID];
|
||||
for (i=0; i<CCMAP_NUM_MID_POINTERS; i++) {
|
||||
mid[i] = CCMAP_EMPTY_PAGE;
|
||||
}
|
||||
mUsedLen += CCMAP_NUM_MID_POINTERS;
|
||||
|
||||
// init the empty page
|
||||
NS_ASSERTION(mUsedLen==CCMAP_EMPTY_PAGE, "empty page offset misconfigured");
|
||||
// the page was zero'd by the memset above
|
||||
mUsedLen += CCMAP_NUM_PRUINT16S_PER_PAGE;
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChar(PRUint16 aChar)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChars(PRUint16 aBase, ALU_TYPE* aPage)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int upper_index = CCMAP_UPPER_INDEX(aBase);
|
||||
unsigned int mid_index = CCMAP_MID_INDEX(aBase);
|
||||
NS_ASSERTION((aBase&CCMAP_PAGE_MASK)==0, "invalid page address");
|
||||
|
||||
//
|
||||
// check of none/all bits set
|
||||
//
|
||||
PRUint16 num_none_set = 0;
|
||||
PRUint16 num_all_set = 0;
|
||||
for (i=0; i<CCMAP_NUM_ALUS_PER_PAGE; i++) {
|
||||
if (aPage[i] == 0)
|
||||
num_none_set++;
|
||||
else if (aPage[i] == CCMAP_ALU_MASK)
|
||||
num_all_set++;
|
||||
}
|
||||
if (num_none_set == CCMAP_NUM_ALUS_PER_PAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Alloc mid if necessary
|
||||
//
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if all bits set share an "all bits set" page
|
||||
//
|
||||
if (num_all_set == CCMAP_NUM_ALUS_PER_PAGE) {
|
||||
if (mAllOnesPage == 0) {
|
||||
mAllOnesPage = mUsedLen;
|
||||
mUsedLen += CCMAP_NUM_PRUINT16S_PER_PAGE;
|
||||
NS_ASSERTION(mUsedLen<=CCMAP_MAX_LEN,"length too long");
|
||||
ALU_TYPE *all_ones_page = (ALU_TYPE*)&u.mCCMap[mAllOnesPage];
|
||||
for (i=0; i<CCMAP_NUM_ALUS_PER_PAGE; i++) {
|
||||
NS_ASSERTION(all_ones_page[i]==0, "this page should be unused");
|
||||
all_ones_page[i] = CCMAP_ALU_MASK;
|
||||
}
|
||||
}
|
||||
u.mCCMap[mid_offset+mid_index] = mAllOnesPage;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Alloc page if necessary
|
||||
//
|
||||
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");
|
||||
}
|
||||
|
||||
// copy the page data
|
||||
ALU_TYPE *page = (ALU_TYPE*)&u.mCCMap[page_offset];
|
||||
for (i=0; i<CCMAP_NUM_ALUS_PER_PAGE; i++) {
|
||||
NS_ASSERTION(page[i]==0, "this page should be unused");
|
||||
page[i] = aPage[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChars(PRUint16* aCCMap)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
//
|
||||
// Copy the input CCMap
|
||||
//
|
||||
// walk thru the upper pointers
|
||||
PRUint16 *upper = &aCCMap[0];
|
||||
for (i=0; i<CCMAP_NUM_UPPER_POINTERS; i++) {
|
||||
if (upper[i] == CCMAP_EMPTY_MID)
|
||||
continue;
|
||||
|
||||
// walk the mid array
|
||||
PRUint16 *mid = &aCCMap[upper[i]];
|
||||
for (j=0; j<CCMAP_NUM_MID_POINTERS; j++) {
|
||||
if (mid[j] == CCMAP_EMPTY_PAGE)
|
||||
continue;
|
||||
|
||||
PRUint32 base = (i*CCMAP_NUM_UCHARS_PER_MID) + (j*CCMAP_NUM_UCHARS_PER_PAGE);
|
||||
NS_ASSERTION(base<NUM_UNICODE_CHARS, "invalid page address");
|
||||
ALU_TYPE *page = (ALU_TYPE*)&aCCMap[mid[j]];
|
||||
SetChars((PRUint16)base, page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChars(PRUint32* aMap)
|
||||
{
|
||||
PRUint32* frommap_page;
|
||||
frommap_page = aMap;
|
||||
PRUint16 base = 0;
|
||||
|
||||
for (int i=0; i<CCMAP_TOTAL_PAGES; i++) {
|
||||
|
||||
#if (CCMAP_BITS_PER_ALU == CCMAP_BITS_PER_PRUINT32)
|
||||
SetChars(base, (ALU_TYPE*)frommap_page);
|
||||
frommap_page += CCMAP_PRUINT32S_PER_PAGE;
|
||||
|
||||
#elif (CCMAP_BITS_PER_ALU > CCMAP_BITS_PER_PRUINT32)
|
||||
int j, k = CCMAP_BITS_PER_PRUINT32;
|
||||
ALU_TYPE page[CCMAP_NUM_ALUS_PER_PAGE];
|
||||
ALU_TYPE *p = page;
|
||||
for (j=0; j<CCMAP_ALUS_PER_PAGE; j++) {
|
||||
ALU_TYPE alu_val = 0;
|
||||
ALU_TYPE tmp;
|
||||
for (k=0; k<CCMAP_PRUINT32S_PER_ALU; k++) {
|
||||
tmp = *frommap_page;
|
||||
tmp <<= (k*CCMAP_BITS_PER_PRUINT32);
|
||||
//alu_val |= (*frommap_page)<<(k*CCMAP_BITS_PER_PRUINT32);
|
||||
alu_val |= tmp;
|
||||
frommap_page++;
|
||||
}
|
||||
*p++ = alu_val;
|
||||
}
|
||||
SetChars(base, page);
|
||||
#elif (CCMAP_BITS_PER_ALU < CCMAP_BITS_PER_PRUINT32)
|
||||
int j, k;
|
||||
ALU_TYPE page[CCMAP_NUM_ALUS_PER_PAGE];
|
||||
int v = CCMAP_PRUINT32S_PER_PAGE;
|
||||
ALU_TYPE *p = page;
|
||||
for (j=0; j<CCMAP_PRUINT32S_PER_PAGE; j++) {
|
||||
PRUint32 pruint32_val = *frommap_page++;
|
||||
for (k=0; k<CCMAP_ALUS_PER_PRUINT32; k++) {
|
||||
*p++ = pruint32_val & CCMAP_ALU_MASK;
|
||||
pruint32_val >>= CCMAP_BITS_PER_ALU;
|
||||
}
|
||||
}
|
||||
SetChars(base, page);
|
||||
#endif
|
||||
|
||||
base += CCMAP_NUM_UCHARS_PER_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
printCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
PRUint16 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");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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(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;
|
||||
}
|
|
@ -320,7 +320,7 @@ protected:
|
|||
#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_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
|
@ -339,10 +339,11 @@ protected:
|
|||
#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_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \
|
||||
#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))
|
||||
#define CCMAP_HAS_CHAR_EXT(m, ucs4) (((ucs4)&0xffff0000) ? \
|
||||
(CCMAP_FLAG(m) & CCMAP_SURROGATE_FLAG) && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4) & 0xffff) : \
|
||||
CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) )
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
|
@ -555,7 +555,7 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe
|
|||
// testing for BMP plane
|
||||
for (k=0; k<NUM_UNICODE_CHARS; k++) {
|
||||
oldb = IS_REPRESENTABLE(aBmpPlaneMap, k);
|
||||
newb = CCMAP_HAS_CHAR(ccmap, k);
|
||||
newb = CCMAP_HAS_CHAR_EXT(ccmap, k);
|
||||
NS_ASSERTION(oldb==newb,"failed to generate map correctly");
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ protected:
|
|||
#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_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
|
@ -339,10 +339,11 @@ protected:
|
|||
#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_EXT2(m, h, l) (CCMAP_FLAG(m)&CCMAP_SURROGATE_FLAG && \
|
||||
#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))
|
||||
#define CCMAP_HAS_CHAR_EXT(m, ucs4) (((ucs4)&0xffff0000) ? \
|
||||
(CCMAP_FLAG(m) & CCMAP_SURROGATE_FLAG) && CCMAP_HAS_CHAR(CCMAP_FOR_PLANE_EXT((m), CCMAP_PLANE(ucs4)), (ucs4) & 0xffff) : \
|
||||
CCMAP_HAS_CHAR(m, (PRUnichar)(ucs4)) )
|
||||
|
||||
#endif // NSCOMPRESSEDCHARMAP_H
|
||||
|
|
Загрузка…
Ссылка в новой задаче