diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 444dcc426b9..f5b549db2e2 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -111,7 +111,6 @@ class nsIRunnable; class nsIInterfaceRequestor; template class nsCOMArray; struct JSRuntime; -class nsICaseConversion; class nsIUGenCategory; class nsIWidget; class nsIDragSession; @@ -615,11 +614,6 @@ public: { return sWordBreaker; } - - static nsICaseConversion* GetCaseConv() - { - return sCaseConv; - } static nsIUGenCategory* GetGenCat() { @@ -1741,7 +1735,6 @@ private: static nsILineBreaker* sLineBreaker; static nsIWordBreaker* sWordBreaker; - static nsICaseConversion* sCaseConv; static nsIUGenCategory* sGenCat; // Holds pointers to nsISupports* that should be released at shutdown diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 22cdac30422..b7b3c2aa0bd 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -146,7 +146,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsIMEStateManager.h" #include "nsContentErrors.h" #include "nsUnicharUtilCIID.h" -#include "nsICaseConversion.h" #include "nsCompressedCharMap.h" #include "nsINativeKeyBindings.h" #include "nsIDOMNSUIEvent.h" @@ -241,7 +240,6 @@ nsIContentPolicy *nsContentUtils::sContentPolicyService; PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE; nsILineBreaker *nsContentUtils::sLineBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker; -nsICaseConversion *nsContentUtils::sCaseConv; nsIUGenCategory *nsContentUtils::sGenCat; nsTArray *nsContentUtils::sPtrsToPtrsToRelease; nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND]; @@ -403,9 +401,6 @@ nsContentUtils::Init() rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker); NS_ENSURE_SUCCESS(rv, rv); - - rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &sCaseConv); - NS_ENSURE_SUCCESS(rv, rv); rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat); NS_ENSURE_SUCCESS(rv, rv); @@ -1083,7 +1078,6 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sIOService); NS_IF_RELEASE(sLineBreaker); NS_IF_RELEASE(sWordBreaker); - NS_IF_RELEASE(sCaseConv); NS_IF_RELEASE(sGenCat); #ifdef MOZ_XTF NS_IF_RELEASE(sXTFService); diff --git a/extensions/spellcheck/hunspell/src/csutil.cpp b/extensions/spellcheck/hunspell/src/csutil.cpp index 43600ed07d5..1a14ccf3e55 100644 --- a/extensions/spellcheck/hunspell/src/csutil.cpp +++ b/extensions/spellcheck/hunspell/src/csutil.cpp @@ -79,7 +79,6 @@ #include "nsServiceManagerUtils.h" #include "nsIUnicodeEncoder.h" #include "nsIUnicodeDecoder.h" -#include "nsICaseConversion.h" #include "nsICharsetConverterManager.h" #include "nsUnicharUtilCIID.h" #include "nsUnicharUtils.h" @@ -5211,7 +5210,6 @@ struct cs_info * get_current_cs(const char * es) { nsCOMPtr encoder; nsCOMPtr decoder; - nsCOMPtr caseConv; nsresult rv; nsCOMPtr ccm = do_GetService(kCharsetConverterManagerCID, &rv); @@ -5227,10 +5225,6 @@ struct cs_info * get_current_cs(const char * es) { return nsnull; decoder->SetInputErrorBehavior(decoder->kOnError_Signal); - caseConv = do_GetService(kUnicharUtilCID, &rv); - if (NS_FAILED(rv)) - return nsnull; - ccs = new cs_info[256]; for (unsigned int i = 0; i <= 0xff; ++i) { @@ -5252,18 +5246,14 @@ struct cs_info * get_current_cs(const char * es) { // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT. if (rv != NS_OK || charLength != 1 || uniLength != 1) break; - rv = caseConv->ToLower(uni, &uniCased); - if (NS_FAILED(rv)) - break; + uniCased = ToLowerCase(uni); rv = encoder->Convert(&uniCased, &uniLength, &lower, &charLength); // Explicitly check NS_OK because we don't want to allow // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT. if (rv != NS_OK || charLength != 1 || uniLength != 1) break; - rv = caseConv->ToUpper(uni, &uniCased); - if (NS_FAILED(rv)) - break; + uniCased = ToUpperCase(uni); rv = encoder->Convert(&uniCased, &uniLength, &upper, &charLength); // Explicitly check NS_OK because we don't want to allow // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT. @@ -5392,15 +5382,6 @@ void free_utf_tbl() { } } -#ifdef MOZILLA_CLIENT -static nsCOMPtr& getcaseConv() -{ - nsresult rv; - static nsCOMPtr caseConv = do_GetService(kUnicharUtilCID, &rv); - return caseConv; -} -#endif - unsigned short unicodetoupper(unsigned short c, int langnum) { // In Azeri and Turkish, I and i dictinct letters: @@ -5412,9 +5393,7 @@ unsigned short unicodetoupper(unsigned short c, int langnum) return u_toupper(c); #else #ifdef MOZILLA_CLIENT - PRUnichar ch2; - getcaseConv()->ToUpper((PRUnichar) c, &ch2); - return ch2; + return ToUpperCase((PRUnichar) c); #else return (utf_tbl) ? utf_tbl[c].cupper : c; #endif @@ -5432,9 +5411,7 @@ unsigned short unicodetolower(unsigned short c, int langnum) return u_tolower(c); #else #ifdef MOZILLA_CLIENT - PRUnichar ch2; - getcaseConv()->ToLower((PRUnichar) c, &ch2); - return ch2; + return ToLowerCase((PRUnichar) c); #else return (utf_tbl) ? utf_tbl[c].clower : c; #endif diff --git a/extensions/spellcheck/src/mozEnglishWordUtils.cpp b/extensions/spellcheck/src/mozEnglishWordUtils.cpp index 154288ae003..46d6c19cc81 100644 --- a/extensions/spellcheck/src/mozEnglishWordUtils.cpp +++ b/extensions/spellcheck/src/mozEnglishWordUtils.cpp @@ -39,6 +39,7 @@ #include "nsICharsetAlias.h" #include "nsReadableUtils.h" #include "nsIServiceManager.h" +#include "nsUnicharUtils.h" #include "nsUnicharUtilCIID.h" #include "nsCRT.h" @@ -51,8 +52,7 @@ NS_INTERFACE_MAP_BEGIN(mozEnglishWordUtils) NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozEnglishWordUtils) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_3(mozEnglishWordUtils, - mCaseConv, +NS_IMPL_CYCLE_COLLECTION_2(mozEnglishWordUtils, mCategories, mURLDetector) @@ -62,7 +62,6 @@ mozEnglishWordUtils::mozEnglishWordUtils() nsresult rv; mURLDetector = do_CreateInstance(MOZ_TXTTOHTMLCONV_CONTRACTID, &rv); - mCaseConv = do_GetService(NS_UNICHARUTIL_CONTRACTID); mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID); } @@ -118,15 +117,15 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRootForm(const PRUnichar *aWord, PRUint32 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr); return NS_ERROR_OUT_OF_MEMORY; } - mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length); + ToLowerCase(tmpPtr[0], tmpPtr[0], length); tmpPtr[1] = ToNewUnicode(word); if (!tmpPtr[1]) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, tmpPtr); return NS_ERROR_OUT_OF_MEMORY; } - mCaseConv->ToLower(tmpPtr[1], tmpPtr[1], length); - mCaseConv->ToUpper(tmpPtr[1], tmpPtr[1], 1); + ToLowerCase(tmpPtr[1], tmpPtr[1], length); + ToUpperCase(tmpPtr[1], tmpPtr[1], 1); tmpPtr[2] = ToNewUnicode(word); if (!tmpPtr[2]) { @@ -148,7 +147,7 @@ NS_IMETHODIMP mozEnglishWordUtils::GetRootForm(const PRUnichar *aWord, PRUint32 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(0, tmpPtr); return NS_ERROR_OUT_OF_MEMORY; } - mCaseConv->ToLower(tmpPtr[0], tmpPtr[0], length); + ToLowerCase(tmpPtr[0], tmpPtr[0], length); tmpPtr[1] = ToNewUnicode(word); if (!tmpPtr[1]) { @@ -245,15 +244,14 @@ NS_IMETHODIMP mozEnglishWordUtils::FindNextWord(const PRUnichar *word, PRUint32 mozEnglishWordUtils::myspCapitalization mozEnglishWordUtils::captype(const nsString &word) { - if(!mCaseConv) return HuhCap; //punt PRUnichar* lword=ToNewUnicode(word); - mCaseConv->ToUpper(lword,lword,word.Length()); + ToUpperCase(lword,lword,word.Length()); if(word.Equals(lword)){ nsMemory::Free(lword); return AllCap; } - mCaseConv->ToLower(lword,lword,word.Length()); + ToLowerCase(lword,lword,word.Length()); if(word.Equals(lword)){ nsMemory::Free(lword); return NoCap; @@ -298,10 +296,12 @@ NS_IMETHODIMP mozEnglishWordUtils::FromRootForm(const PRUnichar *aWord, const PR case NoCap: break; case AllCap: - rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],length); + ToUpperCase(tmpPtr[i],tmpPtr[i],length); + rv = NS_OK; break; case InitCap: - rv = mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],1); + ToUpperCase(tmpPtr[i],tmpPtr[i],1); + rv = NS_OK; break; default: rv = NS_ERROR_FAILURE; // should never get here; diff --git a/extensions/spellcheck/src/mozEnglishWordUtils.h b/extensions/spellcheck/src/mozEnglishWordUtils.h index b128c7d2e6c..fb2300917cf 100644 --- a/extensions/spellcheck/src/mozEnglishWordUtils.h +++ b/extensions/spellcheck/src/mozEnglishWordUtils.h @@ -43,7 +43,6 @@ #include "nsIUnicodeEncoder.h" #include "nsIUnicodeDecoder.h" #include "nsString.h" -#include "nsICaseConversion.h" #include "nsIUGenCategory.h" #include "mozITXTToHTMLConv.h" @@ -69,7 +68,6 @@ protected: nsString mLanguage; nsString mCharset; - nsCOMPtr mCaseConv; nsCOMPtr mCategories; nsCOMPtr mURLDetector; // used to detect urls so the spell checker can skip them. }; diff --git a/intl/build/nsI18nModule.cpp b/intl/build/nsI18nModule.cpp index 7cdcf610e78..71211864919 100644 --- a/intl/build/nsI18nModule.cpp +++ b/intl/build/nsI18nModule.cpp @@ -59,7 +59,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSemanticUnitScanner) NS_DEFINE_NAMED_CID(NS_LBRK_CID); NS_DEFINE_NAMED_CID(NS_WBRK_CID); NS_DEFINE_NAMED_CID(NS_SEMANTICUNITSCANNER_CID); -NS_DEFINE_NAMED_CID(NS_UNICHARUTIL_CID); NS_DEFINE_NAMED_CID(NS_UNICHARCATEGORY_CID); NS_DEFINE_NAMED_CID(NS_ENTITYCONVERTER_CID); NS_DEFINE_NAMED_CID(NS_SAVEASCHARSET_CID); @@ -95,7 +94,6 @@ static const mozilla::Module::CIDEntry kIntlCIDs[] = { { &kNS_LBRK_CID, false, NULL, nsJISx4051LineBreakerConstructor }, { &kNS_WBRK_CID, false, NULL, nsSampleWordBreakerConstructor }, { &kNS_SEMANTICUNITSCANNER_CID, false, NULL, nsSemanticUnitScannerConstructor }, - { &kNS_UNICHARUTIL_CID, false, NULL, nsCaseConversionImp2Constructor }, { &kNS_UNICHARCATEGORY_CID, false, NULL, nsCategoryImpConstructor }, { &kNS_ENTITYCONVERTER_CID, false, NULL, nsEntityConverterConstructor }, { &kNS_SAVEASCHARSET_CID, false, NULL, nsSaveAsCharsetConstructor }, @@ -133,7 +131,6 @@ static const mozilla::Module::ContractIDEntry kIntlContracts[] = { { NS_LBRK_CONTRACTID, &kNS_LBRK_CID }, { NS_WBRK_CONTRACTID, &kNS_WBRK_CID }, { NS_SEMANTICUNITSCANNER_CONTRACTID, &kNS_SEMANTICUNITSCANNER_CID }, - { NS_UNICHARUTIL_CONTRACTID, &kNS_UNICHARUTIL_CID }, { NS_UNICHARCATEGORY_CONTRACTID, &kNS_UNICHARCATEGORY_CID }, { NS_ENTITYCONVERTER_CONTRACTID, &kNS_ENTITYCONVERTER_CID }, { NS_SAVEASCHARSET_CONTRACTID, &kNS_SAVEASCHARSET_CID }, diff --git a/intl/locale/src/nsCollation.cpp b/intl/locale/src/nsCollation.cpp index 6dd59eba8b6..b522b308828 100644 --- a/intl/locale/src/nsCollation.cpp +++ b/intl/locale/src/nsCollation.cpp @@ -41,7 +41,7 @@ #include "nsIComponentManager.h" #include "nsCollation.h" #include "nsCollationCID.h" -#include "nsUnicharUtilCIID.h" +#include "nsUnicharUtils.h" #include "prmem.h" #include "nsReadableUtils.h" @@ -74,9 +74,6 @@ nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** i nsCollation::nsCollation() { MOZ_COUNT_CTOR(nsCollation); - nsresult res; - mCaseConversion = do_GetService(NS_UNICHARUTIL_CONTRACTID, &res); - NS_ASSERTION(NS_SUCCEEDED(res), "CreateInstance failed for kCaseConversionIID"); } nsCollation::~nsCollation() @@ -86,27 +83,22 @@ nsCollation::~nsCollation() nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut) { - if (!mCaseConversion) { - stringOut = stringIn; + PRInt32 aLength = stringIn.Length(); + + if (aLength <= 64) { + PRUnichar conversionBuffer[64]; + ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); + stringOut.Assign(conversionBuffer, aLength); } else { - PRInt32 aLength = stringIn.Length(); - - if (aLength <= 64) { - PRUnichar conversionBuffer[64]; - mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); - stringOut.Assign(conversionBuffer, aLength); - } - else { - PRUnichar* conversionBuffer; - conversionBuffer = new PRUnichar[aLength]; - if (!conversionBuffer) { - return NS_ERROR_OUT_OF_MEMORY; - } - mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); - stringOut.Assign(conversionBuffer, aLength); - delete [] conversionBuffer; + PRUnichar* conversionBuffer; + conversionBuffer = new PRUnichar[aLength]; + if (!conversionBuffer) { + return NS_ERROR_OUT_OF_MEMORY; } + ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); + stringOut.Assign(conversionBuffer, aLength); + delete [] conversionBuffer; } return NS_OK; } diff --git a/intl/locale/src/nsCollation.h b/intl/locale/src/nsCollation.h index 6986c1de7be..f0fda9fd3dd 100644 --- a/intl/locale/src/nsCollation.h +++ b/intl/locale/src/nsCollation.h @@ -41,7 +41,6 @@ #include "nsICollation.h" -#include "nsICaseConversion.h" #include "nsICharsetConverterManager.h" #include "nsCOMPtr.h" @@ -75,7 +74,6 @@ public: nsresult UnicodeToChar(const nsAString& aSrc, char** dst); protected: - nsCOMPtr mCaseConversion; nsCOMPtr mEncoder; }; diff --git a/intl/unicharutil/src/nsCaseConversionImp2.cpp b/intl/unicharutil/src/nsCaseConversionImp2.cpp index 5361909e523..59e4e489971 100644 --- a/intl/unicharutil/src/nsCaseConversionImp2.cpp +++ b/intl/unicharutil/src/nsCaseConversionImp2.cpp @@ -36,137 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ -#include "pratom.h" -#include "nsUUDll.h" #include "nsCaseConversionImp2.h" -#include "casetable.h" - -// For gUpperToTitle -enum { - kUpperIdx =0, - kTitleIdx -}; - -// For gUpperToTitle -enum { - kLowIdx =0, - kSizeEveryIdx, - kDiffIdx -}; - -#define IS_ASCII(u) ( 0x0000 == ((u) & 0xFF80)) -#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a)) -#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a)) -#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u)) -#define IS_ASCII_SPACE(u) ( 0x0020 == (u) ) - -#define IS_NOCASE_CHAR(u) (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8))))) - -// Size of Tables - -#define CASE_MAP_CACHE_SIZE 0x40 -#define CASE_MAP_CACHE_MASK 0x3F - -nsCaseConversionImp2* gCaseConv = nsnull; - -struct nsCompressedMap { - const PRUnichar *mTable; - PRUint32 mSize; - PRUint32 mCache[CASE_MAP_CACHE_SIZE]; - PRUint32 mLastBase; - - PRUnichar Map(PRUnichar aChar) - { - // no need to worry about thread safety since cached values are - // not objects but primitive data types which could be - // accessed in atomic operations. We need to access - // the whole 32 bit of cachedData at once in order to make it - // thread safe. Never access bits from mCache directly. - - PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK]; - if(aChar == ((cachedData >> 16) & 0x0000FFFF)) - return (cachedData & 0x0000FFFF); - - // try the last index first - // store into local variable so we can be thread safe - PRUint32 base = mLastBase; - PRUnichar res = 0; - - if (( aChar <= ((mTable[base+kSizeEveryIdx] >> 8) + - mTable[base+kLowIdx])) && - ( mTable[base+kLowIdx] <= aChar )) - { - // Hit the last base - if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && - (0 != ((aChar - mTable[base+kLowIdx]) % - (mTable[base+kSizeEveryIdx] & 0x00FF)))) - { - res = aChar; - } else { - res = aChar + mTable[base+kDiffIdx]; - } - } else { - res = this->Lookup(0, (mSize/2), mSize-1, aChar); - } - - mCache[aChar & CASE_MAP_CACHE_MASK] = - (((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res)); - return res; - } - - PRUnichar Lookup(PRUint32 l, - PRUint32 m, - PRUint32 r, - PRUnichar aChar) - { - PRUint32 base = m*3; - if ( aChar > ((mTable[base+kSizeEveryIdx] >> 8) + - mTable[base+kLowIdx])) - { - if( l > m ) - return aChar; - PRUint32 newm = (m+r+1)/2; - if(newm == m) - newm++; - return this->Lookup(m+1, newm , r, aChar); - - } else if ( mTable[base+kLowIdx] > aChar ) { - if( r < m ) - return aChar; - PRUint32 newm = (l+m-1)/2; - if(newm == m) - newm++; - return this->Lookup(l, newm, m-1, aChar); - - } else { - if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && - (0 != ((aChar - mTable[base+kLowIdx]) % - (mTable[base+kSizeEveryIdx] & 0x00FF)))) - { - return aChar; - } - mLastBase = base; // cache the base - return aChar + mTable[base+kDiffIdx]; - } - } -}; - -static nsCompressedMap gUpperMap = { - reinterpret_cast(&gToUpper[0]), - gToUpperItems -}; - -static nsCompressedMap gLowerMap = { - reinterpret_cast(&gToLower[0]), - gToLowerItems -}; - -nsCaseConversionImp2* nsCaseConversionImp2::GetInstance() -{ - if (!gCaseConv) - gCaseConv = new nsCaseConversionImp2(); - return gCaseConv; -} +#include "nsUnicharUtils.h" NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::AddRef(void) { @@ -180,166 +51,45 @@ NS_IMETHODIMP_(nsrefcnt) nsCaseConversionImp2::Release(void) NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsCaseConversionImp2, nsICaseConversion) -nsresult nsCaseConversionImp2::ToUpper( - PRUnichar aChar, PRUnichar* aReturn -) +NS_IMETHODIMP nsCaseConversionImp2::ToUpper(PRUnichar aChar, PRUnichar* aReturn) { - if( IS_ASCII(aChar)) // optimize for ASCII - { - if(IS_ASCII_LOWER(aChar)) - *aReturn = aChar - 0x0020; - else - *aReturn = aChar; - } - else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case - { - *aReturn = aChar; - } - else - { - *aReturn = gUpperMap.Map(aChar); - } + *aReturn = ToUpperCase(aChar); return NS_OK; } -// a non-virtual version of ToLower -static PRUnichar FastToLower( - PRUnichar aChar -) +NS_IMETHODIMP nsCaseConversionImp2::ToLower(PRUnichar aChar, PRUnichar* aReturn) { - if( IS_ASCII(aChar)) // optimize for ASCII - { - if(IS_ASCII_UPPER(aChar)) - return aChar + 0x0020; - else - return aChar; - } - else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case - { - return aChar; - } - - return gLowerMap.Map(aChar); -} - -nsresult nsCaseConversionImp2::ToLower( - PRUnichar aChar, PRUnichar* aReturn -) -{ - *aReturn = FastToLower(aChar); + *aReturn = ToLowerCase(aChar); return NS_OK; } -nsresult nsCaseConversionImp2::ToTitle( - PRUnichar aChar, PRUnichar* aReturn -) +NS_IMETHODIMP nsCaseConversionImp2::ToTitle(PRUnichar aChar, PRUnichar* aReturn) { - if( IS_ASCII(aChar)) // optimize for ASCII - { - return this->ToUpper(aChar, aReturn); - } - else if( IS_NOCASE_CHAR(aChar)) // optimize for block which have no case - { - *aReturn = aChar; - } - else - { - // First check for uppercase characters whose titlecase mapping is - // different, like U+01F1 DZ: they must remain unchanged. - if( 0x01C0 == ( aChar & 0xFFC0)) // 0x01Cx - 0x01Fx - { - for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) { - if ( aChar == gUpperToTitle[(i*2)+kUpperIdx]) { - *aReturn = aChar; - return NS_OK; - } - } - } - - PRUnichar upper = gUpperMap.Map(aChar); - - if( 0x01C0 == ( upper & 0xFFC0)) // 0x01Cx - 0x01Fx - { - for(PRUint32 i = 0 ; i < gUpperToTitleItems; i++) { - if ( upper == gUpperToTitle[(i*2)+kUpperIdx]) { - *aReturn = gUpperToTitle[(i*2)+kTitleIdx]; - return NS_OK; - } - } - } - *aReturn = upper; - } + *aReturn = ToTitleCase(aChar); return NS_OK; } -nsresult nsCaseConversionImp2::ToUpper( - const PRUnichar* anArray, PRUnichar* aReturn, PRUint32 aLen -) +NS_IMETHODIMP nsCaseConversionImp2::ToUpper(const PRUnichar* anArray, + PRUnichar* aReturn, + PRUint32 aLen) { - PRUint32 i; - for(i=0;i -static nsICaseConversion* gCaseConv = nsnull; +// For gUpperToTitle +enum { + kUpperIdx =0, + kTitleIdx +}; -nsICaseConversion* -NS_GetCaseConversion() -{ - if (!gCaseConv) { - nsresult rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &gCaseConv); - if (NS_FAILED(rv)) { - NS_ERROR("Failed to get the case conversion service!"); - gCaseConv = nsnull; +// For gUpperToTitle +enum { + kLowIdx =0, + kSizeEveryIdx, + kDiffIdx +}; + +#define IS_ASCII(u) ( 0x0000 == ((u) & 0xFF80)) +#define IS_ASCII_UPPER(u) ((0x0041 <= (u)) && ( (u) <= 0x005a)) +#define IS_ASCII_LOWER(u) ((0x0061 <= (u)) && ( (u) <= 0x007a)) +#define IS_ASCII_ALPHA(u) (IS_ASCII_UPPER(u) || IS_ASCII_LOWER(u)) +#define IS_ASCII_SPACE(u) ( 0x0020 == (u) ) + +#define IS_NOCASE_CHAR(u) (0==(1&(gCaseBlocks[(u)>>13]>>(0x001F&((u)>>8))))) + +// Size of Tables + +#define CASE_MAP_CACHE_SIZE 0x40 +#define CASE_MAP_CACHE_MASK 0x3F + +struct nsCompressedMap { + const PRUnichar *mTable; + PRUint32 mSize; + PRUint32 mCache[CASE_MAP_CACHE_SIZE]; + PRUint32 mLastBase; + + PRUnichar Map(PRUnichar aChar) + { + // no need to worry about thread safety since cached values are + // not objects but primitive data types which could be + // accessed in atomic operations. We need to access + // the whole 32 bit of cachedData at once in order to make it + // thread safe. Never access bits from mCache directly. + + PRUint32 cachedData = mCache[aChar & CASE_MAP_CACHE_MASK]; + if(aChar == ((cachedData >> 16) & 0x0000FFFF)) + return (cachedData & 0x0000FFFF); + + // try the last index first + // store into local variable so we can be thread safe + PRUint32 base = mLastBase; + PRUnichar res = 0; + + if (( aChar <= ((mTable[base+kSizeEveryIdx] >> 8) + + mTable[base+kLowIdx])) && + ( mTable[base+kLowIdx] <= aChar )) + { + // Hit the last base + if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && + (0 != ((aChar - mTable[base+kLowIdx]) % + (mTable[base+kSizeEveryIdx] & 0x00FF)))) + { + res = aChar; + } else { + res = aChar + mTable[base+kDiffIdx]; + } + } else { + res = this->Lookup(0, (mSize/2), mSize-1, aChar); + } + + mCache[aChar & CASE_MAP_CACHE_MASK] = + (((aChar << 16) & 0xFFFF0000) | (0x0000FFFF & res)); + return res; + } + + PRUnichar Lookup(PRUint32 l, + PRUint32 m, + PRUint32 r, + PRUnichar aChar) + { + PRUint32 base = m*3; + if ( aChar > ((mTable[base+kSizeEveryIdx] >> 8) + + mTable[base+kLowIdx])) + { + if( l > m ) + return aChar; + PRUint32 newm = (m+r+1)/2; + if(newm == m) + newm++; + return this->Lookup(m+1, newm , r, aChar); + + } else if ( mTable[base+kLowIdx] > aChar ) { + if( r < m ) + return aChar; + PRUint32 newm = (l+m-1)/2; + if(newm == m) + newm++; + return this->Lookup(l, newm, m-1, aChar); + + } else { + if(((mTable[base+kSizeEveryIdx] & 0x00FF) > 0) && + (0 != ((aChar - mTable[base+kLowIdx]) % + (mTable[base+kSizeEveryIdx] & 0x00FF)))) + { + return aChar; + } + mLastBase = base; // cache the base + return aChar + mTable[base+kDiffIdx]; } } - return gCaseConv; -} +}; + +static nsCompressedMap gUpperMap = { + reinterpret_cast(&gToUpper[0]), + gToUpperItems +}; + +static nsCompressedMap gLowerMap = { + reinterpret_cast(&gToLower[0]), + gToLowerItems +}; void ToLowerCase(nsAString& aString) { - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) { - PRUnichar *buf = aString.BeginWriting(); - caseConv->ToLower(buf, buf, aString.Length()); - } - else - NS_WARNING("No case converter: no conversion done"); + PRUnichar *buf = aString.BeginWriting(); + ToLowerCase(buf, buf, aString.Length()); } void @@ -80,30 +179,18 @@ ToLowerCase(const nsAString& aSource, nsAString& aDest) { const PRUnichar *in; - PRUint32 len = NS_StringGetData(aSource, &in); - PRUnichar *out; + PRUint32 len = NS_StringGetData(aSource, &in); NS_StringGetMutableData(aDest, len, &out); - - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (out && caseConv) - caseConv->ToLower(in, out, len); - else { - NS_WARNING("No case converter: only copying"); - aDest.Assign(aSource); - } + NS_ASSERTION(out, "Uh..."); + ToLowerCase(in, out, len); } void ToUpperCase(nsAString& aString) { - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) { - PRUnichar *buf = aString.BeginWriting(); - caseConv->ToUpper(buf, buf, aString.Length()); - } - else - NS_WARNING("No case converter: no conversion done"); + PRUnichar *buf = aString.BeginWriting(); + ToUpperCase(buf, buf, aString.Length()); } void @@ -111,18 +198,11 @@ ToUpperCase(const nsAString& aSource, nsAString& aDest) { const PRUnichar *in; - PRUint32 len = NS_StringGetData(aSource, &in); - PRUnichar *out; + PRUint32 len = NS_StringGetData(aSource, &in); NS_StringGetMutableData(aDest, len, &out); - - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (out && caseConv) - caseConv->ToUpper(in, out, len); - else { - NS_WARNING("No case converter: only copying"); - aDest.Assign(aSource); - } + NS_ASSERTION(out, "Uh..."); + ToUpperCase(in, out, len); } #ifdef MOZILLA_INTERNAL_API @@ -132,16 +212,7 @@ nsCaseInsensitiveStringComparator::operator()(const PRUnichar* lhs, const PRUnichar* rhs, PRUint32 aLength) const { - PRInt32 result; - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) - caseConv->CaseInsensitiveCompare(lhs, rhs, aLength, &result); - else { - NS_WARNING("No case converter: using default"); - nsDefaultStringComparator comparator; - result = comparator(lhs, rhs, aLength); - } - return result; + return CaseInsensitiveCompare(lhs, rhs, aLength); } PRInt32 @@ -152,18 +223,8 @@ nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs, if (lhs == rhs) return 0; - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) { - caseConv->ToLower(lhs, &lhs); - caseConv->ToLower(rhs, &rhs); - } - else { - if (lhs < 256) - lhs = tolower(char(lhs)); - if (rhs < 256) - rhs = tolower(char(rhs)); - NS_WARNING("No case converter: no conversion done"); - } + lhs = ToLowerCase(lhs); + rhs = ToLowerCase(rhs); if (lhs == rhs) return 0; @@ -173,54 +234,109 @@ nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs, return 1; } -#else // MOZILLA_INTERNAL_API +#endif // MOZILLA_INTERNAL_API PRInt32 CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len) { - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (!caseConv) - return NS_strcmp(a, b); - - PRInt32 result; - caseConv->CaseInsensitiveCompare(a, b, len, &result); - return result; + NS_ASSERTION(a && b, "Do not pass in invalid pointers!"); + + if (len) { + do { + PRUnichar c1 = *a++; + PRUnichar c2 = *b++; + + if (c1 != c2) { + c1 = ToLowerCase(c1); + c2 = ToLowerCase(c2); + if (c1 != c2) { + if (c1 < c2) { + return -1; + } + return 1; + } + } + } while (--len != 0); + } + return 0; } -#endif // MOZILLA_INTERNAL_API - PRUnichar ToLowerCase(PRUnichar aChar) { - PRUnichar result; - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) - caseConv->ToLower(aChar, &result); - else { - NS_WARNING("No case converter: no conversion done"); - if (aChar < 256) - result = tolower(char(aChar)); + if (IS_ASCII(aChar)) { + if (IS_ASCII_UPPER(aChar)) + return aChar + 0x0020; else - result = aChar; + return aChar; + } else if (IS_NOCASE_CHAR(aChar)) { + return aChar; + } + + return gLowerMap.Map(aChar); +} + +void +ToLowerCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen) +{ + for (PRUint32 i = 0; i < aLen; i++) { + aOut[i] = ToLowerCase(aIn[i]); } - return result; } PRUnichar ToUpperCase(PRUnichar aChar) { - PRUnichar result; - nsICaseConversion* caseConv = NS_GetCaseConversion(); - if (caseConv) - caseConv->ToUpper(aChar, &result); - else { - NS_WARNING("No case converter: no conversion done"); - if (aChar < 256) - result = toupper(char(aChar)); + if (IS_ASCII(aChar)) { + if (IS_ASCII_LOWER(aChar)) + return aChar - 0x0020; else - result = aChar; + return aChar; + } else if (IS_NOCASE_CHAR(aChar)) { + return aChar; } - return result; + + return gUpperMap.Map(aChar); +} + +void +ToUpperCase(const PRUnichar *aIn, PRUnichar *aOut, PRUint32 aLen) +{ + for (PRUint32 i = 0; i < aLen; i++) { + aOut[i] = ToUpperCase(aIn[i]); + } +} + +PRUnichar +ToTitleCase(PRUnichar aChar) +{ + if (IS_ASCII(aChar)) { + return ToUpperCase(aChar); + } else if (IS_NOCASE_CHAR(aChar)) { + return aChar; + } + + // First check for uppercase characters whose titlecase mapping is + // different, like U+01F1 DZ: they must remain unchanged. + if (0x01C0 == (aChar & 0xFFC0)) { + for (PRUint32 i = 0; i < gUpperToTitleItems; i++) { + if (aChar == gUpperToTitle[(i*2)+kUpperIdx]) { + return aChar; + } + } + } + + PRUnichar upper = gUpperMap.Map(aChar); + + if (0x01C0 == ( upper & 0xFFC0)) { + for (PRUint32 i = 0 ; i < gUpperToTitleItems; i++) { + if (upper == gUpperToTitle[(i*2)+kUpperIdx]) { + return gUpperToTitle[(i*2)+kTitleIdx]; + } + } + } + + return upper; } diff --git a/intl/unicharutil/util/nsUnicharUtils.h b/intl/unicharutil/util/nsUnicharUtils.h index ab25c6d679a..60b7d250ef6 100644 --- a/intl/unicharutil/util/nsUnicharUtils.h +++ b/intl/unicharutil/util/nsUnicharUtils.h @@ -56,8 +56,12 @@ void ToUpperCase(nsAString&); void ToLowerCase(const nsAString& aSource, nsAString& aDest); void ToUpperCase(const nsAString& aSource, nsAString& aDest); -PRUnichar ToUpperCase(PRUnichar); PRUnichar ToLowerCase(PRUnichar); +PRUnichar ToUpperCase(PRUnichar); +PRUnichar ToTitleCase(PRUnichar); + +void ToLowerCase(const PRUnichar*, PRUnichar*, PRUint32); +void ToUpperCase(const PRUnichar*, PRUnichar*, PRUint32); inline PRBool IsUpperCase(PRUnichar c) { return ToLowerCase(c) != c; @@ -72,11 +76,11 @@ inline PRBool IsLowerCase(PRUnichar c) { class nsCaseInsensitiveStringComparator : public nsStringComparator { public: - virtual int operator() (const PRUnichar*, - const PRUnichar*, - PRUint32 aLength) const; - virtual int operator() (PRUnichar, - PRUnichar) const; + virtual PRInt32 operator() (const PRUnichar*, + const PRUnichar*, + PRUint32 aLength) const; + virtual PRInt32 operator() (PRUnichar, + PRUnichar) const; }; class nsCaseInsensitiveStringArrayComparator @@ -107,11 +111,9 @@ CaseInsensitiveFindInReadable(const nsAString& aPattern, nsCaseInsensitiveStringComparator()); } -#else // MOZILLA_INTERNAL_API - -NS_HIDDEN_(PRInt32) -CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len); - #endif // MOZILLA_INTERNAL_API +PRInt32 +CaseInsensitiveCompare(const PRUnichar *a, const PRUnichar *b, PRUint32 len); + #endif /* nsUnicharUtils_h__ */ diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 00609d2a365..012913e45a4 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -84,7 +84,6 @@ #include "nsTextFrameTextRunCache.h" #include "nsExpirationTracker.h" #include "nsTextFrame.h" -#include "nsICaseConversion.h" #include "nsIUGenCategory.h" #include "nsUnicharUtilCIID.h" @@ -6765,14 +6764,14 @@ static PRUnichar TransformChar(const nsStyleText* aStyle, gfxTextRun* aTextRun, } switch (aStyle->mTextTransform) { case NS_STYLE_TEXT_TRANSFORM_LOWERCASE: - nsContentUtils::GetCaseConv()->ToLower(aChar, &aChar); + aChar = ToLowerCase(aChar); break; case NS_STYLE_TEXT_TRANSFORM_UPPERCASE: - nsContentUtils::GetCaseConv()->ToUpper(aChar, &aChar); + aChar = ToUpperCase(aChar); break; case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE: if (aTextRun->CanBreakLineBefore(aSkippedOffset)) { - nsContentUtils::GetCaseConv()->ToTitle(aChar, &aChar); + aChar = ToTitleCase(aChar); } break; } diff --git a/layout/generic/nsTextRunTransformations.cpp b/layout/generic/nsTextRunTransformations.cpp index fd12936a5f9..2422946150a 100644 --- a/layout/generic/nsTextRunTransformations.cpp +++ b/layout/generic/nsTextRunTransformations.cpp @@ -40,11 +40,11 @@ #include "nsTextFrameUtils.h" #include "gfxSkipChars.h" -#include "nsICaseConversion.h" #include "nsStyleConsts.h" #include "nsStyleContext.h" #include "gfxContext.h" #include "nsContentUtils.h" +#include "nsUnicharUtils.h" #define SZLIG 0x00DF @@ -234,10 +234,6 @@ void nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) { - nsICaseConversion* converter = nsContentUtils::GetCaseConv(); - if (!converter) - return; - gfxFontGroup* fontGroup = aTextRun->GetFontGroup(); gfxFontStyle fontStyle = *fontGroup->GetStyle(); fontStyle.size *= 0.8; @@ -279,7 +275,7 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, if (styles[i]->GetStyleFont()->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS) { PRUnichar ch = str[i]; PRUnichar ch2; - converter->ToUpper(ch, &ch2); + ch2 = ToUpperCase(ch); isLowercase = ch != ch2 || ch == SZLIG; } else { // Don't transform the character! I.e., pretend that it's not lowercase @@ -332,10 +328,6 @@ void nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) { - nsICaseConversion* converter = nsContentUtils::GetCaseConv(); - if (!converter) - return; - PRUint32 length = aTextRun->GetLength(); const PRUnichar* str = aTextRun->GetTextUnicode(); nsRefPtr* styles = aTextRun->mStyles.Elements(); @@ -360,7 +352,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, switch (style) { case NS_STYLE_TEXT_TRANSFORM_LOWERCASE: - converter->ToLower(ch, &ch); + ch = ToLowerCase(ch); break; case NS_STYLE_TEXT_TRANSFORM_UPPERCASE: if (ch == SZLIG) { @@ -368,7 +360,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, extraChar = PR_TRUE; ch = 'S'; } else { - converter->ToUpper(ch, &ch); + ch = ToUpperCase(ch); } break; case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE: @@ -378,7 +370,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun, extraChar = PR_TRUE; ch = 'S'; } else { - converter->ToTitle(ch, &ch); + ch = ToTitleCase(ch); } } break; diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index b06f4fd14bb..7837790d55e 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -138,7 +138,8 @@ GARBAGE += \ dlldeps-javaxpcom.cpp \ $(NULL) -LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util +LOCAL_INCLUDES += -I$(topsrcdir)/intl/unicharutil/util \ + -I$(topsrcdir)/intl/unicharutil/src ifdef MOZ_RDF EXTRA_DEPS += \