bug 203406 : performance enhancement patch for CTL (patch by prabhat), bug 204286 (patch by me) : enable Devanagari rendering in Xft build with Hindi shaper. r=prabhat, sr(rs)=rbs

This commit is contained in:
jshin%mailaps.org 2003-12-23 10:17:50 +00:00
parent 45f50dbc47
commit 4672446205
12 changed files with 383 additions and 838 deletions

View File

@ -39,8 +39,12 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILE_IID)
NS_IMETHOD NeedsCTLFix(const PRUnichar*, const PRInt32,
const PRInt32, PRBool *) = 0;
NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32,
const char*, char*, PRSize*) = 0;
const char*, char*, PRSize*,
PRBool = PR_FALSE) = 0;
NS_IMETHOD PrevCluster(const PRUnichar*, PRUint32,
const PRInt32, PRInt32*) = 0;

View File

@ -1,4 +1,5 @@
/* Pango
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pangolite
* dvng-x.c:
*
* The contents of this file are subject to the Mozilla Public
@ -27,12 +28,13 @@
#include "pango-coverage.h"
#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
#define GLYPH_COMBINING 256
/*************************************************************************
* CHARACTER TYPE CONSTANTS - What they represent *
* ----------------------------------------------- *
* ---------------------------------------------- *
* *
* _NP : Vowel-Modifier Visarg(U+0903) (Displayed to the right). *
* _UP : Vowel-Modifer Chandrabindu(U+0901) and Anuswar (U+0902). *
@ -286,21 +288,21 @@ static const gint DvngChrTypeTbl[128] = {
* Devanagari character composible table
*/
static const gint DvngComposeTbl[14][14] = {
/* ND, UP, NP, IV, CN, CK, RC, NM, RM, IM, HL, NK, VD, HD, */
/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ND */
/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* UP */
/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NP */
/* 3 */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IV */
/* 4 */ 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, /* CN */
/* 5 */ 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, /* CK */
/* 6 */ 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, /* RC */
/* 7 */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NM */
/* 8 */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* RM */
/* 9 */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IM */
/* 10 */ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* HL */
/* 11 */ 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, /* NK */
/* 12 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* VD */
/* 13 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* HD */
/* ND, UP, NP, IV, CN, CK, RC, NM, RM, IM, HL, NK, VD, HD, */
/* 0 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* ND */
/* 1 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* UP */
/* 2 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* NP */
/* 3 */ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* IV */
/* 4 */ { 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,}, /* CN */
/* 5 */ { 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,}, /* CK */
/* 6 */ { 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,}, /* RC */
/* 7 */ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* NM */
/* 8 */ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* RM */
/* 9 */ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* IM */
/* 10 */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,}, /* HL */
/* 11 */ { 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,}, /* NK */
/* 12 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* VD */
/* 13 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, /* HD */
};
StateType DvngStateTbl[MAX_STATE][MAX_DEVA_TYPE] = {
@ -308,68 +310,68 @@ StateType DvngStateTbl[MAX_STATE][MAX_DEVA_TYPE] = {
/* ND, UP, NP, IV, CN, CK, RC, NM, RM,
IM, HL, NK, VD, HD */
/* State 0 */
St11, St1, St1, St2, St4, St4, St12, St1, St1,
St1, St1, St1, St1, St11,
{ St11, St1, St1, St2, St4, St4, St12, St1, St1,
St1, St1, St1, St1, St11, },
/* State 1 */
St1, St1, St1, St1, St1, St1, St1, St1, St1,
St1, St1, St1, St1, St1,
{ St1, St1, St1, St1, St1, St1, St1, St1, St1,
St1, St1, St1, St1, St1, },
/* State 2 */
St2, St3, St3, St2, St2, St2, St2, St2, St2,
St2, St2, St2, St2, St2,
{ St2, St3, St3, St2, St2, St2, St2, St2, St2,
St2, St2, St2, St2, St2, },
/* State 3 */
St3, St3, St3, St3, St3, St3, St3, St3, St3,
St3, St3, St3, St3, St3,
{ St3, St3, St3, St3, St3, St3, St3, St3, St3,
St3, St3, St3, St3, St3, },
/* State 4 */
St4, St8, St8, St4, St4, St4, St4, St6, St6,
St9, St5, St4, St4, St4,
{ St4, St8, St8, St4, St4, St4, St4, St6, St6,
St9, St5, St4, St4, St4, },
/* State 5 */
St5, St5, St5, St5, St4, St4, St4, St5, St5,
St5, St5, St5, St5, St5,
{ St5, St5, St5, St5, St4, St4, St4, St5, St5,
St5, St5, St5, St5, St5, },
/* State 6 */
St6, St7, St7, St6, St6, St6, St6, St6, St6,
St6, St6, St6, St6, St6,
{ St6, St7, St7, St6, St6, St6, St6, St6, St6,
St6, St6, St6, St6, St6, },
/* State 7 */
St7, St7, St7, St7, St7, St7, St7, St7, St7,
St7, St7, St7, St7, St7,
{ St7, St7, St7, St7, St7, St7, St7, St7, St7,
St7, St7, St7, St7, St7, },
/* State 8 */
St8, St8, St8, St8, St8, St8, St8, St8, St8,
St8, St8, St8, St8, St8,
{ St8, St8, St8, St8, St8, St8, St8, St8, St8,
St8, St8, St8, St8, St8, },
/* State 9 */
St9, St10, St10, St9, St9, St9, St9, St9, St9,
St9, St9, St9, St9, St9,
{ St9, St10, St10, St9, St9, St9, St9, St9, St9,
St9, St9, St9, St9, St9, },
/* State 10 */
St10, St10, St10, St10, St10, St10, St10, St10, St10,
St10, St10, St10, St10, St10,
{ St10, St10, St10, St10, St10, St10, St10, St10, St10,
St10, St10, St10, St10, St10, },
/* State 11 */
St11, St11, St11, St11, St11, St11, St11, St11, St11,
St11, St11, St11, St11, St11,
{ St11, St11, St11, St11, St11, St11, St11, St11, St11,
St11, St11, St11, St11, St11, },
/* State 12 */
St12, St8, St8, St12, St12, St12, St12, St6, St6,
St9, St13, St12, St12, St12,
{ St12, St8, St8, St12, St12, St12, St12, St6, St6,
St9, St13, St12, St12, St12, },
/* State 13 */
St13, St13, St13, St13, St14, St14, St14, St13, St13,
St13, St13, St13, St13, St13,
{ St13, St13, St13, St13, St14, St14, St14, St13, St13,
St13, St13, St13, St13, St13, },
/* State 14 */
St14, St18, St18, St14, St14, St14, St14, St16, St16,
St19, St15, St14, St14, St14,
{ St14, St18, St18, St14, St14, St14, St14, St16, St16,
St19, St15, St14, St14, St14, },
/* State 15 */
St15, St15, St15, St15, St14, St14, St14, St15, St15,
St15, St15, St15, St15, St15,
{ St15, St15, St15, St15, St14, St14, St14, St15, St15,
St15, St15, St15, St15, St15, },
/* State 16 */
St16, St17, St17, St16, St16, St16, St16, St16, St16,
St16, St16, St16, St16, St16,
{ St16, St17, St17, St16, St16, St16, St16, St16, St16,
St16, St16, St16, St16, St16, },
/* State 17 */
St17, St17, St17, St17, St17, St17, St17, St17, St17,
St17, St17, St17, St17, St17,
{ St17, St17, St17, St17, St17, St17, St17, St17, St17,
St17, St17, St17, St17, St17, },
/* State 18 */
St18, St18, St18, St18, St18, St18, St18, St18, St18,
St18, St18, St18, St18, St18,
{ St18, St18, St18, St18, St18, St18, St18, St18, St18,
St18, St18, St18, St18, St18, },
/* State 19 */
St19, St20, St20, St19, St19, St19, St19, St19, St19,
St19, St19, St19, St19, St19,
{ St19, St20, St20, St19, St19, St19, St19, St19, St19,
St19, St19, St19, St19, St19, },
/* State 20 */
St20, St20, St20, St20, St20, St20, St20, St20, St20,
St20, St20, St20, St20, St20,
{ St20, St20, St20, St20, St20, St20, St20, St20, St20,
St20, St20, St20, St20, St20, },
};
int DvngRuleTbl[128] = {
@ -943,7 +945,7 @@ get_font_info(const char *fontCharset)
};
DvngFontInfo *font_info = g_new(DvngFontInfo, 1);
gint subfontId, i;
guint i;
font_info->type = DVNG_FONT_NONE;
for (i = 0; i < G_N_ELEMENTS(charsets); i++) {
@ -959,15 +961,18 @@ get_font_info(const char *fontCharset)
static void
add_glyph(PangoliteGlyphString *glyphs,
gint clusterStart,
PangoliteGlyph glyph,
gboolean combining)
gint clusterStart,
PangoliteGlyph glyph,
gint combining)
{
gint index = glyphs->num_glyphs;
if ((clusterStart == 0) && (index != 0))
clusterStart++;
pangolite_glyph_string_set_size (glyphs, index + 1);
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = combining ? 0 : 1;
glyphs->glyphs[index].is_cluster_start = combining;
glyphs->log_clusters[index] = clusterStart;
}
@ -1070,7 +1075,9 @@ get_adjusted_glyphs_list(DvngFontInfo *fontInfo,
if (IsDvngCharCls(cluster[nChars - 1], _UP)) {
if (IsDvngCharCls(cluster[nChars - 2], _RM))
GetBaseConsGlyphs(cluster, nChars - 2,gLst, &nGlyphs);
GetBaseConsGlyphs(cluster, nChars - 2, gLst, &nGlyphs);
else
GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs);
if (IsDvngCharCls(cluster[nChars - 2], _RM)) {
@ -1096,25 +1103,26 @@ get_adjusted_glyphs_list(DvngFontInfo *fontInfo,
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82D);
}
}
else if (IsDvngCharCls(cluster[nChars - 2], _O_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF824);
}
else if (IsDvngCharCls(cluster[nChars - 2], _O_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF824);
}
else if (IsDvngCharCls(cluster[nChars - 2], _OW1_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF827);
}
else if (IsDvngCharCls(cluster[nChars - 2], _OW1_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF827);
}
else if (IsDvngCharCls(cluster[nChars - 2], _OW2_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82A);
else if (IsDvngCharCls(cluster[nChars - 2], _OW2_M)) {
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E);
gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82A);
}
}
}
else
else {
GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs);
}
break;
case St8:
@ -1330,11 +1338,16 @@ add_cluster(DvngFontInfo *fontInfo,
StateType *clustState)
{
PangoliteGlyph glyphsList[MAX_GLYPHS];
gint i, numGlyphs;
gint i, numGlyphs, ClusterStart=0;
numGlyphs = get_glyphs_list(fontInfo, cluster, numChars, glyphsList, clustState);
for (i = 0; i < numGlyphs; i++)
add_glyph(glyphs, clusterBeg, glyphsList[i], i == 0 ? FALSE : TRUE);
for (i = 0; i < numGlyphs; i++) {
ClusterStart = (gint)GLYPH_COMBINING;
if (i == 0)
ClusterStart = numChars;
add_glyph(glyphs, clusterBeg, glyphsList[i], ClusterStart);
}
}
static const gunichar2 *
@ -1380,7 +1393,6 @@ dvng_engine_shape(const char *fontCharset,
gint num_chrs;
StateType aSt = St0;
pangolite_glyph_string_set_size(glyphs, 0);
fontInfo = get_font_info(fontCharset);
p = text;

View File

@ -22,6 +22,7 @@
*
* Contributor(s):
* Prabhat Hegde (prabhat.hegde@sun.com)
* Jungshik Shin (jshin@mailmaps.org)
*/
#include "nsULE.h"
@ -32,437 +33,251 @@
#include "pango-modules.h"
#include "pango-utils.h"
#define GLYPH_COMBINING 256
/*
* To Do: (Last Updated by prabhat - 08/24/02)
* A> Extend shapers to support ASCII + Script
* B> Eliminate Separate Script
* C> Look at improving the speed of cursor handling logic
*
* To Do:(prabhat-04/01/03) Cache GlyphString
*/
#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
*/
nsULE::nsULE() {
}
nsULE::~nsULE() {
// No data to cleanup.
}
NS_IMPL_ISUPPORTS1(nsULE, nsILE)
/* Caller needs to ensure that GetEngine is called with valid state */
PangoliteEngineShape*
nsULE::GetShaper(const PRUnichar *inBuf,
PRUint32 aLength,
const char *lang)
{
PangoliteEngineShape *aEngine = NULL;
PangoliteMap *aMap = NULL;
guint engine_type_id = 0, render_type_id = 0;
PRUnichar wc = inBuf[0];
if ((inBuf == (PRUnichar*)NULL) || (aLength <= 0)) {
aEngine = (PangoliteEngineShape*)NULL;
}
else {
if (engine_type_id == 0) {
engine_type_id = g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string(PANGO_RENDER_TYPE_X);
}
// Do not care about lang for now
aMap = pangolite_find_map("en_US", engine_type_id, render_type_id);
aEngine = (PangoliteEngineShape*)pangolite_map_get_engine(aMap, (PRUint32)wc);
}
return aEngine;
}
PRInt32
nsULE::ScriptsByRun(const PRUnichar *aSrcBuf,
PRInt32 aSrcLen,
textRunList *aRunList)
{
int ct = 0, start = 0;
PRBool sameCtlRun = PR_FALSE;
struct textRun *tmpChunk;
PangoliteEngineShape *curEngine = NULL, *prevEngine = NULL;
PangoliteMap *aMap = NULL;
guint engine_type_id = 0, render_type_id = 0;
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 = pangolite_find_map("en_US", engine_type_id, render_type_id);
for (ct = 0; ct < aSrcLen;) {
tmpChunk = new textRun;
if (!tmpChunk)
break;
if (aRunList->numRuns == 0)
aRunList->head = tmpChunk;
else
aRunList->cur->next = tmpChunk;
aRunList->cur = tmpChunk;
aRunList->numRuns++;
tmpChunk->start = &aSrcBuf[ct];
start = ct;
curEngine = (PangoliteEngineShape*)
pangolite_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
sameCtlRun = (curEngine != NULL);
prevEngine = curEngine;
if (sameCtlRun) {
while (sameCtlRun && ct < aSrcLen) {
curEngine = (PangoliteEngineShape*)
pangolite_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
sameCtlRun = ((curEngine != NULL) && (curEngine == prevEngine));
if (sameCtlRun)
ct++;
}
tmpChunk->isOther = PR_FALSE;
}
else {
while (!sameCtlRun && ct < aSrcLen) {
curEngine = (PangoliteEngineShape*)
pangolite_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
sameCtlRun = (curEngine != NULL);
if (!sameCtlRun)
ct++;
}
tmpChunk->isOther = PR_TRUE;
}
tmpChunk->length = ct - start;
}
return (PRInt32)aRunList->numRuns;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsULE, nsILE)
// Default font encoding by code-range
// At the moment pangoliteLite only supports 2 shapers/scripts
// At the moment pangoLite only supports 2 shapers/scripts
const char*
nsULE::GetDefaultFont(const PRUnichar aString)
{
if ((aString >= 0x0e01) && (aString <= 0x0e5b))
return "tis620-2";
else if ((aString >= 0x0901) && (aString <= 0x0970))
if ((aString >= 0x0901) && (aString <= 0x0970))
return "sun.unicode.india-0";
else
return "iso8859-1";
return "iso8859-1";
}
// Analysis needs to have valid direction
PRInt32
nsULE::GetCtlData(const PRUnichar *aString,
PRUint32 aLength,
PangoliteGlyphString *aGlyphs,
const char *fontCharset)
nsULE::GetGlyphInfo(const PRUnichar *aSrcBuf,
PRInt32 aSrcLen,
PangoliteGlyphString *aGlyphData,
const char *aFontCharset)
{
PangoliteEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL);
PangoliteAnalysis aAnalysis;
int ct=0, start=0, i, index, startgid, lastCluster=0;
PRBool sameCtlRun=PR_FALSE;
PangoliteEngineShape *curShaper=NULL, *prevShaper=NULL;
PangoliteMap *pngMap=NULL;
PangoliteAnalysis pngAnalysis;
guint enginetypeId=0, rendertypeId=0;
aAnalysis.shape_engine = aShaper;
aAnalysis.aDir = PANGO_DIRECTION_LTR;
pngAnalysis.aDir = PANGO_DIRECTION_LTR;
// Maybe find a better way to handle font encodings
if (fontCharset == NULL)
aAnalysis.fontCharset = strdup(GetDefaultFont(aString[0]));
if (aFontCharset == NULL)
pngAnalysis.fontCharset = strdup(GetDefaultFont(aSrcBuf[0]));
else
aAnalysis.fontCharset = strdup(fontCharset);
pngAnalysis.fontCharset = strdup(aFontCharset);
if (aShaper != NULL) {
aShaper->script_shape(aAnalysis.fontCharset, aString, aLength,
&aAnalysis, aGlyphs);
nsMemory::Free(aAnalysis.fontCharset);
enginetypeId = g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE);
rendertypeId = g_quark_from_static_string(PANGO_RENDER_TYPE_X);
pngMap = pangolite_find_map("en_US", enginetypeId, rendertypeId);
for (ct=0; ct < aSrcLen;) {
start = ct;
curShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aSrcBuf[ct++]);
sameCtlRun = (curShaper != NULL);
prevShaper = curShaper;
if (sameCtlRun) {
while (sameCtlRun && ct < aSrcLen) {
curShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aSrcBuf[ct]);
sameCtlRun = ((curShaper != NULL) && (curShaper == prevShaper));
if (sameCtlRun)
ct++;
}
startgid = aGlyphData->num_glyphs;
pngAnalysis.shape_engine = curShaper;
prevShaper->script_shape(pngAnalysis.fontCharset,
&aSrcBuf[start], (ct-start),
&pngAnalysis, aGlyphData);
if (lastCluster > 0) {
for (i=startgid; i < aGlyphData->num_glyphs; i++)
aGlyphData->log_clusters[i] += lastCluster;
}
}
else {
while (!sameCtlRun && ct < aSrcLen) {
curShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aSrcBuf[ct]);
sameCtlRun = (curShaper != NULL);
if (!sameCtlRun)
ct++;
}
index = aGlyphData->num_glyphs;
for (i=0; i < (ct-start); i++) {
pangolite_glyph_string_set_size(aGlyphData, index+1);
aGlyphData->glyphs[index].glyph = aSrcBuf[start+i];
aGlyphData->glyphs[index].is_cluster_start = (gint)1;
aGlyphData->log_clusters[index] = i+lastCluster;
index++;
}
}
lastCluster = aGlyphData->log_clusters[aGlyphData->num_glyphs-1];
}
else {
/* No Shaper - Copy Input to output */
return 0;
}
return aGlyphs->num_glyphs;
nsMemory::Free(pngAnalysis.fontCharset);
return aGlyphData->num_glyphs;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsULE::NeedsCTLFix(const PRUnichar *aString,
const PRInt32 aBeg,
const PRInt32 aEnd,
PRBool *aCTLNeeded)
{
PangoliteEngineShape *BegShaper=NULL, *EndShaper=NULL;
PangoliteMap *pngMap=NULL;
guint enginetypeId=0, rendertypeId=0;
enginetypeId = g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE);
rendertypeId = g_quark_from_static_string(PANGO_RENDER_TYPE_X);
pngMap = pangolite_find_map("en_US", enginetypeId, rendertypeId);
*aCTLNeeded = PR_FALSE;
if (aBeg >= 0)
BegShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aString[aBeg]);
if (!BegShaper) {
if ((aEnd < 0) && ((aBeg+aEnd) >= 0)) {
EndShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aString[aBeg+aEnd]);
}
else {
EndShaper = (PangoliteEngineShape*)
pangolite_map_get_engine(pngMap, (PRUint32)aString[aEnd]);
}
}
if (BegShaper || EndShaper)
*aCTLNeeded = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsULE::GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
const char *aFontCharset,
char *aGlyphs,
PRSize *aOutLength)
PRSize *aOutLength,
PRBool aIsWide)
{
PangoliteGlyphString *tmpGlyphs = pangolite_glyph_string_new();
PangoliteGlyphString *tmpGlyphs=pangolite_glyph_string_new();
GetGlyphInfo(aString, aLength, tmpGlyphs, aFontCharset);
GetCtlData(aString, aLength, tmpGlyphs, fontCharset);
if (tmpGlyphs->num_glyphs > 0) {
guint i = 0, glyphCt = 0;
for (i = 0; i < tmpGlyphs->num_glyphs; i++, glyphCt++) {
if (tmpGlyphs->glyphs[i].glyph > 0xFF) {
aGlyphs[glyphCt]=(unsigned char)((tmpGlyphs->glyphs[i].glyph & 0xFF00) >> 8);
glyphCt++;
}
gint i=0, glyphCt=0;
for (i=0; i < tmpGlyphs->num_glyphs; i++, glyphCt++) {
if (aIsWide)
aGlyphs[glyphCt++]=(unsigned char)
((tmpGlyphs->glyphs[i].glyph & 0xFF00) >> 8);
aGlyphs[glyphCt]=(unsigned char)(tmpGlyphs->glyphs[i].glyph & 0x00FF);
}
*aOutLength = (PRSize)glyphCt;
}
else {
/* No Shaper - Copy Input to output */
}
pangolite_glyph_string_free(tmpGlyphs);
return NS_OK;
}
// 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)
PRInt32 *aNextOffset)
{
textRunList aRun;
textRun *aPtr, *aTmpPtr;
PRInt32 aStrCt=0;
PRBool isBoundary=PR_FALSE;
PangoliteGlyphString *aGlyphData=pangolite_glyph_string_new();
if (aIndex >= aLength-1) {
*nextOffset = aLength; // End
int mStart, mEnd;
if (aIndex < 0) {
*aNextOffset = 0;
return NS_OK;
}
aRun.numRuns = 0;
ScriptsByRun(aString, aLength, &aRun);
aPtr = aRun.head;
for (int i=0; (i < aRun.numRuns); i++) {
PRInt32 runLen=0;
runLen = aPtr->length;
if ((aStrCt+runLen) < aIndex) /* Skip Run and continue */
aStrCt += runLen;
else if ((aStrCt+runLen) == aIndex) {
isBoundary = PR_TRUE;/* Script Boundary - Skip a cell in next iteration */
aStrCt += runLen;
}
else {
if (aPtr->isOther) {
*nextOffset = aIndex+1;
CLEAN_RUN
return NS_OK;
}
else { /* CTL Cell Movement */
PRInt32 j, startCt, beg, end, numCur;
startCt=aStrCt;
GetCtlData(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;
if (aIndex >= aLength) {
*aNextOffset = aLength;
return NS_OK;
}
/* UNUSED */
CLEAN_RUN
this->GetRangeOfCluster(aString, aLength, aIndex, &mStart, &mEnd);
*aNextOffset = mEnd;
return NS_OK;
}
// This routine returns the end-offset of the previous block
// corresponding to string index 'aIndex'
NS_IMETHODIMP
NS_IMETHODIMP
nsULE::PrevCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *prevOffset)
PRInt32 *aPrevOffset)
{
textRunList aRun;
textRun *aPtr, *aTmpPtr;
PRInt32 aStrCt=0, startCt=0, glyphct=0;
PangoliteGlyphString *aGlyphData=pangolite_glyph_string_new();
if (aIndex<=1) {
*prevOffset=0; // End
int gCt, pCluster, cCluster;
PangoliteGlyphString *GlyphInfo=pangolite_glyph_string_new();
if (aIndex <= 1) {
*aPrevOffset = 0;
return NS_OK;
}
pCluster=cCluster=0;
GetGlyphInfo(aString, aLength, GlyphInfo, NULL);
for (gCt=0; gCt < GlyphInfo->num_glyphs; gCt++) {
aRun.numRuns=0;
ScriptsByRun(aString, aLength, &aRun);
if (GlyphInfo->glyphs[gCt].is_cluster_start != GLYPH_COMBINING)
cCluster += GlyphInfo->glyphs[gCt].is_cluster_start;
// 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;
GetCtlData(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;
}
if (cCluster >= aIndex) {
*aPrevOffset = pCluster;
pangolite_glyph_string_free(GlyphInfo);
return NS_OK;
}
else {
if (aPtr->isOther) {
*prevOffset=aIndex-1;
CLEAN_RUN
return NS_OK;
}
else {
PRInt32 j,beg,end,numPrev,numCur;
startCt=aStrCt;
GetCtlData(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;
pCluster = cCluster;
}
/* UNUSED */
CLEAN_RUN
*aPrevOffset = pCluster;
pangolite_glyph_string_free(GlyphInfo);
return NS_OK;
}
// This routine returns the end-offset of the previous block
// corresponding to string index 'aIndex'
NS_IMETHODIMP
// This routine gets the bounds of a cluster given a index
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;
PangoliteGlyphString *aGlyphData=pangolite_glyph_string_new();
PangoliteGlyphString *GlyphInfo=pangolite_glyph_string_new();
int gCt=0;
*aStart = *aEnd = 0;
aRun.numRuns=0;
ScriptsByRun(aString, aLength, &aRun);
GetGlyphInfo(aString, aLength, GlyphInfo, NULL);
// 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;
*aStart=*aEnd=0;
for (gCt=0; gCt < GlyphInfo->num_glyphs; gCt++) {
startCt=aStrCt;
GetCtlData(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;
}
if (GlyphInfo->glyphs[gCt].is_cluster_start != GLYPH_COMBINING)
*aEnd += GlyphInfo->glyphs[gCt].is_cluster_start;
*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;
}
if (*aEnd >= aIndex+1) {
pangolite_glyph_string_free(GlyphInfo);
return NS_OK;
}
aPtr=aPtr->next;
*aStart = *aEnd;
}
CLEAN_RUN
/* UNUSED */
*aEnd = aLength;
pangolite_glyph_string_free(GlyphInfo);
return NS_OK;
}

View File

@ -23,7 +23,6 @@
* Contributor(s):
* Prabhat Hegde (prabhat.hegde@sun.com)
*/
#ifndef nsULE_H
#define nsULE_H
@ -36,66 +35,53 @@
#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 {
class nsULE : public nsILE {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ULE_IID)
NS_DEFINE_STATIC_CID_ACCESSOR(NS_ULE_CID)
NS_DEFINE_STATIC_CID_ACCESSOR(NS_ULE_CID)
NS_DECL_ISUPPORTS
nsULE(void);
// Destructor
virtual ~nsULE(void);
// Public Methods of nsULE - Used to handle CTL operations including
// A> API used to generate Presentation Forms based on supported fonts
// B> API used by common text operations such as cursor positioning
// B> API used by common text operations such as cursor positioning
// and selection
NS_IMETHOD NeedsCTLFix(const PRUnichar *aString,
const PRInt32 aBeg,
const PRInt32 aEnd,
PRBool *aCTLNeeded);
NS_IMETHOD GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
const char *aFontCharset,
char *aGlyphs,
PRSize *aOutLength);
PRSize *aOutLength,
PRBool aIsWide = PR_FALSE);
NS_IMETHOD PrevCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *prevOffset);
PRInt32 *aPrevOffset);
NS_IMETHOD NextCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *nextOffset);
PRInt32 *aNextOffset);
NS_IMETHOD GetRangeOfCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *aStart,
PRInt32 *aEnd);
NS_IMETHOD GetRangeOfCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *aStart,
PRInt32 *aEnd);
private:
// Housekeeping Members
void Init(void);
void CleanUp(void);
const char* GetDefaultFont(const PRUnichar);
PangoliteEngineShape* GetShaper(const PRUnichar *, PRUint32, const char *);
PRInt32 GetCtlData(const PRUnichar*, PRUint32, PangoliteGlyphString*, const char* = (const char*)NULL);
PRInt32 ScriptsByRun(const PRUnichar*, PRInt32, textRunList*);
const char* GetDefaultFont(const PRUnichar);
PRInt32 GetGlyphInfo(const PRUnichar*, PRInt32,
PangoliteGlyphString*,
const char* = (const char*)NULL);
};
#endif /* !nsULE_H */

