From 1496fa7bc3cb9ddb3756a54cdc2ef524cd1ccaed Mon Sep 17 00:00:00 2001 From: "katakai%japan.sun.com" Date: Tue, 18 Sep 2001 10:14:38 +0000 Subject: [PATCH] bug 84380 Need a component that generates thai presentation forms Updates for *extensions*/ctl for prabhat@Sun, r=ftank for check-in A Incorporate frank's review fixes (08/07) B Bugfix in TIS620Encoder C Fix memory corruption D Makefile changes in pangoLite directory to install pango.modules git-svn-id: svn://10.0.0.236/trunk@103086 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/extensions/ctl/public/nsILE.h | 16 +- mozilla/extensions/ctl/src/nsCtlLEModule.cpp | 6 +- mozilla/extensions/ctl/src/nsULE.cpp | 398 ++++++++++++++---- mozilla/extensions/ctl/src/nsULE.h | 47 ++- .../extensions/ctl/src/nsUnicodeToTIS620.cpp | 126 ++++-- .../extensions/ctl/src/nsUnicodeToTIS620.h | 23 +- .../extensions/ctl/src/pangoLite/Makefile.in | 4 +- .../ctl/src/pangoLite/pango-engine.h | 2 +- .../ctl/src/pangoLite/pango-glyph.h | 2 +- .../ctl/src/pangoLite/pango.modules | 5 + mozilla/extensions/ctl/src/pangoLite/shape.c | 2 +- .../extensions/ctl/src/thaiShaper/thai-x.c | 44 +- 12 files changed, 497 insertions(+), 178 deletions(-) create mode 100755 mozilla/extensions/ctl/src/pangoLite/pango.modules diff --git a/mozilla/extensions/ctl/public/nsILE.h b/mozilla/extensions/ctl/public/nsILE.h index 9c5d5971681..55c2bcf34d4 100644 --- a/mozilla/extensions/ctl/public/nsILE.h +++ b/mozilla/extensions/ctl/public/nsILE.h @@ -30,9 +30,6 @@ #include "nsISupports.h" #include "nsCtlCIID.h" -#include "pango-types.h" -#include "pango-glyph.h" - /* * nsILE Interface declaration */ @@ -41,13 +38,16 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILE_IID) - NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32, PangoAnalysis*, - PangoGlyphString*) = 0; - NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32, const char*, char*, PRSize*) = 0; - NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32, - const char*, PRUint32*, PRSize*) = 0; + NS_IMETHOD PrevCluster(const PRUnichar*, PRUint32, + const PRInt32, PRInt32*) = 0; + + NS_IMETHOD NextCluster(const PRUnichar*, PRUint32, + const PRInt32, PRInt32*) = 0; + + NS_IMETHOD GetRangeOfCluster(const PRUnichar*, PRUint32, + const PRInt32, PRInt32*, PRInt32*) = 0; }; #endif // nsILE_h diff --git a/mozilla/extensions/ctl/src/nsCtlLEModule.cpp b/mozilla/extensions/ctl/src/nsCtlLEModule.cpp index 52ef2256bf4..294ae6c023e 100644 --- a/mozilla/extensions/ctl/src/nsCtlLEModule.cpp +++ b/mozilla/extensions/ctl/src/nsCtlLEModule.cpp @@ -46,14 +46,14 @@ PRInt32 g_InstanceCount = 0; PRInt32 g_LockCount = 0; NS_IMPL_NSUCONVERTERREGSELF -NS_UCONV_REG_UNREG(nsUnicodeToTIS620, "Unicode", "tis620", NS_UNICODETOTIS620_CID); +NS_UCONV_REG_UNREG(nsUnicodeToTIS620, "Unicode", "tis620-2", NS_UNICODETOTIS620_CID); NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToTIS620); static nsModuleComponentInfo components[] = { - { ENCODER_NAME_BASE "tis620" , NS_UNICODETOTIS620_CID, - NS_UNICODEENCODER_CONTRACTID_BASE "tis620", + { ENCODER_NAME_BASE "tis620-2" , NS_UNICODETOTIS620_CID, + NS_UNICODEENCODER_CONTRACTID_BASE "tis620-2", nsUnicodeToTIS620Constructor, nsUnicodeToTIS620RegSelf, nsUnicodeToTIS620UnRegSelf }, { "Unicode Layout Engine", NS_ULE_CID, NS_ULE_PROGID, diff --git a/mozilla/extensions/ctl/src/nsULE.cpp b/mozilla/extensions/ctl/src/nsULE.cpp index 5884ee98bca..6671e76b071 100755 --- a/mozilla/extensions/ctl/src/nsULE.cpp +++ b/mozilla/extensions/ctl/src/nsULE.cpp @@ -23,9 +23,6 @@ * Contributor(s): */ -#include -#include /* isspace */ - #include "nsULE.h" #include "nsString.h" @@ -34,6 +31,14 @@ #include "pango-modules.h" #include "pango-utils.h" +#define CLEAN_RUN \ + aPtr = aRun.head; \ + for (int ct=0; (ct < aRun.numRuns); ct++) { \ + aTmpPtr = aPtr; \ + aPtr = aPtr->next; \ + delete(aTmpPtr); \ + } + /* * Start of nsULE Public Functions */ @@ -55,7 +60,7 @@ nsULE::GetShaper(const PRUnichar *inBuf, { PangoEngineShape *aEngine = NULL; PangoMap *aMap = NULL; - guint engine_type_id = 0, render_type_id = 0; + guint engine_type_id = 0, render_type_id = 0; PRUnichar wc = inBuf[0]; if ((inBuf == (PRUnichar*)NULL) || (aLength <= 0)) { @@ -75,38 +80,93 @@ nsULE::GetShaper(const PRUnichar *inBuf, return aEngine; } -// Analysis needs to have valid direction and font charset -NS_IMETHODIMP -nsULE::GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, - PangoAnalysis *aAnalysis, - PangoGlyphString *aGlyphs) +PRInt32 +nsULE::SeparateScript(const PRUnichar* aSrcBuf, + PRInt32 aSrcLen, + textRunList *aRunList) { - PangoEngineShape *aShaper = aAnalysis->shape_engine; - PRSize inLen = 0; - char *utf8Str = NULL; + int ct = 0, start = 0; + PRBool isCtl = PR_FALSE; + struct textRun *tmpChunk; + PangoEngineShape *aEngine = NULL; + PangoMap *aMap = NULL; + guint engine_type_id = 0, render_type_id = 0; - if (aShaper != NULL) { + engine_type_id = g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE); + render_type_id = g_quark_from_static_string(PANGO_RENDER_TYPE_X); + aMap = pango_find_map("en_US", engine_type_id, render_type_id); + + for (ct = 0; ct < aSrcLen;) { + tmpChunk = new textRun; + + if (aRunList->numRuns == 0) + aRunList->head = tmpChunk; + else + aRunList->cur->next = tmpChunk; + aRunList->cur = tmpChunk; + aRunList->numRuns++; - nsAutoString strBuf(aString); + tmpChunk->start = &aSrcBuf[ct]; + start = ct; + aEngine = (PangoEngineShape*) + pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]); + isCtl = (aEngine != NULL); - // Convert Unicode string to UTF8 and store in buffer - utf8Str = strBuf.ToNewUTF8String(); - inLen = strlen(utf8Str); + if (isCtl) { + while (isCtl && ct < aSrcLen) { + aEngine = (PangoEngineShape*) + pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]); + isCtl = (aEngine != NULL); + if (isCtl) + ct++; + } + tmpChunk->isOther = PR_FALSE; + } + else { + while (!isCtl && ct < aSrcLen) { + aEngine = (PangoEngineShape*) + pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]); + isCtl = (aEngine != NULL); + if (!isCtl) + ct++; + } + tmpChunk->isOther = PR_TRUE; + } + + tmpChunk->length = ct - start; + } + return (PRInt32)aRunList->numRuns; +} - aShaper->script_shape(aAnalysis->fontCharset, utf8Str, inLen, - aAnalysis, aGlyphs); - nsMemory::Free(utf8Str); +// Analysis needs to have valid direction and font charset +PRInt32 +nsULE::GetRawCtlData(const PRUnichar *aString, + PRUint32 aLength, + PangoGlyphString *aGlyphs) +{ + PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL); + PangoAnalysis aAnalysis; + + aAnalysis.shape_engine = aShaper; + aAnalysis.aDir = PANGO_DIRECTION_LTR; + // In future fontCharset hard-coding should be removed + aAnalysis.fontCharset = strdup("tis620-2"); + + if (aShaper != NULL) { + aShaper->script_shape(aAnalysis.fontCharset, aString, aLength, + &aAnalysis, aGlyphs); + nsMemory::Free(aAnalysis.fontCharset); } else { /* No Shaper - Copy Input to output */ + return 0; } - return NS_OK; + return aGlyphs->num_glyphs; } NS_IMETHODIMP nsULE::GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, + PRUint32 aLength, const char *fontCharset, char *aGlyphs, PRSize *aOutLength) @@ -114,27 +174,15 @@ nsULE::GetPresentationForm(const PRUnichar *aString, PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL); PangoAnalysis aAnalysis; PangoGlyphString *tmpGlyphs = pango_glyph_string_new(); - PRSize inLen = 0; int aSize = 0; - char *utf8Str = NULL; aAnalysis.shape_engine = aShaper; aAnalysis.aDir = PANGO_DIRECTION_LTR; aAnalysis.fontCharset = (char*)fontCharset; - if (aShaper != NULL) { - - nsAutoString strBuf; - strBuf.Assign(aString, aLength); - - // Convert Unicode string to UTF8 and store in buffer - utf8Str = NULL; - utf8Str = strBuf.ToNewUTF8String(); - inLen = strlen(utf8Str); - - aShaper->script_shape(fontCharset, utf8Str, inLen, - &aAnalysis, tmpGlyphs); - nsMemory::Free(utf8Str); + if (aShaper != NULL) { + aShaper->script_shape(fontCharset, aString, aLength, + &aAnalysis, tmpGlyphs); if (tmpGlyphs->num_glyphs > 0) { // Note : Does NOT handle 2 byte fonts aSize = tmpGlyphs->num_glyphs; @@ -151,50 +199,246 @@ nsULE::GetPresentationForm(const PRUnichar *aString, return NS_OK; } -NS_IMETHODIMP -nsULE::GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, - const char *fontCharset, - PRUint32 *aGlyphs, - PRSize *aOutLength) +// This routine returns the string index of the next cluster +// corresponding to the cluster at string index 'aIndex' +// Note : Index returned is the end-offset +// Cursor position iterates between 0 and (position - 1) +NS_IMETHODIMP +nsULE::NextCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *nextOffset) { - PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL); - PangoAnalysis aAnalysis; - PangoGlyphString *tmpGlyphs = pango_glyph_string_new(); - PRSize inLen = 0; - int aSize = 0; - char *utf8Str = NULL; + textRunList aRun; + textRun *aPtr, *aTmpPtr; + PRInt32 aStrCt=0; + PRBool isBoundary=PR_FALSE; + PangoGlyphString *aGlyphData=pango_glyph_string_new(); + + if (aIndex >= aLength-1) { + *nextOffset = aLength; // End + return NS_OK; + } - aAnalysis.shape_engine = aShaper; - aAnalysis.aDir = PANGO_DIRECTION_LTR; - aAnalysis.fontCharset = (char*)fontCharset; + aRun.numRuns = 0; + SeparateScript(aString, aLength, &aRun); - if (aShaper != NULL) { + aPtr = aRun.head; + for (int i=0; (i < aRun.numRuns); i++) { + PRInt32 runLen=0; + + runLen = aPtr->length; - nsAutoString strBuf; - strBuf.Assign(aString, aLength); + if ((aStrCt+runLen) < aIndex) /* Skip Run and continue */ + aStrCt += runLen; - // Convert Unicode string to UTF8 and store in buffer - utf8Str = NULL; - utf8Str = strBuf.ToNewUTF8String(); - inLen = strlen(utf8Str); - - aShaper->script_shape(fontCharset, utf8Str, inLen, - &aAnalysis, tmpGlyphs); - nsMemory::Free(utf8Str); - if (tmpGlyphs->num_glyphs > 0) { - aSize = tmpGlyphs->num_glyphs; - // if (*aOutLength < aSize) - // trouble - for (int i = 0; i < aSize; i++) - aGlyphs[i] = tmpGlyphs->glyphs[i].glyph; + else if ((aStrCt+runLen) == aIndex) { + isBoundary = PR_TRUE;/* Script Boundary - Skip a cell in next iteration */ + aStrCt += runLen; } - *aOutLength = (PRSize)aSize; + + else { + if (aPtr->isOther) { + *nextOffset = aIndex+1; + CLEAN_RUN + return NS_OK; + } + else { /* CTL Cell Movement */ + PRInt32 j, startCt, beg, end, numCur; + + startCt=aStrCt; + GetRawCtlData(aPtr->start, runLen, aGlyphData); + + numCur=beg=0; + for (j=0; jnum_glyphs; j++) { + while ((!aGlyphData->glyphs[j].attr.is_cluster_start) && + jnum_glyphs) + j++; + if (j>=aGlyphData->num_glyphs) + end=runLen; + else + end=aGlyphData->log_clusters[j]; + numCur += end-beg; + if (startCt+numCur > aIndex) + break; + else + beg=end; + } + + // Found Cluster - Start of Next == End Of Current + *nextOffset = startCt+numCur; + CLEAN_RUN + return NS_OK; + } + } + aPtr = aPtr->next; } - else { - // Should not reach here are checks are set - // in upper layers - /* Alternately, if no Shaper - Copy Input to output */ - } - return NS_OK; + /* UNUSED */ + CLEAN_RUN +} + +// This routine returns the end-offset of the previous block +// corresponding to string index 'aIndex' +NS_IMETHODIMP +nsULE::PrevCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *prevOffset) +{ + textRunList aRun; + textRun *aPtr, *aTmpPtr; + PRInt32 aStrCt=0, startCt=0, glyphct=0; + PangoGlyphString *aGlyphData=pango_glyph_string_new(); + + if (aIndex<=1) { + *prevOffset=0; // End + return NS_OK; + } + + aRun.numRuns=0; + SeparateScript(aString, aLength, &aRun); + + // Get the index of current cluster + aPtr=aRun.head; + for (int i=0; ilength; + + if ((aStrCt+runLen) < aIndex) /* Skip Run */ + aStrCt += runLen; + + else if ((aStrCt+runLen) == aIndex) { + if (aPtr->isOther) { + *prevOffset=aIndex-1; + CLEAN_RUN + return NS_OK; + } + else { /* Move back a cluster */ + startCt=aStrCt; + GetRawCtlData(aPtr->start, runLen, aGlyphData); + + glyphct=aGlyphData->num_glyphs-1; + while (glyphct > 0) { + if (aGlyphData->glyphs[glyphct].attr.is_cluster_start) { + *prevOffset=startCt+aGlyphData->log_clusters[glyphct]; + CLEAN_RUN + return NS_OK; + } + --glyphct; + } + *prevOffset=startCt; + CLEAN_RUN + return NS_OK; + } + } + else { + if (aPtr->isOther) { + *prevOffset=aIndex-1; + CLEAN_RUN + return NS_OK; + } + else { + PRInt32 j,beg,end,numPrev,numCur; + + startCt=aStrCt; + GetRawCtlData(aPtr->start, runLen, aGlyphData); + + numPrev=numCur=beg=0; + for (j=1; jnum_glyphs; j++) { + while ((!aGlyphData->glyphs[j].attr.is_cluster_start) && + jnum_glyphs) + j++; + if (j>=aGlyphData->num_glyphs) + end=runLen; + else + end=aGlyphData->log_clusters[j]; + numCur += end-beg; + if (numCur+startCt >= aIndex) + break; + else { + beg=end; + numPrev=numCur; + } + } + *prevOffset=startCt+numPrev; + CLEAN_RUN + return NS_OK; + } + } + aPtr=aPtr->next; + } + /* UNUSED */ + CLEAN_RUN +} + +// This routine returns the end-offset of the previous block +// corresponding to string index 'aIndex' +NS_IMETHODIMP +nsULE::GetRangeOfCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *aStart, + PRInt32 *aEnd) +{ + textRunList aRun; + textRun *aPtr, *aTmpPtr; + PRInt32 aStrCt=0, startCt=0,j; + PangoGlyphString *aGlyphData=pango_glyph_string_new(); + + *aStart = *aEnd = 0; + aRun.numRuns=0; + SeparateScript(aString, aLength, &aRun); + + // Get the index of current cluster + aPtr=aRun.head; + for (int i=0; ilength; + + if ((aStrCt+runLen) < aIndex) /* Skip Run */ + aStrCt += runLen; + else { + if (aPtr->isOther) { + *aStart = *aEnd = aIndex; + CLEAN_RUN + return NS_OK; + } + else { + PRInt32 beg,end,numCur; + + startCt=aStrCt; + GetRawCtlData(aPtr->start, runLen, aGlyphData); + + numCur=beg=0; + for (j=1; jnum_glyphs; j++) { + while ((!aGlyphData->glyphs[j].attr.is_cluster_start) && + jnum_glyphs) + j++; + if (j>=aGlyphData->num_glyphs) + end=runLen; + else + end=aGlyphData->log_clusters[j]; + + numCur += end-beg; + if (numCur+startCt >= aIndex) + break; + else + beg=end; + } + + *aEnd = startCt+numCur; + if (beg == 0) + *aStart = beg; + else { + if ((end-beg) == 1) /* n=n Condition */ + *aStart = *aEnd; + else + *aStart = startCt+beg+1; /* Maintain Mozilla Convention */ + } + CLEAN_RUN + return NS_OK; + } + } + aPtr=aPtr->next; + } + CLEAN_RUN + /* UNUSED */ } diff --git a/mozilla/extensions/ctl/src/nsULE.h b/mozilla/extensions/ctl/src/nsULE.h index 3b525466ebd..1a20f2d8b33 100755 --- a/mozilla/extensions/ctl/src/nsULE.h +++ b/mozilla/extensions/ctl/src/nsULE.h @@ -32,6 +32,22 @@ #include "nsCtlCIID.h" #include "nsILE.h" +#include "pango-types.h" +#include "pango-glyph.h" + +struct textRun { + PRInt32 length; /* Length of a chunk */ + PRBool isOther; /* Outside the range */ + const PRUnichar *start; /* Address of start offset */ + struct textRun *next; +}; + +struct textRunList { + struct textRun *head; + struct textRun *cur; + PRInt32 numRuns; +}; + /* Class nsULE : Declaration */ class nsULE : public nsILE { public: @@ -48,22 +64,29 @@ public: // A> API used to generate Presentation Forms based on supported fonts // B> API used by common text operations such as cursor positioning // and selection - NS_IMETHOD GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, - PangoAnalysis *aAnalysis, - PangoGlyphString *aGlyphs); NS_IMETHOD GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, + PRUint32 aLength, const char *fontCharset, char *aGlyphs, PRSize *aOutLength); - NS_IMETHOD GetPresentationForm(const PRUnichar *aString, - PRUint32 aLength, - const char *fontCharset, - PRUint32 *aGlyphs, - PRSize *aOutLength); + NS_IMETHOD PrevCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *prevOffset); + + NS_IMETHOD NextCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *nextOffset); + + NS_IMETHOD GetRangeOfCluster(const PRUnichar *aString, + PRUint32 aLength, + const PRInt32 aIndex, + PRInt32 *aStart, + PRInt32 *aEnd); + private: // Housekeeping Members @@ -71,5 +94,9 @@ public: void CleanUp(void); PangoEngineShape* GetShaper(const PRUnichar *, PRUint32, const char *); + + PRInt32 GetRawCtlData(const PRUnichar*, PRUint32, PangoGlyphString*); + + PRInt32 SeparateScript(const PRUnichar*, PRInt32, textRunList*); }; #endif /* nsULE_H */ diff --git a/mozilla/extensions/ctl/src/nsUnicodeToTIS620.cpp b/mozilla/extensions/ctl/src/nsUnicodeToTIS620.cpp index f3914069cf0..fbdc43ac139 100644 --- a/mozilla/extensions/ctl/src/nsUnicodeToTIS620.cpp +++ b/mozilla/extensions/ctl/src/nsUnicodeToTIS620.cpp @@ -22,19 +22,24 @@ * * Contributor(s): */ -#include -#include /* isspace */ #include "nsCOMPtr.h" +#include "nsIServiceManager.h" +#include "nsICharsetConverterManager.h" +#include "nsICharsetConverterManager2.h" +#include "nsILanguageAtomService.h" #include "nsCtlCIID.h" #include "nsILE.h" +#include "nsULE.h" #include "nsUnicodeToTIS620.h" +static NS_DEFINE_CID(kCharSetManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + // XPCOM stuff NS_IMPL_ADDREF(nsUnicodeToTIS620); NS_IMPL_RELEASE(nsUnicodeToTIS620); -int +PRInt32 nsUnicodeToTIS620::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList) { int ct = 0, start = 0; @@ -78,14 +83,13 @@ nsUnicodeToTIS620::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunLis tmpChunk->length = ct - start; } - return (int)aRunList->numRuns; + return (PRInt32)aRunList->numRuns; } nsresult nsUnicodeToTIS620::QueryInterface(REFNSIID aIID, void** aInstancePtr) { - if (NULL == aInstancePtr) { + if (NULL == aInstancePtr) return NS_ERROR_NULL_POINTER; - } *aInstancePtr = NULL; @@ -123,11 +127,28 @@ NS_IMETHODIMP nsUnicodeToTIS620::SetOutputErrorBehavior(PRInt32 aBehavior, nsUnicodeToTIS620::nsUnicodeToTIS620() { + static NS_DEFINE_CID(kLECID, NS_ULE_CID); + nsresult rv; + NS_INIT_REFCNT(); + + mCtlObj = do_CreateInstance(kLECID, &rv); + if (NS_FAILED(rv)) { +#ifdef DEBUG_prabhat + // No other error handling needed here since we + // handle absence of mCtlObj in Convert + printf("ERROR: Cannot create instance of component " NS_ULE_PROGID " [%x].\n", + rv); +#endif + NS_WARNING("Thai Text Layout Will Not Be Supported\n"); + mCtlObj = nsnull; + } } nsUnicodeToTIS620::~nsUnicodeToTIS620() { + // Maybe convert nsILE to a service + // No NS_IF_RELEASE(mCtlObj) of nsCOMPtr; } /* @@ -135,44 +156,74 @@ nsUnicodeToTIS620::~nsUnicodeToTIS620() * Note: ConversionBufferFullException is not handled * since this class is only used for character display. */ -NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar * input, - PRInt32 * aSrcLength, - char * output, PRInt32 * aDestLength) +NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar* input, + PRInt32* aSrcLength, + char* output, + PRInt32* aDestLength) { - int i = 0; - nsCOMPtr mCtlObj; - static NS_DEFINE_CID(kLECID, NS_ULE_CID); - nsresult rv; - textRunList txtRuns; - textRun *aPtr, *aTmpPtr; + textRunList txtRuns; + textRun *aPtr, *aTmpPtr; + +#ifdef DEBUG_prabhath_no_shaper + printf("Debug/Test Case of No thai pango shaper Object\n"); + // Comment out mCtlObj == nsnull for test purposes +#endif + + if (mCtlObj == nsnull) { + nsICharsetConverterManager2* gCharSetManager = nsnull; + nsIUnicodeEncoder* gDefaultTISConverter = nsnull; + nsresult res; + nsServiceManager::GetService(kCharSetManagerCID, + NS_GET_IID(nsICharsetConverterManager2), (nsISupports**) &gCharSetManager); - // No question of starting the conversion from an offset - charOff = byteOff = 0; +#ifdef DEBUG_prabhath + printf("ERROR: No CTL IMPLEMENTATION - Default Thai Conversion"); + // CP874 is the default converter for thai ; + // In case mCtlObj is absent (no CTL support), use it to convert. +#endif - mCtlObj = do_CreateInstance(kLECID, &rv); - if (NS_FAILED(rv)) { - printf("ERROR: Cannot create instance of component " NS_ULE_PROGID " [%x].\n", - rv); - printf("Thai Text Layout Will Not Be Supported\n"); + if (!gCharSetManager) + return NS_ERROR_FAILURE; + + nsCOMPtr charset = getter_AddRefs(NS_NewAtom("TIS-620")); + if (charset) + res = gCharSetManager->GetUnicodeEncoder(charset, &gDefaultTISConverter); + else { + NS_IF_RELEASE(gCharSetManager); + return NS_ERROR_FAILURE; + } + + if (!gDefaultTISConverter) { + NS_WARNING("cannot get default converter for tis-620"); + NS_IF_RELEASE(gCharSetManager); + return NS_ERROR_FAILURE; + } + + gDefaultTISConverter->Convert(input, aSrcLength, output, aDestLength); + NS_IF_RELEASE(gCharSetManager); + NS_IF_RELEASE(gDefaultTISConverter); + return NS_OK; } - txtRuns.numRuns = 0; + // CTLized shaping conversion starts here + // No question of starting the conversion from an offset + mCharOff = mByteOff = 0; + + txtRuns.numRuns = 0; Itemize(input, *aSrcLength, &txtRuns); aPtr = txtRuns.head; - for (i = 0; i < txtRuns.numRuns; i++) { - // char *tmpDestBuf = output + byteOff; - // PRInt32 tmpDestLen = *aDestLength - byteOff; + for (int i = 0; i < txtRuns.numRuns; i++) { PRInt32 tmpSrcLen = aPtr->length; if (aPtr->isOther) { // PangoThaiShaper does not handle ASCII + thai in same shaper - for (i = 0; i < tmpSrcLen; i++) - output[i + byteOff] = (char)(*(aPtr->start + i)); - byteOff += tmpSrcLen; + for (int j = 0; j < tmpSrcLen; j++) + output[j + mByteOff] = (char)(*(aPtr->start + j)); + mByteOff += tmpSrcLen; } else { - PRSize outLen = *aDestLength; + PRSize outLen = *aDestLength - mByteOff; // Charset tis620-0, tis620.2533-1, tis620.2529-1 & iso8859-11 // are equivalent and have the same presentation forms @@ -180,24 +231,21 @@ NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar * input, // in Windows-Stye as it is the current defacto-standard for the // presentation of thai content mCtlObj->GetPresentationForm(aPtr->start, tmpSrcLen, "tis620-2", - output, &outLen); - byteOff += outLen; + &output[mByteOff], &outLen); + mByteOff += outLen; } aPtr = aPtr->next; } - // Check for free nsILE or convert nsILE to a service - // NS_IF_RELEASE(mCtlObj); - // Cleanup Run Info; aPtr = txtRuns.head; - for (i = 0; i < txtRuns.numRuns; i++) { + for (int i = 0; i < txtRuns.numRuns; i++) { aTmpPtr = aPtr; aPtr = aPtr->next; delete aTmpPtr; } - *aDestLength = byteOff; + *aDestLength = mByteOff; return NS_OK; } @@ -205,14 +253,14 @@ NS_IMETHODIMP nsUnicodeToTIS620::Finish(char * output, PRInt32 * aDestLength) { // Finish does'nt have to do much as Convert already flushes // to output buffer - byteOff = charOff = 0; + mByteOff = mCharOff = 0; return NS_OK; } //================================================================ NS_IMETHODIMP nsUnicodeToTIS620::Reset() { - byteOff = charOff = 0; + mByteOff = mCharOff = 0; return NS_OK; } diff --git a/mozilla/extensions/ctl/src/nsUnicodeToTIS620.h b/mozilla/extensions/ctl/src/nsUnicodeToTIS620.h index c63e6c15ab3..03490d96f8d 100644 --- a/mozilla/extensions/ctl/src/nsUnicodeToTIS620.h +++ b/mozilla/extensions/ctl/src/nsUnicodeToTIS620.h @@ -35,18 +35,9 @@ #include "nsIUnicodeEncoder.h" #include "nsICharRepresentable.h" -struct textRun { - PRInt32 length; /* Length of a chunk */ - PRBool isOther; /* Outside the range */ - const PRUnichar *start; /* Address of start offset */ - struct textRun *next; -}; +#include "nsILE.h" -typedef struct { - struct textRun *head; - struct textRun *cur; - PRInt32 numRuns; -} textRunList; +struct textRunList; //---------------------------------------------------------------------- // Class nsUnicodeToTIS620 [declaration] @@ -80,12 +71,14 @@ public: NS_IMETHOD FillInfo(PRUint32* aInfo); private: - PRUint8 state; - PRInt32 byteOff; - PRInt32 charOff; + PRUint8 mState; + PRInt32 mByteOff; + PRInt32 mCharOff; + + nsCOMPtr mCtlObj; // beg and end denote ranges and may need to be expanded in the future to // handle discontinous ranges - int Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList); + PRInt32 Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList); }; #endif /* nsUnicodeToTIS620_h___ */ diff --git a/mozilla/extensions/ctl/src/pangoLite/Makefile.in b/mozilla/extensions/ctl/src/pangoLite/Makefile.in index b6abfb6b201..17a328dd299 100755 --- a/mozilla/extensions/ctl/src/pangoLite/Makefile.in +++ b/mozilla/extensions/ctl/src/pangoLite/Makefile.in @@ -68,4 +68,6 @@ CXXFLAGS += $(GLIB_CFLAGS) CFLAGS += $(GLIB_CFLAGS) EXTRA_DSO_LDOPTS += $(GLIB_LIBS) -lgmodule -#DEFINES += -DSYSCONFDIR=\"$(sysconfdir)\" +# Install pango.modules file for Shaping Modules. +install:: + $(INSTALL) $(srcdir)/pango.modules $(DIST)/bin diff --git a/mozilla/extensions/ctl/src/pangoLite/pango-engine.h b/mozilla/extensions/ctl/src/pangoLite/pango-engine.h index e908936ac84..168b265b2df 100644 --- a/mozilla/extensions/ctl/src/pangoLite/pango-engine.h +++ b/mozilla/extensions/ctl/src/pangoLite/pango-engine.h @@ -80,7 +80,7 @@ struct _PangoEngineShape { PangoEngine engine; void (*script_shape) (const char *fontCharset, - const char *text, + const gunichar2 *text, int length, PangoAnalysis *analysis, PangoGlyphString *glyphs); diff --git a/mozilla/extensions/ctl/src/pangoLite/pango-glyph.h b/mozilla/extensions/ctl/src/pangoLite/pango-glyph.h index a1fa552b2d2..c2b8a17cd9f 100644 --- a/mozilla/extensions/ctl/src/pangoLite/pango-glyph.h +++ b/mozilla/extensions/ctl/src/pangoLite/pango-glyph.h @@ -102,7 +102,7 @@ void pango_glyph_string_x_to_index(PangoGlyphString *glyphs, int *trailing); /* Turn a string of characters into a string of glyphs */ -void pango_shape(const char *text, +void pango_shape(const gunichar2 *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs); diff --git a/mozilla/extensions/ctl/src/pangoLite/pango.modules b/mozilla/extensions/ctl/src/pangoLite/pango.modules new file mode 100755 index 00000000000..171cdd48ee4 --- /dev/null +++ b/mozilla/extensions/ctl/src/pangoLite/pango.modules @@ -0,0 +1,5 @@ + +# Pango Modules file +# Automatically generated file, do not edit +# +./libmozpango-thaix.so ThaiScriptEngineX PangoEngineShape PangoRenderX 3585-3675:* diff --git a/mozilla/extensions/ctl/src/pangoLite/shape.c b/mozilla/extensions/ctl/src/pangoLite/shape.c index d83106e2afc..1f98ba5e94e 100644 --- a/mozilla/extensions/ctl/src/pangoLite/shape.c +++ b/mozilla/extensions/ctl/src/pangoLite/shape.c @@ -47,7 +47,7 @@ * convert the characters into glyphs. You may also pass * in only a substring of the item from pango_itemize(). */ -void pango_shape(const gchar *text, +void pango_shape(const gunichar2 *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs) diff --git a/mozilla/extensions/ctl/src/thaiShaper/thai-x.c b/mozilla/extensions/ctl/src/thaiShaper/thai-x.c index a33c4e0949a..fe6dd89ec83 100644 --- a/mozilla/extensions/ctl/src/thaiShaper/thai-x.c +++ b/mozilla/extensions/ctl/src/thaiShaper/thai-x.c @@ -48,7 +48,7 @@ #define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) #define ucs2tis(wc) (unsigned int)((unsigned int)(wc) - 0x0E00 + 0xA0) -#define tis2uni(c) ((gunichar)(c) - 0xA0 + 0x0E00) +#define tis2uni(c) ((gunichar2)(c) - 0xA0 + 0x0E00) #define MAX_CLUSTER_CHRS 256 #define MAX_GLYPHS 256 @@ -418,7 +418,7 @@ add_glyph(ThaiFontInfo *font_info, static gint get_adjusted_glyphs_list(ThaiFontInfo *font_info, - gunichar *cluster, + gunichar2 *cluster, gint num_chrs, PangoGlyph *glyph_lists, const ThaiShapeTable *shaping_table) @@ -582,7 +582,7 @@ get_adjusted_glyphs_list(ThaiFontInfo *font_info, static gint get_glyphs_list(ThaiFontInfo *font_info, - gunichar *cluster, + gunichar2 *cluster, gint num_chrs, PangoGlyph *glyph_lists) { @@ -647,7 +647,7 @@ static void add_cluster (ThaiFontInfo *font_info, PangoGlyphString *glyphs, gint cluster_start, - gunichar *cluster, + gunichar2 *cluster, gint num_chrs) { @@ -661,7 +661,7 @@ add_cluster (ThaiFontInfo *font_info, } static gboolean -is_wtt_composible (gunichar cur_wc, gunichar nxt_wc) +is_wtt_composible (gunichar2 cur_wc, gunichar2 nxt_wc) { switch (TAC_compose_and_input_check_type_table[char_class(ucs2tis(cur_wc))] [char_class(ucs2tis(nxt_wc))]) { @@ -679,21 +679,21 @@ is_wtt_composible (gunichar cur_wc, gunichar nxt_wc) return FALSE; } -static const char * -get_next_cluster(const char *text, - gint length, - gunichar *cluster, - gint *num_chrs) +static const gunichar2 * +get_next_cluster(const gunichar2 *text, + gint length, + gunichar2 *cluster, + gint *num_chrs) { - const char *p; - gint n_chars = 0; + const gunichar2 *p; + gint n_chars = 0; p = text; while (p < text + length && n_chars < 3) { - gunichar current = g_utf8_get_char (p); + gunichar2 current = *p; if (n_chars == 0 || - is_wtt_composible ((gunichar)(cluster[n_chars - 1]), current) || + is_wtt_composible ((gunichar2)(cluster[n_chars - 1]), current) || (n_chars == 1 && is_char_type (cluster[0], Cons) && is_char_type (current, SaraAm)) || @@ -702,7 +702,7 @@ get_next_cluster(const char *text, is_char_type (cluster[1], Tone) && is_char_type (current, SaraAm))) { cluster[n_chars++] = current; - p = g_utf8_next_char(p); + p++; } else break; @@ -714,16 +714,16 @@ get_next_cluster(const char *text, static void thai_engine_shape(const char *fontCharset, - const char *text, + const gunichar2 *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs) { - ThaiFontInfo *font_info; - const char *p; - const char *log_cluster; - gunichar cluster[MAX_CLUSTER_CHRS]; - gint num_chrs; + ThaiFontInfo *font_info; + const gunichar2 *p; + const gunichar2 *log_cluster; + gunichar2 cluster[MAX_CLUSTER_CHRS]; + gint num_chrs; pango_glyph_string_set_size(glyphs, 0); @@ -745,7 +745,7 @@ thai_engine_get_coverage(const char *fontCharset, ThaiFontInfo *font_info = get_font_info(fontCharset); if (font_info->type != THAI_FONT_NONE) { - gunichar wc; + gunichar2 wc; for (wc = 0xe01; wc <= 0xe3a; wc++) pango_coverage_set(result, wc, PANGO_COVERAGE_EXACT);