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
This commit is contained in:
katakai%japan.sun.com 2001-09-18 10:14:38 +00:00
parent d9fd93b244
commit 1496fa7bc3
12 changed files with 497 additions and 178 deletions

View File

@ -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

View File

@ -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,

View File

@ -23,9 +23,6 @@
* Contributor(s):
*/
#include <stdio.h>
#include <ctype.h> /* 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; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_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; i<aRun.numRuns; i++) {
PRInt32 runLen=aPtr->length;
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; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_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; i<aRun.numRuns; i++) {
PRInt32 runLen=aPtr->length;
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; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_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 */
}

View File

@ -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 */

View File

@ -22,19 +22,24 @@
*
* Contributor(s):
*/
#include <stdio.h>
#include <ctype.h> /* 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<nsILE> 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<nsIAtom> 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;
}

View File

@ -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<nsILE> 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___ */

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -0,0 +1,5 @@
# Pango Modules file
# Automatically generated file, do not edit
#
./libmozpango-thaix.so ThaiScriptEngineX PangoEngineShape PangoRenderX 3585-3675:*

View File

@ -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)

View File

@ -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);