зеркало из https://github.com/mozilla/pjs.git
bug 127713
support Surrogate display on Linux by using FreeType r=bstell, sr=bryner
This commit is contained in:
Родитель
44f475da93
Коммит
dadd6c39ce
|
@ -113,5 +113,8 @@ interface nsIFreeType2 : nsISupports
|
|||
in FTC_Face_Requester requester, in FT_Pointer req_data,
|
||||
out FTC_Manager manager);
|
||||
void imageCacheNew(in FTC_Manager manager, out FTC_Image_Cache cache);
|
||||
};
|
||||
|
||||
FT_ULong getFirstChar(in FT_Face face, out FT_UInt gindex);
|
||||
FT_ULong getNextChar(in FT_Face face, in FT_ULong charcode, out FT_UInt gindex);
|
||||
void supportsExtFunc(out PRBool res);
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#ifndef NSCOMPRESSEDCHARMAP_H
|
||||
#define NSCOMPRESSEDCHARMAP_H
|
||||
#include "prtypes.h"
|
||||
|
||||
#include "nsICharRepresentable.h"
|
||||
|
||||
#define ALU_SIZE PR_BITS_PER_LONG
|
||||
//#define ALU_SIZE 16
|
||||
|
@ -67,7 +67,7 @@ extern PRUint16* CreateEmptyCCMap();
|
|||
extern PRUint16* MapToCCMap(PRUint32* aMap);
|
||||
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
||||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint16 *);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint32 *);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
#ifdef DEBUG
|
||||
void printCCMap(PRUint16* aCCMap);
|
||||
|
@ -101,17 +101,22 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe
|
|||
// (256*16 max pages) = 4400 PRUint16
|
||||
#define CCMAP_MAX_LEN (16+16+16+256+4096)
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
class nsCompressedCharMap {
|
||||
public:
|
||||
nsCompressedCharMap();
|
||||
~nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChar(PRUint32);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
void SetChars(PRUint32*);
|
||||
void Extend() {mExtended = PR_TRUE;} // enable surrogate area
|
||||
|
||||
protected:
|
||||
union {
|
||||
|
@ -122,6 +127,11 @@ protected:
|
|||
PRUint16 mUsedLen; // in PRUint16
|
||||
PRUint16 mAllOnesPage;
|
||||
|
||||
PRBool mExtended;
|
||||
|
||||
// for surrogate support
|
||||
PRUint32* mExtMap[EXTENDED_UNICODE_PLANES+1];
|
||||
PRUint32 mMap[UCS2_MAP_LEN];
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -295,7 +305,7 @@ protected:
|
|||
#define CCMAP_TOTAL_PAGES CCMAP_POW2(CCMAP_BITS_PER_UPPER_LOG2 \
|
||||
+CCMAP_BITS_PER_MID_LOG2)
|
||||
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFF
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFFFFFF
|
||||
|
||||
//
|
||||
// Finally, build up the macro to test the bit for a given char
|
||||
|
@ -323,9 +333,6 @@ protected:
|
|||
#define CCMAP_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1)
|
||||
|
||||
|
@ -345,5 +352,4 @@ protected:
|
|||
#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
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
|
@ -75,6 +76,7 @@ nsHashtable* nsFreeType2::sFontFamilies = nsnull;
|
|||
nsHashtable* nsFreeType2::sRange1CharSetNames = nsnull;
|
||||
nsHashtable* nsFreeType2::sRange2CharSetNames = nsnull;
|
||||
nsICharsetConverterManager2* nsFreeType2::sCharSetManager = nsnull;
|
||||
PRBool nsFreeType2::gHasExtFunc = PR_TRUE;
|
||||
|
||||
extern nsulCodePageRangeCharSetName ulCodePageRange1CharSetNames[];
|
||||
extern nsulCodePageRangeCharSetName ulCodePageRange2CharSetNames[];
|
||||
|
@ -96,24 +98,26 @@ static NS_DEFINE_CID(kCharSetManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
|||
//
|
||||
#define NS_FT2_OFFSET(f) (int)&((nsFreeType2*)0)->f
|
||||
FtFuncList nsFreeType2::FtFuncs [] = {
|
||||
{"FT_Done_Face", NS_FT2_OFFSET(nsFT_Done_Face)},
|
||||
{"FT_Done_FreeType", NS_FT2_OFFSET(nsFT_Done_FreeType)},
|
||||
{"FT_Done_Glyph", NS_FT2_OFFSET(nsFT_Done_Glyph)},
|
||||
{"FT_Get_Char_Index", NS_FT2_OFFSET(nsFT_Get_Char_Index)},
|
||||
{"FT_Get_Glyph", NS_FT2_OFFSET(nsFT_Get_Glyph)},
|
||||
{"FT_Get_Sfnt_Table", NS_FT2_OFFSET(nsFT_Get_Sfnt_Table)},
|
||||
{"FT_Glyph_Get_CBox", NS_FT2_OFFSET(nsFT_Glyph_Get_CBox)},
|
||||
{"FT_Init_FreeType", NS_FT2_OFFSET(nsFT_Init_FreeType)},
|
||||
{"FT_Load_Glyph", NS_FT2_OFFSET(nsFT_Load_Glyph)},
|
||||
{"FT_New_Face", NS_FT2_OFFSET(nsFT_New_Face)},
|
||||
{"FT_Outline_Decompose", NS_FT2_OFFSET(nsFT_Outline_Decompose)},
|
||||
{"FT_Set_Charmap", NS_FT2_OFFSET(nsFT_Set_Charmap)},
|
||||
{"FTC_Image_Cache_Lookup", NS_FT2_OFFSET(nsFTC_Image_Cache_Lookup)},
|
||||
{"FTC_Manager_Lookup_Size", NS_FT2_OFFSET(nsFTC_Manager_Lookup_Size)},
|
||||
{"FTC_Manager_Done", NS_FT2_OFFSET(nsFTC_Manager_Done)},
|
||||
{"FTC_Manager_New", NS_FT2_OFFSET(nsFTC_Manager_New)},
|
||||
{"FTC_Image_Cache_New", NS_FT2_OFFSET(nsFTC_Image_Cache_New)},
|
||||
{nsnull, 0},
|
||||
{"FT_Done_Face", NS_FT2_OFFSET(nsFT_Done_Face), PR_TRUE},
|
||||
{"FT_Done_FreeType", NS_FT2_OFFSET(nsFT_Done_FreeType), PR_TRUE},
|
||||
{"FT_Done_Glyph", NS_FT2_OFFSET(nsFT_Done_Glyph), PR_TRUE},
|
||||
{"FT_Get_Char_Index", NS_FT2_OFFSET(nsFT_Get_Char_Index), PR_TRUE},
|
||||
{"FT_Get_Glyph", NS_FT2_OFFSET(nsFT_Get_Glyph), PR_TRUE},
|
||||
{"FT_Get_Sfnt_Table", NS_FT2_OFFSET(nsFT_Get_Sfnt_Table), PR_TRUE},
|
||||
{"FT_Glyph_Get_CBox", NS_FT2_OFFSET(nsFT_Glyph_Get_CBox), PR_TRUE},
|
||||
{"FT_Init_FreeType", NS_FT2_OFFSET(nsFT_Init_FreeType), PR_TRUE},
|
||||
{"FT_Load_Glyph", NS_FT2_OFFSET(nsFT_Load_Glyph), PR_TRUE},
|
||||
{"FT_New_Face", NS_FT2_OFFSET(nsFT_New_Face), PR_TRUE},
|
||||
{"FT_Outline_Decompose", NS_FT2_OFFSET(nsFT_Outline_Decompose), PR_TRUE},
|
||||
{"FT_Set_Charmap", NS_FT2_OFFSET(nsFT_Set_Charmap), PR_TRUE},
|
||||
{"FTC_Image_Cache_Lookup", NS_FT2_OFFSET(nsFTC_Image_Cache_Lookup), PR_TRUE},
|
||||
{"FTC_Manager_Lookup_Size", NS_FT2_OFFSET(nsFTC_Manager_Lookup_Size), PR_TRUE},
|
||||
{"FTC_Manager_Done", NS_FT2_OFFSET(nsFTC_Manager_Done), PR_TRUE},
|
||||
{"FTC_Manager_New", NS_FT2_OFFSET(nsFTC_Manager_New), PR_TRUE},
|
||||
{"FTC_Image_Cache_New", NS_FT2_OFFSET(nsFTC_Image_Cache_New), PR_TRUE},
|
||||
{"FT_Get_First_Char", NS_FT2_OFFSET(nsFT_Get_First_Char), PR_FALSE},
|
||||
{"FT_Get_Next_Char", NS_FT2_OFFSET(nsFT_Get_Next_Char), PR_FALSE},
|
||||
{nsnull, 0, 0},
|
||||
};
|
||||
|
||||
nsTTFontEncoderInfo FEI_Adobe_Symbol_Encoding = {
|
||||
|
@ -204,7 +208,7 @@ nsFreeType2::GetCharIndex(FT_Face face, FT_ULong charcode, FT_UInt *index)
|
|||
*index = nsFT_Get_Char_Index(face, charcode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFreeType2::GetGlyph(FT_GlyphSlot slot, FT_Glyph *glyph)
|
||||
{
|
||||
|
@ -316,6 +320,29 @@ nsFreeType2::ImageCacheNew(FTC_Manager manager, FTC_Image_Cache *cache)
|
|||
FT_Error error = nsFTC_Image_Cache_New(manager, cache);
|
||||
return error ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFreeType2::GetFirstChar(FT_Face face, FT_UInt *gindex, FT_ULong *charcode)
|
||||
{
|
||||
// call the FreeType2 function via the function pointer
|
||||
*charcode = nsFT_Get_First_Char(face, gindex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFreeType2::GetNextChar(FT_Face face, FT_ULong charcode, FT_UInt *gindex, FT_ULong *ncharcode)
|
||||
{
|
||||
// call the FreeType2 function via the function pointer
|
||||
*ncharcode = nsFT_Get_Next_Char(face, charcode, gindex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFreeType2::SupportsExtFunc(PRBool *res)
|
||||
{
|
||||
*res = gHasExtFunc;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFreeType2::GetImageCache(FTC_Image_Cache *aCache)
|
||||
|
@ -621,15 +648,22 @@ nsFreeType2::LoadSharedLib()
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// checking FT_Get_First_Char() and FT_Get_Next_Char() for fast lookup methods
|
||||
gHasExtFunc = PR_TRUE;
|
||||
FtFuncList *p;
|
||||
PRFuncPtr func;
|
||||
void *ptr = this;
|
||||
for (p=FtFuncs; p->FuncName; p++) {
|
||||
func = PR_FindFunctionSymbol(mSharedLib, p->FuncName);
|
||||
if (!func) {
|
||||
NS_WARNING("nsFreeType2::LoadSharedLib Error");
|
||||
ClearFunctions();
|
||||
return PR_FALSE;
|
||||
if (p->Required == PR_TRUE) {
|
||||
NS_WARNING("nsFreeType2::LoadSharedLib Error");
|
||||
ClearFunctions();
|
||||
return PR_FALSE;
|
||||
} else {
|
||||
// should not return, but disable fast lookup methods
|
||||
gHasExtFunc = PR_FALSE;
|
||||
}
|
||||
}
|
||||
*((PRFuncPtr*)((char*)ptr+p->FuncOffset)) = func;
|
||||
}
|
||||
|
@ -720,6 +754,9 @@ PRUint16*
|
|||
nsFreeType2::GetCCMap(nsFontCatalogEntry *aFce)
|
||||
{
|
||||
nsCompressedCharMap ccmapObj;
|
||||
if (aFce->mFlags & FCE_FLAGS_SURROGATE) {
|
||||
ccmapObj.Extend();
|
||||
}
|
||||
ccmapObj.SetChars(aFce->mCCMap);
|
||||
return ccmapObj.NewCCMap();
|
||||
}
|
||||
|
@ -954,15 +991,32 @@ nsFreeTypeFaceRequester(FTC_FaceID face_id, FT_Library lib,
|
|||
platform_id = ffei->mEncodingInfo->mCmapPlatformID;
|
||||
encoding_id = ffei->mEncodingInfo->mCmapEncoding;
|
||||
}
|
||||
|
||||
for (int i=0; i < face->num_charmaps; i++) {
|
||||
if ( (face->charmaps[i]->platform_id == platform_id)
|
||||
&& (face->charmaps[i]->encoding_id == encoding_id)) {
|
||||
rv = ft2->SetCharmap(face, face->charmaps[i]);
|
||||
if (NS_FAILED(rv)) {
|
||||
FREETYPE_PRINTF(("failed to set cmap"));
|
||||
ft2->DoneFace(face);
|
||||
*aFace = nsnull;
|
||||
fterror = 1;
|
||||
if (face->charmaps[i]->platform_id == platform_id) {
|
||||
#if defined(TT_MS_ID_UCS_4)
|
||||
if (face->charmaps[i]->encoding_id == TT_MS_ID_UCS_4) {
|
||||
rv = ft2->SetCharmap(face, face->charmaps[i]);
|
||||
if (NS_FAILED(rv)) {
|
||||
FREETYPE_PRINTF(("failed to set cmap"));
|
||||
ft2->DoneFace(face);
|
||||
*aFace = nsnull;
|
||||
fterror = 1;
|
||||
}
|
||||
// UCS_4 is the most prefered cmap since it supports surrogates
|
||||
// so stop here to avoid the possibly of getting UNICODE_CS which
|
||||
// is the 2nd prefered choice.
|
||||
break;
|
||||
} else
|
||||
#endif /* defined(TT_MS_ID_UCS_4) */
|
||||
if (face->charmaps[i]->encoding_id == encoding_id) {
|
||||
rv = ft2->SetCharmap(face, face->charmaps[i]);
|
||||
if (NS_FAILED(rv)) {
|
||||
FREETYPE_PRINTF(("failed to set cmap"));
|
||||
ft2->DoneFace(face);
|
||||
*aFace = nsnull;
|
||||
fterror = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,9 +63,10 @@ typedef struct {
|
|||
PRUint16 *mCCMap; // compressed char map
|
||||
} nsFontCatalogEntry;
|
||||
|
||||
#define FCE_FLAGS_ISVALID 0x01
|
||||
#define FCE_FLAGS_UNICODE 0x02
|
||||
#define FCE_FLAGS_SYMBOL 0x04
|
||||
#define FCE_FLAGS_ISVALID 0x01
|
||||
#define FCE_FLAGS_UNICODE 0x02
|
||||
#define FCE_FLAGS_SYMBOL 0x04
|
||||
#define FCE_FLAGS_SURROGATE 0x08
|
||||
#define FREE_IF(x) if(x) free((void*)x)
|
||||
|
||||
typedef struct {
|
||||
|
@ -110,6 +111,9 @@ typedef FT_Error (*FTC_Manager_New_t)(FT_Library, FT_UInt, FT_UInt, FT_ULong,
|
|||
FTC_Face_Requester, FT_Pointer, FTC_Manager*);
|
||||
typedef FT_Error (*FTC_Image_Cache_New_t)(FTC_Manager, FTC_Image_Cache*);
|
||||
|
||||
typedef FT_ULong (*FT_Get_First_Char_t)(FT_Face, FT_UInt*);
|
||||
typedef FT_ULong (*FT_Get_Next_Char_t)(FT_Face, FT_ULong, FT_UInt*);
|
||||
|
||||
class nsFreeTypeFace;
|
||||
|
||||
nsFreeTypeFace * nsFreeTypeGetFaceID(nsFontCatalogEntry *aFce);
|
||||
|
@ -117,6 +121,7 @@ nsFreeTypeFace * nsFreeTypeGetFaceID(nsFontCatalogEntry *aFce);
|
|||
typedef struct {
|
||||
const char *FuncName;
|
||||
int FuncOffset;
|
||||
const PRBool Required;
|
||||
} FtFuncList;
|
||||
|
||||
// class nsFreeType class definition
|
||||
|
@ -155,9 +160,12 @@ protected:
|
|||
FTC_Manager_Done_t nsFTC_Manager_Done;
|
||||
FTC_Manager_New_t nsFTC_Manager_New;
|
||||
FTC_Image_Cache_New_t nsFTC_Image_Cache_New;
|
||||
FT_Get_First_Char_t nsFT_Get_First_Char;
|
||||
FT_Get_Next_Char_t nsFT_Get_Next_Char;
|
||||
|
||||
// this array needs to be big enough to hold all the function pointers
|
||||
// plus one extra for the null at the end
|
||||
static FtFuncList FtFuncs[18];
|
||||
static FtFuncList FtFuncs[20];
|
||||
|
||||
protected:
|
||||
PRBool mEnableFreeType2;
|
||||
|
@ -171,6 +179,7 @@ public:
|
|||
static double gAATTDarkTextGain;
|
||||
static PRInt32 gAntiAliasMinimum;
|
||||
static PRInt32 gEmbeddedBitmapMaximumHeight;
|
||||
static PRBool gHasExtFunc;
|
||||
|
||||
protected:
|
||||
void ClearGlobals();
|
||||
|
@ -217,6 +226,8 @@ public:
|
|||
PRUint16 *GetCCMap();
|
||||
nsFontCatalogEntry* GetFce() { return mFce; };
|
||||
|
||||
PRBool mHasExtendFuncs;
|
||||
|
||||
protected:
|
||||
nsFontCatalogEntry *mFce;
|
||||
PRUint16 *mCCMap;
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
#include <X11/Xatom.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#define IS_SURROGATE(u) (u > 0x10000)
|
||||
|
||||
#define UCS2_NOMAPPING 0XFFFD
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -1479,6 +1481,7 @@ NS_IMETHODIMP nsFontMetricsGTK::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
mCurrentFont = mWesternFont;
|
||||
|
||||
RealizeFont();
|
||||
|
@ -1823,7 +1826,7 @@ nsFontMetricsGTK::LocateFont(PRUint32 aChar, PRInt32 & aCount)
|
|||
// see if one of our loaded fonts can represent the character
|
||||
for (i = 0; i < aCount; ++i) {
|
||||
font = (nsFontGTK*)mLoadedFonts[i];
|
||||
if (CCMAP_HAS_CHAR(font->mCCMap, aChar))
|
||||
if (CCMAP_HAS_CHAR_EXT(font->mCCMap, aChar))
|
||||
return font;
|
||||
}
|
||||
|
||||
|
@ -1865,7 +1868,7 @@ nsFontMetricsGTK::ResolveForwards(const PRUnichar *aString,
|
|||
//This if block is meant to speedup the process in normal situation, when
|
||||
//most characters can be found in first font
|
||||
if (currFont == mLoadedFonts[0]) {
|
||||
while (currChar < lastChar && CCMAP_HAS_CHAR(currFont->mCCMap,*currChar))
|
||||
while (currChar < lastChar && CCMAP_HAS_CHAR_EXT(currFont->mCCMap,*currChar))
|
||||
++currChar;
|
||||
fontSwitch.mFontGTK = currFont;
|
||||
if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData))
|
||||
|
@ -2346,7 +2349,7 @@ DumpTree(void)
|
|||
struct nsFontSearch
|
||||
{
|
||||
nsFontMetricsGTK* mMetrics;
|
||||
PRUnichar mChar;
|
||||
PRUint32 mChar;
|
||||
nsFontGTK* mFont;
|
||||
};
|
||||
|
||||
|
@ -3131,12 +3134,12 @@ nsFontMetricsGTK::FindNearestSize(nsFontStretch* aStretch, PRUint16 aSize)
|
|||
|
||||
static PRBool
|
||||
SetFontCharsetInfo(nsFontGTK *aFont, nsFontCharSetInfo* aCharSet,
|
||||
PRUnichar aChar)
|
||||
PRUint32 aChar)
|
||||
{
|
||||
if (aCharSet->mCharSet) {
|
||||
aFont->mCCMap = aCharSet->mCCMap;
|
||||
// check that the font is not empty
|
||||
if (CCMAP_HAS_CHAR(aFont->mCCMap, aChar)) {
|
||||
if (CCMAP_HAS_CHAR_EXT(aFont->mCCMap, aChar)) {
|
||||
aFont->LoadFont();
|
||||
if (!aFont->GetXFont()) {
|
||||
return PR_FALSE;
|
||||
|
@ -3188,7 +3191,7 @@ nsFontMetricsGTK::GetAASBBaseFont(nsFontStretch* aStretch,
|
|||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch,
|
||||
nsFontCharSetInfo* aCharSet, PRUnichar aChar, const char *aName)
|
||||
nsFontCharSetInfo* aCharSet, PRUint32 aChar, const char *aName)
|
||||
{
|
||||
if (aStretch->mFreeTypeFaceID) {
|
||||
//FREETYPE_FONT_PRINTF(("mFreeTypeFaceID = 0x%p", aStretch->mFreeTypeFaceID));
|
||||
|
@ -3218,6 +3221,11 @@ nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch,
|
|||
return AddToLoadedFontsList(ftfont);
|
||||
}
|
||||
|
||||
if (IS_SURROGATE(aChar)) {
|
||||
// SURROGATE is only supported by FreeType
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool use_scaled_font = PR_FALSE;
|
||||
PRBool have_nearly_rightsized_bitmap = PR_FALSE;
|
||||
nsFontGTK* base_aafont = nsnull;
|
||||
|
@ -3444,13 +3452,24 @@ nsFontMetricsGTK::GetWidth (const PRUnichar* aString, PRUint32 aLength,
|
|||
PRUint32 start = 0;
|
||||
PRUint32 i;
|
||||
|
||||
for (i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
PRUint32 extraSurrogateLength;
|
||||
for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
|
||||
PRUint32 c = aString[i];
|
||||
extraSurrogateLength=0;
|
||||
|
||||
if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] and
|
||||
// low surrogate aString[i+1]
|
||||
c = SURROGATE_TO_UCS4(c, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
nsFontGTK* currFont = nsnull;
|
||||
nsFontGTK** font = mLoadedFonts;
|
||||
nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) {
|
||||
if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
|
@ -3611,13 +3630,23 @@ nsFontMetricsGTK::DrawString(const PRUnichar* aString, PRUint32 aLength,
|
|||
PRUint32 start = 0;
|
||||
PRUint32 i;
|
||||
|
||||
for (i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
PRUint32 extraSurrogateLength;
|
||||
for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
|
||||
PRUint32 c = aString[i];
|
||||
extraSurrogateLength=0;
|
||||
if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] and
|
||||
// low surrogate aString[i+1]
|
||||
c = SURROGATE_TO_UCS4(c, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
nsFontGTK* currFont = nsnull;
|
||||
nsFontGTK** font = mLoadedFonts;
|
||||
nsFontGTK** lastFont = &mLoadedFonts[mLoadedFontsCount];
|
||||
while (font < lastFont) {
|
||||
if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) {
|
||||
if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
|
@ -3787,15 +3816,24 @@ nsFontMetricsGTK::GetBoundingMetrics(const PRUnichar *aString,
|
|||
PRBool firstTime = PR_TRUE;
|
||||
PRUint32 start = 0;
|
||||
PRUint32 i;
|
||||
|
||||
for (i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
PRUint32 extraSurrogateLength;
|
||||
for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
|
||||
PRUint32 c = aString[i];
|
||||
extraSurrogateLength=0;
|
||||
if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] and
|
||||
// low surrogate aString[i+1]
|
||||
c = SURROGATE_TO_UCS4(c, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
nsFontGTK* currFont = nsnull;
|
||||
nsFontGTK** font = mLoadedFonts;
|
||||
nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount];
|
||||
|
||||
while (font < end) {
|
||||
if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) {
|
||||
if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
|
@ -3872,14 +3910,24 @@ nsFontMetricsGTK::GetTextDimensions (const PRUnichar* aString,
|
|||
PRUint32 start = 0;
|
||||
PRUint32 i;
|
||||
|
||||
for (i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
PRUint32 extraSurrogateLength;
|
||||
for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
|
||||
PRUint32 c = aString[i];
|
||||
extraSurrogateLength=0;
|
||||
if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] and
|
||||
// low surrogate aString[i+1]
|
||||
c = SURROGATE_TO_UCS4(c, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
nsFontGTK* currFont = nsnull;
|
||||
nsFontGTK** font = mLoadedFonts;
|
||||
nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount];
|
||||
|
||||
while (font < end) {
|
||||
if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) {
|
||||
if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
|
@ -4722,7 +4770,7 @@ SetCharsetLangGroup(nsFontCharSetInfo* aCharSetInfo)
|
|||
} while (0)
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::SearchNode(nsFontNode* aNode, PRUnichar aChar)
|
||||
nsFontMetricsGTK::SearchNode(nsFontNode* aNode, PRUint32 aChar)
|
||||
{
|
||||
if (aNode->mDummy) {
|
||||
return nsnull;
|
||||
|
@ -4738,6 +4786,12 @@ nsFontMetricsGTK::SearchNode(nsFontNode* aNode, PRUnichar aChar)
|
|||
* loading a font with the same map.
|
||||
*/
|
||||
if (charSetInfo->mCharSet) {
|
||||
// if SURROGATE char, ignore charSetInfo->mCCMap checking
|
||||
// because the exact ccmap is never created before loading
|
||||
// NEED TO FIX: need better way
|
||||
if (IS_SURROGATE(aChar) ) {
|
||||
goto check_done;
|
||||
}
|
||||
PRUint16* ccmap = charSetInfo->mCCMap;
|
||||
if (ccmap) {
|
||||
for (int i = 0; i < mLoadedFontsCount; i++) {
|
||||
|
@ -4757,6 +4811,8 @@ nsFontMetricsGTK::SearchNode(nsFontNode* aNode, PRUnichar aChar)
|
|||
}
|
||||
}
|
||||
|
||||
check_done:
|
||||
|
||||
aNode->FillStyleHoles();
|
||||
nsFontStyle* style = aNode->mStyles[mStyleIndex];
|
||||
|
||||
|
@ -5584,7 +5640,7 @@ FFRESubstituteEncoding(nsACString &aFFREName,
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::TryNodes(nsACString &aFFREName, PRUnichar aChar)
|
||||
nsFontMetricsGTK::TryNodes(nsACString &aFFREName, PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF((" TryNodes aFFREName = %s",
|
||||
PromiseFlatCString(aFFREName).get()));
|
||||
|
@ -5613,7 +5669,7 @@ nsFontMetricsGTK::TryNodes(nsACString &aFFREName, PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::TryNode(nsCString* aName, PRUnichar aChar)
|
||||
nsFontMetricsGTK::TryNode(nsCString* aName, PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF((" TryNode aName = %s", (*aName).get()));
|
||||
//
|
||||
|
@ -5676,7 +5732,7 @@ nsFontMetricsGTK::TryNode(nsCString* aName, PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUnichar aChar)
|
||||
nsFontMetricsGTK::TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUint32 aChar)
|
||||
{
|
||||
//
|
||||
// for this family check related registry-encoding (for the language)
|
||||
|
@ -5691,7 +5747,7 @@ nsFontMetricsGTK::TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUnichar
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::TryFamily(nsCString* aName, PRUnichar aChar)
|
||||
nsFontMetricsGTK::TryFamily(nsCString* aName, PRUint32 aChar)
|
||||
{
|
||||
//
|
||||
// check the patterh "*-familyname-registry-encoding" for language
|
||||
|
@ -5725,7 +5781,7 @@ nsFontMetricsGTK::TryFamily(nsCString* aName, PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::TryAliases(nsCString* aAlias, PRUnichar aChar)
|
||||
nsFontMetricsGTK::TryAliases(nsCString* aAlias, PRUint32 aChar)
|
||||
{
|
||||
nsCStringKey key(*aAlias);
|
||||
char* name = (char*) gAliases->Get(&key);
|
||||
|
@ -5738,7 +5794,7 @@ nsFontMetricsGTK::TryAliases(nsCString* aAlias, PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindUserDefinedFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindUserDefinedFont(PRUint32 aChar)
|
||||
{
|
||||
if (mIsUserDefined) {
|
||||
FIND_FONT_PRINTF((" FindUserDefinedFont"));
|
||||
|
@ -5753,7 +5809,7 @@ nsFontMetricsGTK::FindUserDefinedFont(PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindStyleSheetSpecificFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindStyleSheetSpecificFont(PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF((" FindStyleSheetSpecificFont"));
|
||||
while (mFontsIndex < mFonts.Count()) {
|
||||
|
@ -5860,7 +5916,7 @@ PrefEnumCallback(const char* aName, void* aClosure)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindStyleSheetGenericFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindStyleSheetGenericFont(PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF((" FindStyleSheetGenericFont"));
|
||||
nsFontGTK* font;
|
||||
|
@ -5932,16 +5988,16 @@ if (gAllowDoubleByteSpecialChars) {
|
|||
sub_font->mCCMap = gDoubleByteSpecialCharsCCMap;
|
||||
AddToLoadedFontsList(sub_font);
|
||||
}
|
||||
if (western_font && CCMAP_HAS_CHAR(western_font->mCCMap, aChar)) {
|
||||
if (western_font && CCMAP_HAS_CHAR_EXT(western_font->mCCMap, aChar)) {
|
||||
return western_font;
|
||||
}
|
||||
else if (symbol_font && CCMAP_HAS_CHAR(symbol_font->mCCMap, aChar)) {
|
||||
else if (symbol_font && CCMAP_HAS_CHAR_EXT(symbol_font->mCCMap, aChar)) {
|
||||
return symbol_font;
|
||||
}
|
||||
else if (euro_font && CCMAP_HAS_CHAR(euro_font->mCCMap, aChar)) {
|
||||
else if (euro_font && CCMAP_HAS_CHAR_EXT(euro_font->mCCMap, aChar)) {
|
||||
return euro_font;
|
||||
}
|
||||
else if (sub_font && CCMAP_HAS_CHAR(sub_font->mCCMap, aChar)) {
|
||||
else if (sub_font && CCMAP_HAS_CHAR_EXT(sub_font->mCCMap, aChar)) {
|
||||
FIND_FONT_PRINTF((" transliterate special chars for single byte docs"));
|
||||
return sub_font;
|
||||
}
|
||||
|
@ -5992,7 +6048,7 @@ if (gAllowDoubleByteSpecialChars) {
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindAnyFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindAnyFont(PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF((" FindAnyFont"));
|
||||
// XXX If we get to this point, that means that we have exhausted all the
|
||||
|
@ -6025,11 +6081,11 @@ nsFontMetricsGTK::FindAnyFont(PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindSubstituteFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindSubstituteFont(PRUint32 aChar)
|
||||
{
|
||||
if (!mSubstituteFont) {
|
||||
for (int i = 0; i < mLoadedFontsCount; i++) {
|
||||
if (CCMAP_HAS_CHAR(mLoadedFonts[i]->mCCMap, 'a')) {
|
||||
if (CCMAP_HAS_CHAR_EXT(mLoadedFonts[i]->mCCMap, 'a')) {
|
||||
mSubstituteFont = new nsFontGTKSubstitute(mLoadedFonts[i]);
|
||||
break;
|
||||
}
|
||||
|
@ -6063,7 +6119,7 @@ nsFontMetricsGTK::FindSubstituteFont(PRUnichar aChar)
|
|||
//
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUint32 aChar)
|
||||
{
|
||||
nsFontGTK* font;
|
||||
//
|
||||
|
@ -6132,7 +6188,7 @@ nsFontMetricsGTK::FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUnichar aChar)
|
|||
}
|
||||
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCString *aName)
|
||||
nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUint32 aChar, nsCString *aName)
|
||||
{
|
||||
nsFontGTK* font;
|
||||
|
||||
|
@ -6207,7 +6263,7 @@ nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCStr
|
|||
* for the characters (FindSubstituteFont).
|
||||
*/
|
||||
nsFontGTK*
|
||||
nsFontMetricsGTK::FindFont(PRUnichar aChar)
|
||||
nsFontMetricsGTK::FindFont(PRUint32 aChar)
|
||||
{
|
||||
FIND_FONT_PRINTF(("\nFindFont(%c/0x%04x)", aChar, aChar));
|
||||
|
||||
|
|
|
@ -167,8 +167,8 @@ public:
|
|||
void LoadFont(void);
|
||||
PRBool IsEmptyFont(XFontStruct*);
|
||||
|
||||
inline int SupportsChar(PRUnichar aChar)
|
||||
{ return mCCMap && CCMAP_HAS_CHAR(mCCMap, aChar); };
|
||||
inline int SupportsChar(PRUint32 aChar)
|
||||
{ return mCCMap && CCMAP_HAS_CHAR_EXT(mCCMap, aChar); };
|
||||
|
||||
virtual GdkFont* GetGDKFont(void);
|
||||
virtual nsXFont* GetXFont(void);
|
||||
|
@ -260,21 +260,21 @@ public:
|
|||
NS_IMETHOD ResolveForwards(const PRUnichar* aString, PRUint32 aLength,
|
||||
nsFontSwitchCallbackGTK aFunc, void* aData);
|
||||
|
||||
nsFontGTK* FindFont(PRUnichar aChar);
|
||||
nsFontGTK* FindUserDefinedFont(PRUnichar aChar);
|
||||
nsFontGTK* FindStyleSheetSpecificFont(PRUnichar aChar);
|
||||
nsFontGTK* FindStyleSheetGenericFont(PRUnichar aChar);
|
||||
nsFontGTK* FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUnichar aChar);
|
||||
nsFontGTK* FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCString* aName);
|
||||
nsFontGTK* FindAnyFont(PRUnichar aChar);
|
||||
nsFontGTK* FindSubstituteFont(PRUnichar aChar);
|
||||
nsFontGTK* FindFont(PRUint32 aChar);
|
||||
nsFontGTK* FindUserDefinedFont(PRUint32 aChar);
|
||||
nsFontGTK* FindStyleSheetSpecificFont(PRUint32 aChar);
|
||||
nsFontGTK* FindStyleSheetGenericFont(PRUint32 aChar);
|
||||
nsFontGTK* FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUint32 aChar);
|
||||
nsFontGTK* FindLangGroupFont(nsIAtom* aLangGroup, PRUint32 aChar, nsCString* aName);
|
||||
nsFontGTK* FindAnyFont(PRUint32 aChar);
|
||||
nsFontGTK* FindSubstituteFont(PRUint32 aChar);
|
||||
|
||||
nsFontGTK* SearchNode(nsFontNode* aNode, PRUnichar aChar);
|
||||
nsFontGTK* TryAliases(nsCString* aName, PRUnichar aChar);
|
||||
nsFontGTK* TryFamily(nsCString* aName, PRUnichar aChar);
|
||||
nsFontGTK* TryNode(nsCString* aName, PRUnichar aChar);
|
||||
nsFontGTK* TryNodes(nsACString &aFFREName, PRUnichar aChar);
|
||||
nsFontGTK* TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUnichar aChar);
|
||||
nsFontGTK* SearchNode(nsFontNode* aNode, PRUint32 aChar);
|
||||
nsFontGTK* TryAliases(nsCString* aName, PRUint32 aChar);
|
||||
nsFontGTK* TryFamily(nsCString* aName, PRUint32 aChar);
|
||||
nsFontGTK* TryNode(nsCString* aName, PRUint32 aChar);
|
||||
nsFontGTK* TryNodes(nsACString &aFFREName, PRUint32 aChar);
|
||||
nsFontGTK* TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUint32 aChar);
|
||||
|
||||
nsFontGTK* AddToLoadedFontsList(nsFontGTK* aFont);
|
||||
nsFontGTK* FindNearestSize(nsFontStretch* aStretch, PRUint16 aSize);
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
nsFontCharSetInfo* aCharSet);
|
||||
nsFontGTK* PickASizeAndLoad(nsFontStretch* aStretch,
|
||||
nsFontCharSetInfo* aCharSet,
|
||||
PRUnichar aChar,
|
||||
PRUint32 aChar,
|
||||
const char *aName);
|
||||
|
||||
// nsIFontMetricsGTK (calls from the font rendering layer)
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
|
||||
void
|
||||
FreeCCMap(PRUint16* &aMap)
|
||||
|
@ -111,47 +111,71 @@ MapperToCCMap(nsICharRepresentable *aMapper)
|
|||
}
|
||||
|
||||
PRBool
|
||||
NextNonEmptyCCMapPage(PRUint16* aCCMap, PRUint16 *aPageStart)
|
||||
NextNonEmptyCCMapPage(PRUint16* aCCMap, PRUint32 *aPageStart)
|
||||
{
|
||||
int i, j;
|
||||
int i, j, l;
|
||||
int planeend = 0;
|
||||
int planestart = 0;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// checking each plane
|
||||
for(l=planestart; l<=planeend; l++, pagestart = CCMAP_BEGIN_AT_START_OF_MAP) {
|
||||
|
||||
if(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 the mid array
|
||||
PRUint16 *mid = &aCCMap[upper[i]];
|
||||
for (j=mid_index; j<CCMAP_NUM_MID_POINTERS; j++) {
|
||||
if (mid[j] == CCMAP_EMPTY_PAGE)
|
||||
// walk thru the upper pointers
|
||||
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 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;
|
||||
// walk the mid array
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,17 +209,21 @@ PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2)
|
|||
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;
|
||||
if (mExtended) {
|
||||
return MapToCCMapExt(mMap, mExtMap+1, EXTENDED_UNICODE_PLANES);
|
||||
} else {
|
||||
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;
|
||||
newMap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(newMap) = GetSize();
|
||||
CCMAP_FLAG(newMap) = CCMAP_NONE_FLAG;
|
||||
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
|
@ -208,6 +236,18 @@ nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
|||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::~nsCompressedCharMap()
|
||||
{
|
||||
if(mExtended){
|
||||
int i;
|
||||
for (i = 1; i <= EXTENDED_UNICODE_PLANES; ++i) {
|
||||
if (mExtMap[i]) {
|
||||
PR_Free(mExtMap[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
{
|
||||
// initialize map to have:
|
||||
|
@ -239,45 +279,70 @@ nsCompressedCharMap::nsCompressedCharMap()
|
|||
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;
|
||||
|
||||
// init extended
|
||||
mExtended = PR_FALSE;
|
||||
memset(mExtMap+1, 0, sizeof(PRUint32*) * EXTENDED_UNICODE_PLANES);
|
||||
memset(mMap, 0, sizeof(mMap));
|
||||
mExtMap[0] = mMap;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChar(PRUint16 aChar)
|
||||
nsCompressedCharMap::SetChar(PRUint32 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;
|
||||
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");
|
||||
|
||||
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;
|
||||
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);
|
||||
CCMAP_SET_CHAR(u.mCCMap,aChar);
|
||||
#undef CCMAP_SET_CHAR
|
||||
NS_ASSERTION(CCMAP_HAS_CHAR(u.mCCMap,aChar), "failed to set bit");
|
||||
NS_ASSERTION(CCMAP_HAS_CHAR(u.mCCMap,aChar), "failed to set bit");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -359,26 +424,40 @@ 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)
|
||||
if(mExtended){
|
||||
PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
while (NextNonEmptyCCMapPage(aCCMap, &page)) {
|
||||
PRUint32 pagechar = page;
|
||||
for (i=0; i<(CCMAP_BITS_PER_PAGE/8); i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if (CCMAP_HAS_CHAR_EXT(aCCMap, pagechar)) {
|
||||
SetChar(pagechar);
|
||||
}
|
||||
pagechar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// 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;
|
||||
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +515,7 @@ nsCompressedCharMap::SetChars(PRUint32* aMap)
|
|||
void
|
||||
printCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
PRUint16 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
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;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#ifndef NSCOMPRESSEDCHARMAP_H
|
||||
#define NSCOMPRESSEDCHARMAP_H
|
||||
#include "prtypes.h"
|
||||
|
||||
#include "nsICharRepresentable.h"
|
||||
|
||||
#define ALU_SIZE PR_BITS_PER_LONG
|
||||
//#define ALU_SIZE 16
|
||||
|
@ -67,7 +67,7 @@ extern PRUint16* CreateEmptyCCMap();
|
|||
extern PRUint16* MapToCCMap(PRUint32* aMap);
|
||||
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
||||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint16 *);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint32 *);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
#ifdef DEBUG
|
||||
void printCCMap(PRUint16* aCCMap);
|
||||
|
@ -101,17 +101,22 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe
|
|||
// (256*16 max pages) = 4400 PRUint16
|
||||
#define CCMAP_MAX_LEN (16+16+16+256+4096)
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
class nsCompressedCharMap {
|
||||
public:
|
||||
nsCompressedCharMap();
|
||||
~nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChar(PRUint32);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
void SetChars(PRUint32*);
|
||||
void Extend() {mExtended = PR_TRUE;} // enable surrogate area
|
||||
|
||||
protected:
|
||||
union {
|
||||
|
@ -122,6 +127,11 @@ protected:
|
|||
PRUint16 mUsedLen; // in PRUint16
|
||||
PRUint16 mAllOnesPage;
|
||||
|
||||
PRBool mExtended;
|
||||
|
||||
// for surrogate support
|
||||
PRUint32* mExtMap[EXTENDED_UNICODE_PLANES+1];
|
||||
PRUint32 mMap[UCS2_MAP_LEN];
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -295,7 +305,7 @@ protected:
|
|||
#define CCMAP_TOTAL_PAGES CCMAP_POW2(CCMAP_BITS_PER_UPPER_LOG2 \
|
||||
+CCMAP_BITS_PER_MID_LOG2)
|
||||
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFF
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFFFFFF
|
||||
|
||||
//
|
||||
// Finally, build up the macro to test the bit for a given char
|
||||
|
@ -323,9 +333,6 @@ protected:
|
|||
#define CCMAP_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1)
|
||||
|
||||
|
@ -345,5 +352,4 @@ protected:
|
|||
#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
|
||||
|
|
|
@ -1303,7 +1303,7 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
const char *aFontFileName,
|
||||
int aFaceIndex, int * aNumFaces)
|
||||
{
|
||||
int i, len;
|
||||
PRUint32 i, len;
|
||||
nsFontCatalogEntry *fce;
|
||||
FT_Error fterror;
|
||||
FT_Face face = nsnull;
|
||||
|
@ -1360,14 +1360,27 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
}
|
||||
else {
|
||||
for (i=0; i < face->num_charmaps; i++) {
|
||||
if ( (face->charmaps[i]->platform_id == TT_PLATFORM_MICROSOFT)
|
||||
&& (face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS)) {
|
||||
fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_UNICODE;
|
||||
rv = mFt2->SetCharmap(face, face->charmaps[i]);
|
||||
if (NS_FAILED(rv)) {
|
||||
FONT_SCAN_PRINTF(("failed to select unicode charmap"));
|
||||
goto cleanup_and_return;
|
||||
|
||||
if (face->charmaps[i]->platform_id == TT_PLATFORM_MICROSOFT) {
|
||||
if (face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS) {
|
||||
fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_UNICODE;
|
||||
fterror = mFt2->SetCharmap(face, face->charmaps[i]);
|
||||
if (fterror) {
|
||||
FONT_SCAN_PRINTF(("failed to select unicode charmap"));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
}
|
||||
#if defined(TT_MS_ID_UCS_4)
|
||||
else if (face->charmaps[i]->encoding_id == TT_MS_ID_UCS_4) {
|
||||
fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_UNICODE | FCE_FLAGS_SURROGATE;
|
||||
fterror = mFt2->SetCharmap(face, face->charmaps[i]);
|
||||
if (fterror) {
|
||||
FONT_SCAN_PRINTF(("failed to select unicode charmap"));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1420,20 +1433,46 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
fce->mEmbeddedBitmapHeights[i] = face->available_sizes[i].height;
|
||||
}
|
||||
|
||||
if (fce->mFlags & FCE_FLAGS_UNICODE) {
|
||||
/* get the Unicode char map */
|
||||
blank_chars = 0;
|
||||
if ((fce->mFlags & FCE_FLAGS_UNICODE) || (fce->mFlags & FCE_FLAGS_SURROGATE)) {
|
||||
if (fce->mFlags & FCE_FLAGS_SURROGATE) {
|
||||
ccmapObj.Extend();
|
||||
}
|
||||
|
||||
// check fast methods are defined
|
||||
PRBool has_fast_methods;
|
||||
mFt2->SupportsExtFunc(&has_fast_methods);
|
||||
|
||||
PRBool scan_done = PR_FALSE;
|
||||
if (has_fast_methods) {
|
||||
mFt2->GetFirstChar(face, &glyph_index, (FT_ULong*)&i);
|
||||
if (glyph_index == 0) {
|
||||
// no glyph in the font
|
||||
scan_done = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
i=0;
|
||||
}
|
||||
|
||||
len = NUM_UNICODE_CHARS;
|
||||
if(fce->mFlags & FCE_FLAGS_SURROGATE) {
|
||||
len = 0xFFFFF;
|
||||
}
|
||||
|
||||
blank_chars = 0;
|
||||
slot = face->glyph;
|
||||
FONT_SCAN_PRINTF((" "));
|
||||
for (i=0; i<len; i++) {
|
||||
mFt2->GetCharIndex(face, (FT_ULong)i, &glyph_index);
|
||||
//FONT_CATALOG_PRINTF(("i=%d, glyph_index=%d", i, glyph_index));
|
||||
if (!glyph_index)
|
||||
continue;
|
||||
|
||||
while (!scan_done && i < len) {
|
||||
if (!has_fast_methods) {
|
||||
mFt2->GetCharIndex(face, (FT_ULong)i, &glyph_index);
|
||||
//FONT_CATALOG_PRINTF(("i=%d, glyph_index=%d", i, glyph_index));
|
||||
if (glyph_index == 0) {
|
||||
goto next_char;
|
||||
}
|
||||
}
|
||||
if (gFontDebug & NS_FONT_DEBUG_FONT_SCAN) {
|
||||
if ((num_checked % 1000) == 0) {
|
||||
FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b%5d glyphs", num_checked));
|
||||
FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%7d glyphs", num_checked));
|
||||
}
|
||||
}
|
||||
num_checked++;
|
||||
|
@ -1443,7 +1482,7 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
if (NS_FAILED(rv)) {
|
||||
FONT_CATALOG_PRINTF(("error loading %d (glyph index = %d)",
|
||||
i, glyph_index));
|
||||
continue;
|
||||
goto next_char;
|
||||
}
|
||||
if (slot->format == ft_glyph_format_outline) {
|
||||
//FONT_CATALOG_PRINTF(("n_contours=%d", slot->outline.n_contours));
|
||||
|
@ -1456,7 +1495,7 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
mFt2->DoneGlyph(glyph);
|
||||
if((bbox.xMax==0) && (bbox.xMin==0)
|
||||
&& (bbox.yMax==0) && (bbox.yMin==0)) {
|
||||
continue;
|
||||
goto next_char;
|
||||
}
|
||||
FONT_SCAN_PRINTF(("no contours %d (glyph index = %d)\n", i,
|
||||
glyph_index));
|
||||
|
@ -1472,7 +1511,7 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
FONT_CATALOG_PRINTF(("continue at line %d", __LINE__));
|
||||
FONT_SCAN_PRINTF(("empty bitmap %d (glyph index = %d)\n",
|
||||
i, glyph_index));
|
||||
continue;
|
||||
goto next_char;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1480,15 +1519,28 @@ nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary,
|
|||
}
|
||||
ccmapObj.SetChar(i);
|
||||
fce->mNumUsableGlyphs++;
|
||||
next_char:
|
||||
if (has_fast_methods) {
|
||||
FT_ULong ncharcode;
|
||||
mFt2->GetNextChar(face, (FT_ULong)i, &glyph_index, &ncharcode);
|
||||
i = ncharcode;
|
||||
if (glyph_index == 0) {
|
||||
// no more glyph in the font
|
||||
scan_done = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (gFontDebug & NS_FONT_DEBUG_FONT_SCAN) {
|
||||
FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b%5d glyphs", num_checked));
|
||||
FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%7d glyphs", num_checked));
|
||||
if (blank_chars) {
|
||||
FONT_SCAN_PRINTF((" (%d invalid)", blank_chars));
|
||||
}
|
||||
}
|
||||
if (fce->mNumUsableGlyphs == 0)
|
||||
fce->mFlags |= FCE_FLAGS_ISVALID;
|
||||
|
||||
fce->mCCMap = ccmapObj.NewCCMap();
|
||||
}
|
||||
else if (fce->mFlags & FCE_FLAGS_SYMBOL) {
|
||||
|
@ -1555,7 +1607,7 @@ nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB)
|
|||
nsFontCatalogEntry *fce = nsnull;
|
||||
long longVal;
|
||||
unsigned long uLongVal;
|
||||
int num, intVal;
|
||||
int num, intVal, i;
|
||||
nsCompressedCharMap ccmapObj;
|
||||
|
||||
fce = (nsFontCatalogEntry *)calloc(1, sizeof(nsFontCatalogEntry));
|
||||
|
@ -1566,6 +1618,7 @@ nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB)
|
|||
FONT_CATALOG_PRINTF(("file garbled: expected begin=Font_, got %s", type));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
|
||||
while (aDB->GetNextElement(&name, &value) > 0) {
|
||||
if (STRMATCH(name,"FamilyName")) {
|
||||
if (fce->mFamilyName) {
|
||||
|
@ -1583,12 +1636,15 @@ nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB)
|
|||
fce->mFontFileName?fce->mFontFileName:""));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
num = sscanf(value, "%lu", &uLongVal);
|
||||
num = sscanf(value, "%lx", &uLongVal);
|
||||
if (num != 1) {
|
||||
FONT_CATALOG_PRINTF(("failed to parse Flags (%s)",value));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
fce->mFlags = uLongVal;
|
||||
if (fce->mFlags & FCE_FLAGS_SURROGATE) {
|
||||
ccmapObj.Extend();
|
||||
}
|
||||
}
|
||||
else if (STRMATCH(name,"FontFileName")) {
|
||||
if (fce->mFontFileName) {
|
||||
|
@ -1822,6 +1878,7 @@ nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB)
|
|||
}
|
||||
|
||||
fce->mCCMap = ccmapObj.NewCCMap();
|
||||
|
||||
if (!fce->mCCMap) {
|
||||
FONT_CATALOG_PRINTF(("missing char map"));
|
||||
goto cleanup_and_return;
|
||||
|
@ -1855,7 +1912,8 @@ nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB)
|
|||
goto cleanup_and_return;
|
||||
}
|
||||
if (fce->mFlags&FCE_FLAGS_ISVALID
|
||||
&& (fce->mFlags & FCE_FLAGS_UNICODE) && (fce->mNumUsableGlyphs == 0)) {
|
||||
&& ((fce->mFlags & FCE_FLAGS_UNICODE) || (fce->mFlags & FCE_FLAGS_SURROGATE))
|
||||
&& (fce->mNumUsableGlyphs == 0)) {
|
||||
FONT_CATALOG_PRINTF(("missing num usable glyphs"));
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
|
@ -1889,7 +1947,7 @@ nsFT2FontCatalog::ParseCCMapLine(nsCompressedCharMap *aCCMapObj, long base,
|
|||
{
|
||||
int i, j, len;
|
||||
unsigned int byte;
|
||||
PRUint16 pagechar = (PRUint16)base;
|
||||
PRUint32 pagechar = (PRUint32)base;
|
||||
|
||||
// check we have the right number of chars
|
||||
len = strlen(valString);
|
||||
|
@ -1942,7 +2000,7 @@ nsFT2FontCatalog::PrintCCMap(nsNameValuePairDB *aDB, PRUint16 *aCCMap)
|
|||
if (!aCCMap)
|
||||
return;
|
||||
|
||||
PRUint16 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
while (NextNonEmptyCCMapPage(aCCMap, &page)) {
|
||||
//FONT_CATALOG_PRINTF(("page starting at 0x%04x has chars", page));
|
||||
PrintPageBits(aDB, aCCMap, page);
|
||||
|
@ -2044,7 +2102,7 @@ nsFT2FontCatalog::PrintPageBits(nsNameValuePairDB *aDB, PRUint16 *aCCMap,
|
|||
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)) {
|
||||
if (CCMAP_HAS_CHAR_EXT(aCCMap, pagechar)) {
|
||||
val |= 1 << j;
|
||||
}
|
||||
pagechar++;
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
|
||||
#if (defined(MOZ_ENABLE_FREETYPE2))
|
||||
#include "nsFreeType.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIPref.h"
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#endif
|
||||
|
||||
#include "nsFontFreeType.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
#if (!defined(MOZ_ENABLE_FREETYPE2))
|
||||
|
||||
|
@ -316,13 +317,25 @@ nsFreeTypeFont::doGetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the text size
|
||||
PRUint32 i;
|
||||
for (i=0; i<aLength; i++) {
|
||||
PRUint32 i, extraSurrogateLength;
|
||||
for (i=0; i<aLength; i+=1+extraSurrogateLength) {
|
||||
FT_UInt glyph_index;
|
||||
FT_Glyph glyph;
|
||||
FT_BBox glyph_bbox;
|
||||
FT_Pos advance;
|
||||
mFt2->GetCharIndex(face, (FT_ULong)aString[i], &glyph_index);
|
||||
extraSurrogateLength=0;
|
||||
|
||||
FT_ULong code_point = aString[i];
|
||||
if(i<aLength-1 && IS_HIGH_SURROGATE(code_point) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] surrogate and
|
||||
// low surrogate aString[i+1]
|
||||
code_point = SURROGATE_TO_UCS4(code_point, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
mFt2->GetCharIndex(face, code_point, &glyph_index);
|
||||
|
||||
//NS_ASSERTION(glyph_index,"failed to get glyph");
|
||||
if (glyph_index) {
|
||||
rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph);
|
||||
|
@ -392,8 +405,19 @@ nsFreeTypeFont::GetWidth(const PRUnichar* aString, PRUint32 aLength)
|
|||
if (!icache)
|
||||
return 0;
|
||||
|
||||
for (PRUint32 i=0; i<aLength; i++) {
|
||||
mFt2->GetCharIndex((FT_Face)face, (FT_ULong)aString[i], &glyph_index);
|
||||
PRUint32 i, extraSurrogateLength;
|
||||
for (i=0; i<aLength; i+=1+extraSurrogateLength) {
|
||||
extraSurrogateLength=0;
|
||||
FT_ULong code_point = aString[i];
|
||||
if(i<aLength-1 && IS_HIGH_SURROGATE(code_point) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] surrogate and
|
||||
// low surrogate aString[i+1]
|
||||
code_point = SURROGATE_TO_UCS4(code_point, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
mFt2->GetCharIndex((FT_Face)face, code_point, &glyph_index);
|
||||
nsresult rv;
|
||||
rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"error loading glyph");
|
||||
|
@ -709,13 +733,25 @@ nsFreeTypeXImage::DrawString(nsRenderingContextGTK* aContext,
|
|||
// Get aa glyphs and blend with background
|
||||
//
|
||||
blendGlyph blendGlyph = nsX11AlphaBlend::GetBlendGlyph();
|
||||
PRUint32 i;
|
||||
for (i=0; i<aLength; i++) {
|
||||
PRUint32 i, extraSurrogateLength;
|
||||
for (i=0; i<aLength; i+=1+extraSurrogateLength) {
|
||||
FT_UInt glyph_index;
|
||||
FT_Glyph glyph;
|
||||
nsresult rv;
|
||||
FT_BBox glyph_bbox;
|
||||
mFt2->GetCharIndex(face, (FT_ULong)aString[i], &glyph_index);
|
||||
FT_ULong code_point = aString[i];
|
||||
extraSurrogateLength = 0;
|
||||
|
||||
if(i<aLength-1 && IS_HIGH_SURROGATE(code_point) && IS_LOW_SURROGATE(aString[i+1])) {
|
||||
// if surrogate, make UCS4 code point from high aString[i] surrogate and
|
||||
// low surrogate aString[i+1]
|
||||
code_point = SURROGATE_TO_UCS4(code_point, aString[i+1]);
|
||||
|
||||
// skip aString[i+1], it is already used as low surrogate
|
||||
extraSurrogateLength = 1;
|
||||
}
|
||||
|
||||
mFt2->GetCharIndex(face, code_point, &glyph_index);
|
||||
if (glyph_index) {
|
||||
rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
#include "nsCompressedCharMap.h"
|
||||
|
||||
void
|
||||
FreeCCMap(PRUint16* &aMap)
|
||||
|
@ -111,47 +111,71 @@ MapperToCCMap(nsICharRepresentable *aMapper)
|
|||
}
|
||||
|
||||
PRBool
|
||||
NextNonEmptyCCMapPage(PRUint16* aCCMap, PRUint16 *aPageStart)
|
||||
NextNonEmptyCCMapPage(PRUint16* aCCMap, PRUint32 *aPageStart)
|
||||
{
|
||||
int i, j;
|
||||
int i, j, l;
|
||||
int planeend = 0;
|
||||
int planestart = 0;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// checking each plane
|
||||
for(l=planestart; l<=planeend; l++, pagestart = CCMAP_BEGIN_AT_START_OF_MAP) {
|
||||
|
||||
if(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 the mid array
|
||||
PRUint16 *mid = &aCCMap[upper[i]];
|
||||
for (j=mid_index; j<CCMAP_NUM_MID_POINTERS; j++) {
|
||||
if (mid[j] == CCMAP_EMPTY_PAGE)
|
||||
// walk thru the upper pointers
|
||||
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 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;
|
||||
// walk the mid array
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,17 +209,21 @@ PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2)
|
|||
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;
|
||||
if (mExtended) {
|
||||
return MapToCCMapExt(mMap, mExtMap+1, EXTENDED_UNICODE_PLANES);
|
||||
} else {
|
||||
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;
|
||||
newMap += CCMAP_EXTRA;
|
||||
CCMAP_SIZE(newMap) = GetSize();
|
||||
CCMAP_FLAG(newMap) = CCMAP_NONE_FLAG;
|
||||
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
FillCCMap(newMap);
|
||||
return newMap;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint16*
|
||||
|
@ -208,6 +236,18 @@ nsCompressedCharMap::FillCCMap(PRUint16* aCCMap)
|
|||
return aCCMap;
|
||||
}
|
||||
|
||||
nsCompressedCharMap::~nsCompressedCharMap()
|
||||
{
|
||||
if(mExtended){
|
||||
int i;
|
||||
for (i = 1; i <= EXTENDED_UNICODE_PLANES; ++i) {
|
||||
if (mExtMap[i]) {
|
||||
PR_Free(mExtMap[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCompressedCharMap::nsCompressedCharMap()
|
||||
{
|
||||
// initialize map to have:
|
||||
|
@ -239,45 +279,70 @@ nsCompressedCharMap::nsCompressedCharMap()
|
|||
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;
|
||||
|
||||
// init extended
|
||||
mExtended = PR_FALSE;
|
||||
memset(mExtMap+1, 0, sizeof(PRUint32*) * EXTENDED_UNICODE_PLANES);
|
||||
memset(mMap, 0, sizeof(mMap));
|
||||
mExtMap[0] = mMap;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsCompressedCharMap::SetChar(PRUint16 aChar)
|
||||
nsCompressedCharMap::SetChar(PRUint32 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;
|
||||
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");
|
||||
|
||||
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;
|
||||
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);
|
||||
CCMAP_SET_CHAR(u.mCCMap,aChar);
|
||||
#undef CCMAP_SET_CHAR
|
||||
NS_ASSERTION(CCMAP_HAS_CHAR(u.mCCMap,aChar), "failed to set bit");
|
||||
NS_ASSERTION(CCMAP_HAS_CHAR(u.mCCMap,aChar), "failed to set bit");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -359,26 +424,40 @@ 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)
|
||||
if(mExtended){
|
||||
PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
while (NextNonEmptyCCMapPage(aCCMap, &page)) {
|
||||
PRUint32 pagechar = page;
|
||||
for (i=0; i<(CCMAP_BITS_PER_PAGE/8); i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if (CCMAP_HAS_CHAR_EXT(aCCMap, pagechar)) {
|
||||
SetChar(pagechar);
|
||||
}
|
||||
pagechar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// 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;
|
||||
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +515,7 @@ nsCompressedCharMap::SetChars(PRUint32* aMap)
|
|||
void
|
||||
printCCMap(PRUint16* aCCMap)
|
||||
{
|
||||
PRUint16 page = CCMAP_BEGIN_AT_START_OF_MAP;
|
||||
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;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#ifndef NSCOMPRESSEDCHARMAP_H
|
||||
#define NSCOMPRESSEDCHARMAP_H
|
||||
#include "prtypes.h"
|
||||
|
||||
#include "nsICharRepresentable.h"
|
||||
|
||||
#define ALU_SIZE PR_BITS_PER_LONG
|
||||
//#define ALU_SIZE 16
|
||||
|
@ -67,7 +67,7 @@ extern PRUint16* CreateEmptyCCMap();
|
|||
extern PRUint16* MapToCCMap(PRUint32* aMap);
|
||||
extern PRUint16* MapperToCCMap(nsICharRepresentable *aMapper);
|
||||
extern void FreeCCMap(PRUint16* &aMap);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint16 *);
|
||||
extern PRBool NextNonEmptyCCMapPage(PRUint16 *, PRUint32 *);
|
||||
extern PRBool IsSameCCMap(PRUint16* ccmap1, PRUint16* ccmap2);
|
||||
#ifdef DEBUG
|
||||
void printCCMap(PRUint16* aCCMap);
|
||||
|
@ -101,17 +101,22 @@ MapToCCMapExt(PRUint32* aBmpPlaneMap, PRUint32** aOtherPlaneMaps, PRUint32 aOthe
|
|||
// (256*16 max pages) = 4400 PRUint16
|
||||
#define CCMAP_MAX_LEN (16+16+16+256+4096)
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
class nsCompressedCharMap {
|
||||
public:
|
||||
nsCompressedCharMap();
|
||||
~nsCompressedCharMap();
|
||||
|
||||
PRUint16* NewCCMap();
|
||||
PRUint16* FillCCMap(PRUint16* aCCMap);
|
||||
PRUint16 GetSize() {return mUsedLen;};
|
||||
void SetChar(PRUint16);
|
||||
void SetChar(PRUint32);
|
||||
void SetChars(PRUint16*);
|
||||
void SetChars(PRUint16, ALU_TYPE*);
|
||||
void SetChars(PRUint32*);
|
||||
void Extend() {mExtended = PR_TRUE;} // enable surrogate area
|
||||
|
||||
protected:
|
||||
union {
|
||||
|
@ -122,6 +127,11 @@ protected:
|
|||
PRUint16 mUsedLen; // in PRUint16
|
||||
PRUint16 mAllOnesPage;
|
||||
|
||||
PRBool mExtended;
|
||||
|
||||
// for surrogate support
|
||||
PRUint32* mExtMap[EXTENDED_UNICODE_PLANES+1];
|
||||
PRUint32 mMap[UCS2_MAP_LEN];
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -295,7 +305,7 @@ protected:
|
|||
#define CCMAP_TOTAL_PAGES CCMAP_POW2(CCMAP_BITS_PER_UPPER_LOG2 \
|
||||
+CCMAP_BITS_PER_MID_LOG2)
|
||||
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFF
|
||||
#define CCMAP_BEGIN_AT_START_OF_MAP 0xFFFFFFFF
|
||||
|
||||
//
|
||||
// Finally, build up the macro to test the bit for a given char
|
||||
|
@ -323,9 +333,6 @@ protected:
|
|||
#define CCMAP_SURROGATE_FLAG 0x0001
|
||||
#define CCMAP_NONE_FLAG 0x0000
|
||||
|
||||
// non-bmp unicode support extension
|
||||
#define EXTENDED_UNICODE_PLANES 16
|
||||
|
||||
// get plane number from ccmap, bmp excluded, so plane 1's number is 0.
|
||||
#define CCMAP_PLANE_FROM_SURROGATE(h) ((((PRUint16)(h) - (PRUint16)0xd800) >> 6) + 1)
|
||||
|
||||
|
@ -345,5 +352,4 @@ protected:
|
|||
#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
|
||||
|
|
Загрузка…
Ссылка в новой задаче