View File

@ -18,118 +18,47 @@
*
* Contributor(s):
* Prabhat Hegde (prabhat.hegde@sun.com)
* Jungshik Shin (jshin@mailmaps.org)
*/
#include "nsCOMPtr.h"
#include "nsCtlCIID.h"
#include "nsILE.h"
#include "nsULE.h"
#include "nsUnicodeToSunIndic.h"
NS_IMPL_ADDREF(nsUnicodeToSunIndic)
NS_IMPL_RELEASE(nsUnicodeToSunIndic)
NS_IMPL_ISUPPORTS2(nsUnicodeToSunIndic, nsIUnicodeEncoder, nsICharRepresentable)
PRInt32
nsUnicodeToSunIndic::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList)
NS_IMETHODIMP
nsUnicodeToSunIndic::SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder *aEncoder,
PRUnichar aChar)
{
int ct = 0, start = 0;
PRBool isHindi = PR_FALSE;
struct textRun *tmpChunk;
if (aBehavior == kOnError_CallBack && aEncoder == nsnull)
return NS_ERROR_NULL_POINTER;
NS_IF_RELEASE(aEncoder);
mErrEncoder = aEncoder;
NS_IF_ADDREF(aEncoder);
// Handle Simple Case Now : Multiple Ranges later
PRUnichar hindiBeg = 2305; // U+0x0901;
PRUnichar hindiEnd = 2416; // U+0x097f;
for (ct = 0; ct < aSrcLen;) {
tmpChunk = new textRun;
if (!tmpChunk)
break;
if (aRunList->numRuns == 0)
aRunList->head = tmpChunk;
else
aRunList->cur->next = tmpChunk;
aRunList->cur = tmpChunk;
aRunList->numRuns++;
tmpChunk->start = &aSrcBuf[ct];
start = ct;
isHindi = (aSrcBuf[ct] >= hindiBeg && aSrcBuf[ct] <= hindiEnd);
if (isHindi) {
while (isHindi && ct < aSrcLen) {
isHindi = (aSrcBuf[ct] >= hindiBeg && aSrcBuf[ct] <= hindiEnd);
if (isHindi)
ct++;
}
tmpChunk->isOther = PR_FALSE;
}
else {
while (!isHindi && ct < aSrcLen) {
isHindi = (aSrcBuf[ct] >= hindiBeg && aSrcBuf[ct] <= hindiEnd);
if (!isHindi)
ct++;
}
tmpChunk->isOther = PR_TRUE;
}
tmpChunk->length = ct - start;
}
return (PRInt32)aRunList->numRuns;
}
nsresult nsUnicodeToSunIndic::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = NULL;
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIUnicodeEncoder))) {
*aInstancePtr = (void*) ((nsIUnicodeEncoder*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsICharRepresentable))) {
*aInstancePtr = (void*) ((nsICharRepresentable*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) ((nsISupports*)((nsIUnicodeEncoder*)this));
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP nsUnicodeToSunIndic::SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder * aEncoder,
PRUnichar aChar)
{
return NS_ERROR_NOT_IMPLEMENTED;
mErrBehavior = aBehavior;
mErrChar = aChar;
return NS_OK;
}
// constructor and destructor
nsUnicodeToSunIndic::nsUnicodeToSunIndic()
{
static NS_DEFINE_CID(kLECID, NS_ULE_CID);
nsresult rv;
NS_INIT_ISUPPORTS();
mCtlObj = do_CreateInstance(kLECID, &rv);
if (NS_FAILED(rv)) {
#ifdef DEBUG_prabhat
// No other error handling needed here since we
#ifdef DEBUG_prabhath
// 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);
printf("ERROR: Cannot create instance of component " NS_ULE_PROGID " [%x].\n", rv);
#endif
NS_WARNING("Indian Text Shaping Will Not Be Supported\n");
@ -140,7 +69,7 @@ nsUnicodeToSunIndic::nsUnicodeToSunIndic()
nsUnicodeToSunIndic::~nsUnicodeToSunIndic()
{
// Maybe convert nsILE to a service
// No NS_IF_RELEASE(mCtlObj) of nsCOMPtr;
//NS_IF_RELEASE(mCtlObj);
}
/*
@ -153,58 +82,23 @@ NS_IMETHODIMP nsUnicodeToSunIndic::Convert(const PRUnichar* input,
char* output,
PRInt32* aDestLength)
{
textRunList txtRuns;
textRun *aPtr, *aTmpPtr;
int i;
if (mCtlObj == nsnull) {
nsresult res;
PRSize outLen;
if (mCtlObj == nsnull) {
#ifdef DEBUG_prabhath
printf("Debug/Test Case of No Hindi pango shaper Object\n");
// Comment out mCtlObj == nsnull for test purposes
printf("ERROR: No Hindi Text Layout Implementation");
#endif
NS_WARNING("cannot get default converter for Hindi");
NS_WARNING("cannot get default converter for Hindi");
return NS_ERROR_FAILURE;
}
mCharOff = mByteOff = 0;
txtRuns.numRuns = 0;
Itemize(input, *aSrcLength, &txtRuns);
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
PRInt32 tmpSrcLen = aPtr->length;
if (aPtr->isOther) {
// PangoHindiShaper does not handle ASCII + Hindi in same shaper
for (int j = 0; j < tmpSrcLen; j++)
output[j + mByteOff] = (char)(*(aPtr->start + j));
mByteOff += tmpSrcLen;
}
else {
PRSize outLen = *aDestLength - mByteOff;
// At the moment only generate presentation forms for
// sun.unicode.india are supported.
mCtlObj->GetPresentationForm(aPtr->start, tmpSrcLen, "sun.unicode.india-0",
&output[mByteOff], &outLen);
mByteOff += outLen;
}
aPtr = aPtr->next;
}
// Cleanup Run Info;
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
aTmpPtr = aPtr;
aPtr = aPtr->next;
delete aTmpPtr;
}
*aDestLength = mByteOff;
mCtlObj->GetPresentationForm(input, *aSrcLength, "sun.unicode.india-0",
&output[mByteOff], &outLen, PR_TRUE);
*aDestLength = outLen;
return NS_OK;
}
@ -224,7 +118,7 @@ NS_IMETHODIMP nsUnicodeToSunIndic::Reset()
}
//================================================================
NS_IMETHODIMP nsUnicodeToSunIndic::GetMaxLength(const PRUnichar * aSrc,
NS_IMETHODIMP nsUnicodeToSunIndic::GetMaxLength(const PRUnichar * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
@ -232,8 +126,8 @@ NS_IMETHODIMP nsUnicodeToSunIndic::GetMaxLength(const PRUnichar * aSrc,
// atmost two presentation forms
return NS_OK;
}
//================================================================
//================================================================
NS_IMETHODIMP nsUnicodeToSunIndic::FillInfo(PRUint32* aInfo)
{
PRUint16 i;
@ -256,9 +150,8 @@ NS_IMETHODIMP nsUnicodeToSunIndic::FillInfo(PRUint32* aInfo)
SET_REPRESENTABLE(aInfo, i);
for (i = 0x0958; i <= 0x0970; i++)
SET_REPRESENTABLE(aInfo, i);
SET_REPRESENTABLE(aInfo, i);
// ZWJ and ZWNJ support & coverage need to be added.
return NS_OK;
}

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ucvth : nsUnicodeToSunIndic.h
* ucvhi : nsUnicodeToSunIndic.h
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@ -19,7 +19,6 @@
* Contributor(s):
* Prabhat Hegde (prabhat.hegde@sun.com)
*/
#ifndef nsUnicodeToSunIndic_h___
#define nsUnicodeToSunIndic_h___
@ -34,20 +33,14 @@
#include "nsILE.h"
struct textRunList;
//----------------------------------------------------------------------
// Class nsUnicodeToSunIndic [declaration]
class nsUnicodeToSunIndic : public nsIUnicodeEncoder, public nsICharRepresentable
{
NS_DECL_ISUPPORTS
public:
/**
* Class constructor.
*/
nsUnicodeToSunIndic();
virtual ~nsUnicodeToSunIndic();
@ -62,7 +55,7 @@ public:
NS_IMETHOD Reset();
NS_IMETHOD SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder * aEncoder,
nsIUnicharEncoder * aEncoder,
PRUnichar aChar);
NS_IMETHOD FillInfo(PRUint32* aInfo);
@ -74,9 +67,8 @@ private:
nsCOMPtr<nsILE> mCtlObj;
// beg and end denote ranges and may need to be expanded in the future to
// handle discontinous ranges
PRInt32 Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList);
PRInt32 mErrBehavior;
PRUnichar mErrChar;
nsIUnicharEncoder* mErrEncoder;
};
#endif /* !nsUnicodeToSunIndic_h___ */

View File

@ -23,7 +23,6 @@
* Contributor(s):
* Prabhat Hegde (prabhat.hegde@sun.com)
*/
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
@ -35,88 +34,7 @@
static NS_DEFINE_CID(kCharSetManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
// XPCOM stuff
NS_IMPL_ADDREF(nsUnicodeToTIS620)
NS_IMPL_RELEASE(nsUnicodeToTIS620)
PRInt32
nsUnicodeToTIS620::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList)
{
int ct = 0, start = 0;
PRBool isTis = PR_FALSE;
struct textRun *tmpChunk;
// Handle Simple Case Now : Multiple Ranges later
PRUnichar thaiBeg = 3585; // U+0x0E01;
PRUnichar thaiEnd = 3675; // U+0x0E5b
for (ct = 0; ct < aSrcLen;) {
tmpChunk = new textRun;
if (!tmpChunk)
break;
if (aRunList->numRuns == 0)
aRunList->head = tmpChunk;
else
aRunList->cur->next = tmpChunk;
aRunList->cur = tmpChunk;
aRunList->numRuns++;
tmpChunk->start = &aSrcBuf[ct];
start = ct;
isTis = (aSrcBuf[ct] >= thaiBeg && aSrcBuf[ct] <= thaiEnd);
if (isTis) {
while (isTis && ct < aSrcLen) {
isTis = (aSrcBuf[ct] >= thaiBeg && aSrcBuf[ct] <= thaiEnd);
if (isTis)
ct++;
}
tmpChunk->isOther = PR_FALSE;
}
else {
while (!isTis && ct < aSrcLen) {
isTis = (aSrcBuf[ct] >= thaiBeg && aSrcBuf[ct] <= thaiEnd);
if (!isTis)
ct++;
}
tmpChunk->isOther = PR_TRUE;
}
tmpChunk->length = ct - start;
}
return (PRInt32)aRunList->numRuns;
}
nsresult nsUnicodeToTIS620::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = NULL;
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIUnicodeEncoder))) {
*aInstancePtr = (void*) ((nsIUnicodeEncoder*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsICharRepresentable))) {
*aInstancePtr = (void*) ((nsICharRepresentable*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) ((nsISupports*)((nsIUnicodeEncoder*)this));
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ISUPPORTS2(nsUnicodeToTIS620, nsIUnicodeEncoder, nsICharRepresentable)
NS_IMETHODIMP nsUnicodeToTIS620::SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder * aEncoder,
@ -125,20 +43,19 @@ NS_IMETHODIMP nsUnicodeToTIS620::SetOutputErrorBehavior(PRInt32 aBehavior,
return NS_ERROR_NOT_IMPLEMENTED;
}
// constructor and destroctor
nsUnicodeToTIS620::nsUnicodeToTIS620()
{
static NS_DEFINE_CID(kLECID, NS_ULE_CID);
nsresult rv;
NS_INIT_ISUPPORTS();
mCtlObj = do_CreateInstance(kLECID, &rv);
if (NS_FAILED(rv)) {
#ifdef DEBUG_prabhat
// No other error handling needed here since we
#ifdef DEBUG_prabhath
// 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);
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;
@ -161,15 +78,12 @@ NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar* input,
char* output,
PRInt32* aDestLength)
{
textRunList txtRuns;
textRun *aPtr, *aTmpPtr;
int i;
PRSize outLen = 0;
#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) {
nsICharsetConverterManager* gCharSetManager = nsnull;
nsIUnicodeEncoder* gDefaultTISConverter = nsnull;
@ -193,54 +107,27 @@ NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar* input,
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;
return NS_OK;
}
// CTLized shaping conversion starts here
// No question of starting the conversion from an offset
mCharOff = mByteOff = 0;
txtRuns.numRuns = 0;
Itemize(input, *aSrcLength, &txtRuns);
// Charset tis620-0, tis620.2533-1, tis620.2529-1 & iso8859-11
// are equivalent and have the same presentation forms
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
PRInt32 tmpSrcLen = aPtr->length;
if (aPtr->isOther) {
// PangoThaiShaper does not handle ASCII + thai in same shaper
for (int j = 0; j < tmpSrcLen; j++)
output[j + mByteOff] = (char)(*(aPtr->start + j));
mByteOff += tmpSrcLen;
}
else {
PRSize outLen = *aDestLength - mByteOff;
// Charset tis620-0, tis620.2533-1, tis620.2529-1 & iso8859-11
// are equivalent and have the same presentation forms
// tis620-2 is hard-coded since we only generate presentation forms
// in Windows-Stye as it is the current defacto-standard for the
// presentation of thai content
mCtlObj->GetPresentationForm(input, *aSrcLength, "tis620-2",
&output[mByteOff], &outLen);
// tis620-2 is hard-coded since we only generate presentation forms
// in Windows-Stye as it is the current defacto-standard for the
// presentation of thai content
mCtlObj->GetPresentationForm(aPtr->start, tmpSrcLen, "tis620-2",
&output[mByteOff], &outLen);
mByteOff += outLen;
}
aPtr = aPtr->next;
}
// Cleanup Run Info;
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
aTmpPtr = aPtr;
aPtr = aPtr->next;
delete aTmpPtr;
}
*aDestLength = mByteOff;
*aDestLength = outLen;
return NS_OK;
}
@ -260,16 +147,16 @@ NS_IMETHODIMP nsUnicodeToTIS620::Reset()
}
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::GetMaxLength(const PRUnichar * aSrc,
NS_IMETHODIMP nsUnicodeToTIS620::GetMaxLength(const PRUnichar * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
*aDestLength = (aSrcLength + 1) * 2; // Each Thai character can generate
*aDestLength = (aSrcLength + 1) * 2; // Each Thai character can generate
// atmost two presentation forms
return NS_OK;
}
//================================================================
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::FillInfo(PRUint32* aInfo)
{
PRUint16 i;
@ -279,9 +166,9 @@ NS_IMETHODIMP nsUnicodeToTIS620::FillInfo(PRUint32* aInfo)
SET_REPRESENTABLE(aInfo, i);
// 0x0e01-0x0e7f
for (i = 0x0e01; i <= 0xe3a; i++)
for (i = 0x0e01; i <= 0xe3a; i++)
SET_REPRESENTABLE(aInfo, i);
// U+0E3B - U+0E3E is undefined
// U+0E3F - U+0E5B
for (i = 0x0e3f; i <= 0x0e5b; i++)

View File

@ -37,8 +37,6 @@
#include "nsILE.h"
struct textRunList;
//----------------------------------------------------------------------
// Class nsUnicodeToTIS620 [declaration]
@ -76,9 +74,5 @@ private:
PRInt32 mCharOff;
nsCOMPtr<nsILE> mCtlObj;
// beg and end denote ranges and may need to be expanded in the future to
// handle discontinous ranges
PRInt32 Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList);
};
#endif /* !nsUnicodeToTIS620_h___ */

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* Pangolite
* modules.h:
*
* The contents of this file are subject to the Mozilla Public
@ -32,8 +32,8 @@
* LGPL.
*/
#include <pangolite/pango-engine.h>
#include <pangolite/pango-modules.h>
#include <pango-engine.h>
#include <pango-modules.h>
#ifndef __MODULES_H__
#define __MODULES_H__

View File

@ -41,26 +41,19 @@
extern "C" {
#endif /* __cplusplus */
typedef struct _PangoliteGlyphVisAttr PangoliteGlyphVisAttr;
typedef struct _PangoliteGlyphInfo PangoliteGlyphInfo;
typedef struct _PangoliteGlyphString PangoliteGlyphString;
/* 1000ths of a device unit */
typedef gint32 PangoliteGlyphUnit;
/* Visual attributes of a glyph
*/
struct _PangoliteGlyphVisAttr
{
guint is_cluster_start : 1;
};
/* A single glyph
*/
struct _PangoliteGlyphInfo
{
PangoliteGlyph glyph;
PangoliteGlyphVisAttr attr;
PangoliteGlyph glyph;
gint is_cluster_start;
};
/* A string of glyphs with positional information and visual attributes -
@ -86,20 +79,7 @@ PangoliteGlyphString *pangolite_glyph_string_new(void);
void pangolite_glyph_string_set_size(PangoliteGlyphString *string, gint new_len);
void pangolite_glyph_string_free(PangoliteGlyphString *string);
void pangolite_glyph_string_index_to_x(PangoliteGlyphString *glyphs,
char *text,
int length,
PangoliteAnalysis *analysis,
int index,
gboolean trailing,
int *x_pos);
void pangolite_glyph_string_x_to_index(PangoliteGlyphString *glyphs,
char *text,
int length,
PangoliteAnalysis *analysis,
int x_pos,
int *index,
int *trailing);
/* Turn a string of characters into a string of glyphs */
void pangolite_shape(const gunichar2 *text,
@ -107,8 +87,6 @@ void pangolite_shape(const gunichar2 *text,
PangoliteAnalysis *analysis,
PangoliteGlyphString *glyphs);
GList *pangolite_reorder_items(GList *logical_items);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* Pangolite
* pango.h:
*
* The contents of this file are subject to the Mozilla Public
@ -39,9 +39,9 @@
extern "C" {
#endif /* __cplusplus */
#include <pangolite/pango-engine.h>
#include <pangolite/pango-glyph.h>
#include <pangolite/pango-types.h>
#include <pango-engine.h>
#include <pango-glyph.h>
#include <pango-types.h>
#ifdef __cplusplus
}

View File

@ -50,8 +50,9 @@
#define ucs2tis(wc) (unsigned int)((unsigned int)(wc) - 0x0E00 + 0xA0)
#define tis2uni(c) ((gunichar2)(c) - 0xA0 + 0x0E00)
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
#define GLYPH_COMBINING 256
/* Define TACTIS character classes */
#define CTRL 0
@ -105,28 +106,6 @@
typedef guint16 PangoliteXSubfont;
#define PANGO_MOZ_MAKE_GLYPH(index) ((guint32)0 | (index))
#ifdef MOZ_WIDGET_GTK2
char g_utf8_skip_array[256] = {
#else
char g_utf8_skip[256] = {
#endif
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0
};
#ifdef MOZ_WIDGET_GTK2
extern const gchar * const g_utf8_skip = g_utf8_skip_array;
#else
#define g_utf8_next_char(p) (char*)((p) + g_utf8_skip[*(unsigned char*)(p)])
#endif
/* We handle the range U+0e01 to U+0e5b exactly
*/
static PangoliteEngineRange thai_ranges[] = {
@ -397,7 +376,7 @@ get_font_info (const char *fontCharset)
};
ThaiFontInfo *font_info = g_new(ThaiFontInfo, 1);
gint subfontId, i;
guint i;
font_info->type = THAI_FONT_NONE;
for (i = 0; i < G_N_ELEMENTS(charsets); i++) {
@ -411,17 +390,20 @@ get_font_info (const char *fontCharset)
}
static void
add_glyph(ThaiFontInfo *font_info,
add_glyph(ThaiFontInfo *font_info,
PangoliteGlyphString *glyphs,
gint cluster_start,
gint cluster_start,
PangoliteGlyph glyph,
gboolean combining)
gint combining)
{
gint index = glyphs->num_glyphs;
if ((cluster_start == 0) && (index != 0))
cluster_start++;
pangolite_glyph_string_set_size(glyphs, index + 1);
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = combining ? 0 : 1;
glyphs->glyphs[index].is_cluster_start = combining;
glyphs->log_clusters[index] = cluster_start;
}
@ -653,20 +635,24 @@ get_glyphs_list(ThaiFontInfo *font_info,
}
static void
add_cluster (ThaiFontInfo *font_info,
PangoliteGlyphString *glyphs,
gint cluster_start,
gunichar2 *cluster,
gint num_chrs)
add_cluster(ThaiFontInfo *font_info,
PangoliteGlyphString *glyphs,
gint cluster_start,
gunichar2 *cluster,
gint num_chrs)
{
PangoliteGlyph glyphs_list[MAX_GLYPHS];
gint i, num_glyphs;
gint i, num_glyphs, ClusterStart=0;
num_glyphs = get_glyphs_list(font_info, cluster, num_chrs, glyphs_list);
for (i=0; i<num_glyphs; i++)
add_glyph(font_info, glyphs, cluster_start, glyphs_list[i],
i == 0 ? FALSE : TRUE);
for (i=0; i<num_glyphs; i++) {
ClusterStart = (gint)GLYPH_COMBINING;
if (i == 0)
ClusterStart = num_chrs;
add_glyph(font_info, glyphs, cluster_start, glyphs_list[i], ClusterStart);
}
}
static gboolean
@ -734,8 +720,6 @@ thai_engine_shape(const char *fontCharset,
gunichar2 cluster[MAX_CLUSTER_CHRS];
gint num_chrs;
pangolite_glyph_string_set_size(glyphs, 0);
font_info = get_font_info(fontCharset);
p = text;