Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsCompressedCharMap.cpp File Reference
#include <stdio.h>
#include "prmem.h"
#include "nsCRT.h"
#include "nsICharRepresentable.h"
#include "nsCompressedCharMap.h"

Go to the source code of this file.

Defines

#define CCMAP_MID_OFFSET(m, i)   ((m)[i])
#define CCMAP_PAGE_OFFSET_FROM_MIDOFFSET(m, midoffset, i)   ((m)[(i) + (midoffset)])
#define CCMAP_SET_CHAR(m, c)   (CCMAP_TO_ALU(m,c) |= (CCMAP_POW2(CCMAP_BIT_INDEX(c))))

Functions

void FreeCCMap (PRUint16 *&aMap)
PRUint16MapToCCMap (PRUint32 *aMap)
PRUint16CreateEmptyCCMap ()
PRUint16MapperToCCMap (nsICharRepresentable *aMapper)
PRBool NextNonEmptyCCMapPage (const PRUint16 *aCCMap, PRUint32 *aPageStart)
PRBool IsSameCCMap (PRUint16 *ccmap1, PRUint16 *ccmap2)
PRUint16MapToCCMapExt (PRUint32 *aBmpPlaneMap, PRUint32 **aOtherPlaneMaps, PRUint32 aOtherPlaneNum)

Define Documentation

#define CCMAP_MID_OFFSET (   m,
  i 
)    ((m)[i])

Definition at line 186 of file nsCompressedCharMap.cpp.

#define CCMAP_PAGE_OFFSET_FROM_MIDOFFSET (   m,
  midoffset,
  i 
)    ((m)[(i) + (midoffset)])

Definition at line 187 of file nsCompressedCharMap.cpp.


Function Documentation

Definition at line 85 of file nsCompressedCharMap.cpp.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void FreeCCMap ( PRUint16 *&  aMap)

Definition at line 46 of file nsCompressedCharMap.cpp.

{
  if (!aMap)
    return;
  PR_Free(aMap - CCMAP_EXTRA);
  aMap = nsnull;
}

Here is the caller graph for this function:

PRBool IsSameCCMap ( PRUint16 ccmap1,
PRUint16 ccmap2 
)

Definition at line 196 of file nsCompressedCharMap.cpp.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 101 of file nsCompressedCharMap.cpp.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 55 of file nsCompressedCharMap.cpp.

{
  // 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint16* MapToCCMapExt ( PRUint32 aBmpPlaneMap,
PRUint32 **  aOtherPlaneMaps,
PRUint32  aOtherPlaneNum 
)

Definition at line 542 of file nsCompressedCharMap.cpp.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool NextNonEmptyCCMapPage ( const PRUint16 aCCMap,
PRUint32 aPageStart 
)

Definition at line 114 of file nsCompressedCharMap.cpp.

{
  int i, j, l;
  int planeend = 0;
  int planestart = 0;
  unsigned int k;
  const PRUint16* ccmap;
  PRUint32 pagestart = *aPageStart;

  if(CCMAP_FLAG(aCCMap) & CCMAP_SURROGATE_FLAG) {
    // for SURROGATE
    planeend = EXTENDED_UNICODE_PLANES;
  }

  if(pagestart != CCMAP_BEGIN_AT_START_OF_MAP) {
    planestart = CCMAP_PLANE(pagestart);
  }

  // checking each plane
  for(l=planestart; l<=planeend; l++, pagestart = CCMAP_BEGIN_AT_START_OF_MAP) {

    if(l != 0 && CCMAP_FLAG(aCCMap) & CCMAP_SURROGATE_FLAG) {
      // for SURROGATE - get ccmap per plane
      ccmap = CCMAP_FOR_PLANE_EXT(aCCMap, l);
    } else {
      // only BMP
      ccmap = aCCMap;
    }
    //
    // Point to the next page
    //
    unsigned int upper_index;
    unsigned int mid_index;

    if (pagestart == CCMAP_BEGIN_AT_START_OF_MAP) {
      upper_index = 0;
      mid_index   = 0;
    } else {
      upper_index = CCMAP_UPPER_INDEX(pagestart & 0xffff);
      mid_index   = CCMAP_MID_INDEX(pagestart & 0xffff) + 1;
    }

    // walk thru the upper pointers
    const PRUint16 *upper = &ccmap[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
      const PRUint16 *mid = &ccmap[upper[i]];
      for (j=mid_index; j<CCMAP_NUM_MID_POINTERS; j++) {
        if (mid[j] == CCMAP_EMPTY_PAGE)
          continue;
  
        // walk the page
        const ALU_TYPE *page = (ALU_TYPE*)&ccmap[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");
            // return exact UCS4 code point, plane number + base
            *aPageStart = (((PRUint32)l)<<16)+base;
            return PR_TRUE;
          }
        }
      }
    }
  }
  return PR_FALSE;
}

Here is the caller graph for this function: