mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
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:
parent
45f50dbc47
commit
4672446205
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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___ */
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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___ */
|
||||
|
@ -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__
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user