/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * Pangolite * dvng-x.c: * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. The Initial Developer of the Original Code is Sun Microsystems, Inc. Portions created by SUN are Copyright (C) 2002 SUN Microsystems, Inc. All Rights Reserved. * * The Initial Developer of the Original Code is * Sun Microsystems, Inc. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Prabhat Hegde (prabhat.hegde@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include #include #include "pango-engine.h" #include "pango-coverage.h" #define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) #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). * * Displayed above the Consonant/Vowel * * _IV : Independant Vowels * * _CN : All consonants except _CK and _RC below * * _CK : Consonants that can be followed by a Nukta(U+093C). Characters * * (U+0958-U+095F). No clue why Unicode imposed it on Devanagari. * * _RC : Consonant Ra - Needs to handle 'Reph' * * _NM : Handle special case of Matras when followed by a Chandrabindu/ * * Anuswar. * * _IM : Choti I Matra (U+093F). Needs to handle re-ordering. * * _HL : Halant (U+094D) * * _NK : Nukta (U+093C) * * _VD : For Vedic extension characters (U+0951 - U+0954) * * _HD : Hindu Numerals written in Devanagari * * _MS : For Matras such U+0941, U+0942 which need to be attached to the * * holding consonant at the Stem. * * _RM : A cluster of Ra+Halant at the begining would be represented by * * a Reph (placed in sun.unicode.india-0 at 0xF812). Reph is * * typically attached on top of the last consonant. * * _II_M, _EY_M, _AI_M, _OW1_M, _OW2_M, _AYE_M, _EE_M, _AWE_M, _O_M, * * : Separate glyphs are provided which combine matra with a reph. * * Matras which need to use this are represented by the above. * *************************************************************************/ /************************************************************************* * CLUSTERING LOGIC * * ---------------- * * * * Notations used to describe Devanagari Script Generic Info: * * D : Vowel-Modifiers (U+0901 - U+0903) * * V : Vowels (U+0905 - U+0913) & (U+0960, U+0961) * * C : Consonants (U+0915 - U+0939) * * M : Matras (U+093E - U+094C) & (U+0962, U+0963) * * H : Halant (U+094D) * * N : Nukta (U+093C) * * * * RULES:- * * ------- * * Syllable/Cluster types * * * * 1] Vowel Syllable ::- V[D] * * 2] Cons - Vowel Syllable ::- [Cons-Syllable] Full- Cons [M] [D] * * 3] Cons-Syllable ::- [Pure-Cons][Pure-Cons] Pure-Cons * * 4] Pure-Cons ::- Full-Cons H * * 5] Full-Cons ::- C[N] * * * * Notes: * * 1] Nukta (N) can come after only those consonants with which it can * * combine, ie U+0915-U+0917, U+091C, U+0921, U+0922, U+092B & U+092F * * 2] Worst case Vowel cluster - V D * * 3] A worst case Consonant cluster: C N H C N H C N H C N M D * *************************************************************************/ /* * Devanagari character classes */ #define _NP 1L #define _UP (1L<<1) #define _IV (1L<<2) #define _CN (1L<<3) #define _CK (1L<<4) #define _RC (1L<<5) #define _NM (1L<<6) #define _IM (1L<<7) #define _HL (1L<<8) #define _NK (1L<<9) #define _VD (1L<<10) #define _HD (1L<<11) #define _II_M (1L<<12) #define _EY_M (1L<<13) #define _AI_M (1L<<14) #define _OW1_M (1L<<15) #define _OW2_M (1L<<16) #define _MS (1L<<17) #define _AYE_M (1L<<18) #define _EE_M (1L<<19) #define _AWE_M (1L<<20) #define _O_M (1L<<21) #define _RM (_II_M|_EY_M|_AI_M|_OW1_M|_OW2_M|_AYE_M|_EE_M|_AWE_M|_O_M) /* Common Non-defined type */ #define __ND 0 /* * Devanagari character types */ #define __UP 1 #define __NP 2 #define __IV 3 #define __CN 4 #define __CK 5 #define __RC 6 #define __NM 7 #define __RM 8 #define __IM 9 #define __HL 10 #define __NK 11 #define __VD 12 #define __HD 13 /* * Devanagari Glyph Type State */ #define St0 0 #define St1 1 #define St2 2 #define St3 3 #define St4 4 #define St5 5 #define St6 6 #define St7 7 #define St8 8 #define St9 9 #define St10 10 #define St11 11 #define St12 12 #define St13 13 #define St14 14 #define St15 15 #define St16 16 #define St17 17 #define St18 18 #define St19 19 #define St20 20 #define _ND 0 #define _NC 1 #define _UC (1<<1) #define _BC (1<<2) #define _SC (1<<3) #define _AV (1<<4) #define _BV (1<<5) #define _TN (1<<6) #define _AD (1<<7) #define _BD (1<<8) #define _AM (1<<9) #define MAP_SIZE 243 #define MAX_STATE 21 #define MAX_DEVA_TYPE 14 #define MAX_CORE_CONS 6 #define SCRIPT_ENGINE_NAME "DvngScriptEngineX" #define PANGO_RENDER_TYPE_X "PangoliteRenderX" #define ucs2dvng(ch) (gunichar2)((gunichar2)(ch) - 0x0900) typedef guint16 PangoliteXSubfont; #define PANGO_MOZ_MAKE_GLYPH(index) ((guint32)0 | (index)) /* We handle the following ranges between U+0901 to U+0970 exactly */ static PangoliteEngineRange dvng_ranges[] = { { 0x0901, 0x0903, "*" }, { 0x0905, 0x0939, "*" }, { 0x093c, 0x094d, "*" }, { 0x0950, 0x0954, "*" }, { 0x0958, 0x0970, "*" }, /* Hindi Ranges */ }; static PangoliteEngineInfo script_engines[] = { { SCRIPT_ENGINE_NAME, PANGO_ENGINE_TYPE_SHAPE, PANGO_RENDER_TYPE_X, dvng_ranges, G_N_ELEMENTS(dvng_ranges) } }; /* X window system script engine portion */ typedef struct _DvngFontInfo DvngFontInfo; /* The type of encoding that we will use */ typedef enum { DVNG_FONT_NONE, DVNG_FONT_SUN } DvngFontType; /* */ typedef struct { const gunichar ISCII[MAX_CORE_CONS]; const unsigned short ISFOC[MAX_CORE_CONS]; } DvngGlyphEntry; /* */ struct _DvngFontInfo { DvngFontType type; PangoliteXSubfont subfont; }; typedef long DvngCls; typedef int StateType; /* * Devanagari character class table */ static const DvngCls DvngChrClsTbl[128] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */ /* 0 */ _ND, _UP, _UP, _NP, _ND, _IV, _IV, _IV, _IV, _IV, _IV, _IV, _IV, _IV, _IV, _IV, /* 1 */ _IV, _IV, _IV, _IV, _IV, _CK|_MS, _CK, _CK, _CN, _CN, _CN, _CN, _CK, _CN, _CN,_CN|_MS, /* 2 */ _CN|_MS, _CK|_MS, _CK|_MS, _CN, _CN, _CN, _CN, _CN, _CN, _CN, _CN, _CK|_MS, _CN, _CN, _CN, _CN, /* 3 */ _RC, _CN, _CN, _CN, _CN, _CN, _CN, _CN, _CN, _CN|_MS, _ND, _ND, _NK, _VD, _NM, _IM, /* 4 */ _II_M, _NM, _NM, _NM, _NM, _AYE_M, _EE_M, _EY_M, _AI_M, _AWE_M, _O_M, _OW1_M, _OW2_M, _HL, _ND, _ND, /* 5 */ _ND, _VD, _VD, _VD, _VD, _ND, _ND, _ND, _CN, _CN, _CN, _CN, _CN, _CN, _CN, _CN, /* 6 */ _IV, _IV, _NM, _NM, _ND, _ND, _HD, _HD, _HD, _HD, _HD, _HD, _HD, _HD, _HD, _HD, /* 7 */ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND, }; /* * Devanagari character type table */ static const gint DvngChrTypeTbl[128] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */ /* 0 */ __ND, __UP, __UP, __NP, __ND, __IV, __IV, __IV, __IV, __IV, __IV, __IV, __IV, __IV, __IV, __IV, /* 1 */ __IV, __IV, __IV, __IV, __IV, __CK, __CK, __CK, __CN, __CN, __CN, __CN, __CK, __CN, __CN, __CN, /* 2 */ __CN, __CK, __CK, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __CK, __CN, __CN, __CN, __CN, /* 3 */ __RC, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __ND, __ND, __NK, __VD, __NM, __IM, /* 4 */ __RM, __NM, __NM, __NM, __NM, __RM, __RM, __RM, __RM, __RM, __RM, __RM, __RM, __HL, __ND, __ND, /* 5 */ __ND, __VD, __VD, __VD, __VD, __ND, __ND, __ND, __CN, __CN, __CN, __CN, __CN, __CN, __CN, __CN, /* 6 */ __IV, __IV, __NM, __NM, __ND, __ND, __HD, __HD, __HD, __HD, __HD, __HD, __HD, __HD, __HD, __HD, /* 7 */ __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, __ND, }; /* * 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 */ }; 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, }, /* State 1 */ { 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, }, /* State 3 */ { 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, }, /* State 5 */ { 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, }, /* State 7 */ { 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, }, /* State 9 */ { 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, }, /* State 11 */ { 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, }, /* State 13 */ { 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, }, /* State 15 */ { 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, }, /* State 17 */ { 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, }, /* State 19 */ { 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, }, }; int DvngRuleTbl[128] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */ /* 0 */ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */ 1, 1, 1, 1, 1, 4, 4, 4, 4, 2, 4, 1, 4, 4, 3, 3, /* 2 */ 3, 3, 3, 2, 4, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, /* 3 */ 2, 2, 2, 2, 1, 4, 4, 3, 5, 4, 0, 0, 2, 1, 1, 1, /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, /* 5 */ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define IsDvngCharCls(ch, mask) (DvngChrClsTbl[ucs2dvng((ch))] & (mask)) #define IsComposible(ch1, ch2) (DvngComposeTbl[DvngChrTypeTbl[ucs2dvng((ch1))]][DvngChrTypeTbl[ucs2dvng((ch2))]]) #define GetDvngRuleCt(ch) (DvngRuleTbl[ucs2dvng((ch))]) #define IsKern(gid) ((gid >= 0xF830 && gid <= 0xF83E) ? TRUE : FALSE) #define IsMatraAtStem(gid) (((gid >= 0xF811 && gid <= 0xF813) || \ (gid >= 0xF81E && gid <= 0xF82F) || \ (gid >= 0x0962 && gid <= 0x0963) || \ (gid >= 0x0941 && gid <= 0x0948) || \ (gid == 0x093C) || (gid == 0x094D)) ? TRUE : FALSE) #define SetClusterState(st, ch) DvngStateTbl[(st)][DvngChrTypeTbl[ucs2dvng((ch))]] #define MAP_SIZE 243 /* * Devanagari Glyph Tables */ static const DvngGlyphEntry sunGlyphTbl[MAP_SIZE] = { /* Vowel Modifiers - Ct 3 */ { {0x0901,0x0}, {0x0901,0x0} }, { {0x0902,0x0}, {0x0902,0x0} }, { {0x0903,0x0}, {0x0903,0x0} }, /* vowels 13 - Ct 18 */ { {0x0905,0x0}, {0x0905,0x0} }, { {0x0906,0x0}, {0x0906,0x0} }, { {0x0907,0x0}, {0x0907,0x0} }, { {0x0908,0x0}, {0x0908,0x0} }, { {0x0909,0x0}, {0x0909,0x0} }, { {0x090a,0x0}, {0x090a,0xF830,0x0} }, { {0x090b,0x0}, {0x090b,0xF831,0x0} }, { {0x0960,0x0}, {0x0960,0xF831,0x0} }, { {0x090c,0x0}, {0x090c,0xF83D,0x0} }, { {0x0961,0x0}, {0x0961,0xF83D,0x0} }, { {0x090d,0x0}, {0x090d,0x0} }, { {0x090e,0x0}, {0x090e,0x0} }, { {0x090f,0x0}, {0x090f,0x0} }, { {0x0910,0x0}, {0x0910,0x0} }, { {0x0911,0x0}, {0x0911,0x0} }, { {0x0912,0x0}, {0x0912,0x0} }, { {0x0913,0x0}, {0x0913,0x0} }, { {0x0914,0x0}, {0x0914,0x0} }, /* Vowel signs - Ct 17 */ { {0x093e,0x0}, {0x093e,0x0} }, { {0x093f,0x0}, {0x093f,0x0} }, { {0x0940,0x0}, {0x0940,0x0} }, { {0x0941,0x0}, {0x0941,0x0} }, { {0x0942,0x0}, {0x0942,0x0} }, { {0x0943,0x0}, {0x0943,0x0} }, { {0x0944,0x0}, {0x0944,0x0} }, { {0x0945,0x0}, {0x0945,0x0} }, { {0x0946,0x0}, {0x0946,0x0} }, { {0x0947,0x0}, {0x0947,0x0} }, { {0x0948,0x0}, {0x0948,0x0} }, { {0x0949,0x0}, {0x0949,0x0} }, { {0x094a,0x0}, {0x094a,0x0} }, { {0x094b,0x0}, {0x094b,0x0} }, { {0x094c,0x0}, {0x094c,0x0} }, { {0x0962,0x0}, {0x0962,0x0} }, { {0x0963,0x0}, {0x0963,0x0} }, /* Consonants */ /* ka -> ka + kern space */ { {0x0915,0x0}, {0x0915,0xF832,0x0} }, /* ka nukta -> ka nukta + kern space */ { {0x0915,0x093c,0x0}, {0x0958,0xF832,0x0} }, /* ka + halant -> half ka */ { {0x0915,0x094d,0x0}, {0xF7C1,0x0} }, /* ka nukta + halant-> half ka nukta */ { {0x0915,0x093c,0x094d,0x0}, {0xF7C2,0x0} }, { {0x0915,0x094d,0x0915,0x0}, {0xF845,0xF832,0x0} }, /* ka + halant + ta -> kta + kern space */ { {0x0915,0x094d,0x0924,0x0}, {0xF7C4,0xF832,0x0} }, /* ka + halant + ra -> kra + kern space */ { {0x0915,0x094d,0x0930,0x0}, {0xF7C3,0xF832,0x0} }, { {0x0915,0x094d,0x0930,0x094d,0x0}, {0xF7C3,0x094d,0xF832,0x0} }, /* ka + halant + SHa -> kSHa */ { {0x0915,0x094d,0x0937,0x0}, {0xF7C5,0x093E,0x0} }, /* ka + halant + SHa + halant -> half kSHa */ { {0x0915,0x094d,0x0937,0x094d,0x0}, {0xF7C5,0x0} }, /* kha 6 */ { {0x0916,0x0}, {0x0916,0x0} }, { {0x0916,0x094d,0x0}, {0xF7C6,0x0} }, { {0x0916,0x093c,0x0}, {0x0959,0x0} }, { {0x0916,0x093c,0x094d,0x0}, {0xF7C7,0x0} }, { {0x0916,0x094d,0x0930,0x0}, {0xF7C8,0x093E,0x0} }, { {0x0916,0x094d,0x0930,0x094d,0x0}, {0xF7C8,0x0} }, /* ga 6 */ { {0x0917,0x0}, {0x0917,0x0} }, { {0x0917,0x094d,0x0}, {0xF7C9,0x0} }, { {0x0917,0x093c,0x0}, {0x095a,0x0} }, { {0x0917,0x093c,0x094d,0x0}, {0xF7CA,0x0} }, { {0x0917,0x094d,0x0930,0x0}, {0xF7CB,0x093E,0x0} }, { {0x0917,0x094d,0x0930,0x094d,0x0}, {0xF7CB,0x0} }, /* gha 4 */ { {0x0918,0x0}, {0x0918,0x0} }, { {0x0918,0x094d,0x0}, {0xF7CC,0x0} }, { {0x0918,0x094d,0x0930,0x0}, {0xF7CD,0x093E,0x0} }, { {0x0918,0x094d,0x0930,0x094d,0x0}, {0xF7CD,0x0} }, /* nga 1 */ { {0x0919,0x0}, {0x0919,0xF833,0x0} }, /* { {0x0919,0x094d,0x0}, {0x0919,0x094d,0xF833,0x0} }, */ /* cha 4 */ { {0x091a,0x0}, {0x091a,0x0} }, /* cha + halant -> half cha */ { {0x091a,0x094d,0x0}, {0xF7CE,0x0} }, /* cha + halant ra -> chra */ { {0x091a,0x094d,0x0930,0x0}, {0xF7CF,0x093E,0x0} }, /* cha + halant ra + halant */ { {0x091a,0x094d,0x0930,0x094d,0x0}, {0xF7CF,0x0} }, /* chha 1 */ { {0x091b,0x0}, {0x091b,0xF834,0x0} }, /* chha + halant -> chha+ halant */ /* { {0x091b,0x094d,0x0 }, {0x091b,0x094d,0xF834,0x0} }, */ /* ja 6 */ /* ja */ { {0x091c,0x0}, {0x091c,0x0} }, /* ja + halant -> half ja */ { {0x091c,0x094d,0x0}, {0xF7D0,0x0} }, /* ja + nukta -> za */ { {0x091c,0x093c,0x0}, {0xF7D1,0x093E,0x0} }, /* ja + nukta + halant -> half za */ { {0x091c,0x093c,0x094d,0x0 }, {0xF7D1,0x0} }, /* ja + halant + ra -> jra */ { {0x091c,0x094d,0x0930,0x0}, {0xF7D2,0x093E,0x0} }, /* ja + halant + ra + halant -> */ { {0x091c,0x094d,0x0930,0x094d,0x0}, {0xF7D2,0x0} }, /* dna 2 */ /* ja + halant + jna -> dna */ { {0x091c,0x094d,0x091e,0x0}, {0xF7D3,0x093E,0x0} }, /* ja + halant + jna -> half dna */ { {0x091c,0x094d,0x091e,0x094d,0x0}, {0xF7D3,0x0} }, /* jha 4 */ /* jha */ { {0x091d,0x0}, {0x091d,0x0} }, /* jha + halant -> half jha */ { {0x091d,0x094d,0x0}, {0xF7D4,0x0} }, /* jha + halant -> jhra */ { {0x091d,0x094d,0x0930,0x0}, {0xF7D5,0x093E,0x0} }, /* jha + halant -> half jhra */ { {0x091d,0x094d,0x0930,0x094d,0x0}, {0xF7D5,0x0} }, /* nya 2 */ /* nya */ { {0x091e,0x0}, {0x091e,0x0} }, /* nya + halant -> half nya */ { {0x091e,0x094d,0x0}, {0xF7D6,0x0} }, { {0x091e,0x094d,0x091c,0x0}, {0xF846,0x0} }, /* Ta 3 */ /* Ta -> Ta + kern space */ { {0x091f,0x0}, {0x091F,0xF835,0x0} }, { {0x091f,0x094d,0x0}, {0x091f,0x094d,0xF835,0x0} }, /* Ta + halant + Ta -> TaTa + kern space */ { {0x091f,0x094d,0x091f,0x0}, {0xF7D7,0xF835,0x0} }, /* Ta + halant + Tha -> TaTha + kern space */ { {0x091f,0x094d,0x0920,0x0}, {0xF7D8,0xF835,0x0} }, /* Tha 2 */ /* Tha -> Tha + kern space */ { {0x0920,0x0}, {0x0920,0xF836,0x0} }, { {0x0920,0x094d,0x0}, {0x0920,0x094d,0xF836,0x0} }, /* Tha + halant + Tha -> + kern space */ { {0x0920,0x094d,0x0920,0x0}, {0xF7D9,0xF836,0x0} }, /* Da 1 */ /* Da -> Da + kern space */ { {0x0921,0x0}, {0x0921,0xF837,0x0} }, { {0x0921,0x094d,0x0}, {0x0921,0x094d,0xF837,0x0} }, /* Da nukta 1 */ /* Da + nukta -> + kern space */ { {0x0921,0x093c,0x0}, {0x095c,0xF837,0x0} }, /* Da + nukta+ halant */ { {0x0921,0x093c,0x094d,0x0}, {0x095c,0x094d,0xF837,0x0} }, { {0x0921,0x094d,0x0917,0x0}, {0xF847,0xF837,0x0} }, /* Da halant Da 1 */ /* Da + halant + Da - > + kern space */ { {0x0921,0x094d,0x0921,0x0}, {0xF7DA,0xF837,0x0} }, /* Da halant Dha 1 */ /* Da + halant + Dha -> + kern space */ { {0x0921,0x094d,0x0922,0x0}, {0xF7DB,0xF837,0x0} }, /* Dha 1 */ /* Dha + kern space */ { {0x0922,0x0}, {0x0922,0xF838,0x0} }, /* Dha nukta 1 */ /* Dha + nukta -> + kern space */ { {0x0922,0x093c,0x0}, {0x095d,0xF838,0x0} }, { {0x0922,0x093c,0x094d,0x0}, {0x095d,0x094d,0xF838,0x0} }, { {0x0922,0x094d,0x0}, {0x0922,0x094d,0xF838,0x0} }, /* Nna 2 */ /* Nna */ { {0x0923,0x0}, {0x0923,0x0} }, /* Nna + halant -> half Nna */ { {0x0923,0x094d,0x0}, {0xF7DC,0x0} }, /* ta 6 */ /* ta */ { {0x0924,0x0}, {0x0924,0x0} }, /* ta + halant -> half ta */ { {0x0924,0x094d,0x0}, {0xF7DD,0x0} }, /* ta + halant + ra -> half tra */ { {0x0924,0x094d,0x0930,0x0}, {0xF7DE,0x093E,0x0} }, /* ta + halant + ra + halant -> half tra */ { {0x0924,0x094d,0x0930,0x094d,0x0}, {0xF7DE,0x0} }, /* ta + halant + ta -> */ { {0x0924,0x094d,0x0924,0x0}, {0xF7DF,0x093E,0x0} }, /* ta + halant + ta + halant -> */ { {0x0924,0x094d,0x0924,0x094d,0x0}, {0xF7DF,0x0} }, /* tha 4 */ /* tha */ { {0x0925,0x0}, {0x0925,0x0} }, /* tha + halant -> half tha */ { {0x0925,0x094d,0x0}, {0xF7E0,0x0} }, /* tha + halant + ra -> */ { {0x0925,0x094d,0x0930,0x0}, {0xF7E1,0x093E,0x0} }, /* tha + halant + ra + halant -> */ { {0x0925,0x094d,0x0930,0x094d,0x0}, {0xF7E1,0x0} }, /* da 1 */ /* da -> da + kern space */ { {0x0926,0x0}, {0x0926,0xF839,0x0} }, /* da + halant -> half da + kern space */ { {0x0926,0x094d,0x0}, {0x0926,0x094d,0xF839,0x0} }, /* da ri 1 */ /* da + ru -> da + ru + kern space */ { {0x0926,0x0943,0x0}, {0xF7E2,0xF839,0x0} }, /* da halant ra 1 */ /* da + halant + ra -> dra + kern space */ { {0x0926,0x094d,0x0930,0x0}, {0xF7E3,0xF839,0x0} }, { {0x0926,0x094d,0x0930,0x094d,0x0}, {0xF7E3,0x094d,0xF839,0x0} }, { {0x0926,0x094d,0x0918,0x0}, {0xF848,0xF839,0x0} }, /* da halant da 1 */ /* da + halant + da -> + kern space */ { {0x0926,0x094d,0x0926,0x0}, {0xF7E4,0xF839,0x0} }, /* da halant dha 1 */ /* da + halant + dha -> + kern space */ { {0x0926,0x094d,0x0927,0x0}, {0xF7E5,0xF839,0x0} }, { {0x0926,0x094d,0x092c,0x0}, {0xF849,0xF839,0x0} }, { {0x0926,0x094d,0x092d,0x0}, {0xF844,0xF839,0x0} }, /* da halant ma 1 */ /* da + halant + ma -> + kern space */ { {0x0926,0x094d,0x092e,0x0}, {0xF7E6,0xF839,0x0} }, /* da halant ya 1 */ /* da + halant + ya -> + kern space */ { {0x0926,0x094d,0x092f,0x0}, {0xF7E7,0xF839,0x0} }, /* da halant va 1 */ /* da + halant + va -> + kern space */ { {0x0926,0x094d,0x0935,0x0}, {0xF7E8,0xF839,0x0} }, /* dha 4 */ /* Dha */ { {0x0927,0x0}, {0x0927,0x0} }, /* Dha + halant - > half Dha */ { {0x0927,0x094d,0x0}, {0xF7E9,0x0} }, /* Dha + halant + ra -> half Dhra */ { {0x0927,0x094d,0x0930,0x0}, {0xF7EA,0x093E,0x0} }, /* Dha + halant + ra + halant -> */ { {0x0927,0x094d,0x0930,0x094d,0x0}, {0xF7EA,0x0} }, /* na 6 */ /* na */ { {0x0928,0x0}, {0x0928,0x0} }, /* na + halant -> half na */ { {0x0928,0x094d,0x0}, {0xF7EB,0x0} }, /* na + halant + ra -> */ { {0x0928,0x094d,0x0930,0x0}, {0xF7EC,0x093E,0x0} }, /* na + halant + ra + halant -> */ { {0x0928,0x094d,0x0930,0x094d,0x0}, {0xF7EC,0x0} }, /* na + halant + na -> */ { {0x0928,0x094d,0x0928,0x0}, {0xF7ED,0x093E,0x0} }, /* na + halant + na + halant -> */ { {0x0928,0x094d,0x0928,0x094d,0x0}, {0xF7ED,0x0} }, { {0x0929,0x0}, {0x0929,0x0} }, /* pa 4 */ /* pa */ { {0x092a,0x0}, {0x092a,0x0} }, /* pa + halant -> half pa */ { {0x092a,0x094d,0x0}, {0xF7EE,0x0} }, /* pa + halant +ra -> pra */ { {0x092a,0x094d,0x0930,0x0}, {0xF7EF,0x093E,0x0} }, /* pa + halant + ra + halant -> half pra */ { {0x092a,0x094d,0x0930,0x094d,0x0}, {0xF7EF,0x0} }, /* pha 5 */ /* pha -> pha + kern space */ { {0x092b,0x0 }, {0x092b,0xF832,0x0} }, /* pha + halant -> half pha */ { {0x092b,0x094d,0x0}, {0xF7F0,0x0} }, /* pha nukta -> pha nukta + kern space */ { {0x092b,0x093c,0x0}, {0x095e,0xF832,0x0} }, /* pha nukta + halant-> half pha nukta */ { {0x092b,0x093c,0x094d,0x0}, {0xF7F1,0x0} }, /* pha + halant + ra -> fra + kern space */ { {0x092b,0x094d,0x0930,0x0}, {0xF7F5,0xF832,0x0} }, /* pha + halant + ra -> fra + kern space */ { {0x092b,0x094d,0x0930,0x094d,0x0}, {0xF7F5,0xF832,0x094d,0x0} }, /* ba 4 */ /* ba */ { {0x092c,0x0}, {0x092c,0x0} }, /* ba + halant -> half ba */ { {0x092c,0x094d,0x0}, {0xF7F6,0x0} }, /* ba + halant + ra -> */ { {0x092c,0x094d,0x0930,0x0}, {0xF7F7,0x093E,0x0} }, /* ba + halant ra + halant -> */ { {0x092c,0x094d,0x0930,0x094d,0x0}, {0xF7F7,0x0} }, /* bha 4 */ /* bha */ { {0x092d,0x0}, {0x092d,0x0} }, /* bha + halant -> half halant */ { {0x092d,0x094d,0x0}, {0xF7F8,0x0} }, /* bha + halant + ra -> */ { {0x092d,0x094d,0x0930,0x0}, {0xF7F9,0x093E,0x0} }, /* bha + halant + ra + halant -> */ { {0x092d,0x094d,0x0930,0x094d,0x0}, {0xF7F9,0x0} }, /* ma 4 */ /* ma */ { {0x092e,0x0}, {0x092e,0x0} }, /* ma + halant -> half ma */ { {0x092e,0x094d,0x0}, {0xF7FA,0x0} }, /* ma + halant + ra -> */ { {0x092e,0x094d,0x0930,0x0}, {0xF7FB,0x093E,0x0} }, /* ma + halant + ra + halant -> */ { {0x092e,0x094d,0x0930,0x094d,0x0}, {0xF7FB,0x0} }, /* ya 4 */ /* ya */ { {0x092f,0x0}, {0x092f,0x0} }, /* ya + halant -> half ya */ { {0x092f,0x094d,0x0}, {0xF7FC,0x0} }, /* ya + halant + ra -> */ { {0x092f,0x094d,0x0930,0x0}, {0xF7FD,0x093E,0x0} }, /* ya + halant + ra + halant -> */ { {0x092f,0x094d,0x0930,0x094d,0x0}, {0xF7FD,0x0} }, /* ra 3 */ /* ra */ { {0x0930,0x0 }, {0x0930,0xF83A,0x0} }, /* { {0x0930,0x094d,0x0}, {0xF812,0x0} }, */ /* ra + u -> Ru + kern space */ { {0x0930,0x0941,0x0}, {0xF800,0xF83B,0x0} }, /* ra + U -> RU + kern space */ { {0x0930,0x0942,0x0}, {0xF801,0xF83C,0x0} }, { {0x0931,0x0}, {0x0931,0x0} }, { {0x0931,0x094d,0x0}, {0xF7FF,0x0} }, /* la 2 */ /* la */ { {0x0932,0x0}, {0x0932,0x0} }, /* la + halant -> */ { {0x0932,0x094d,0x0}, {0xF802,0x0} }, /* La 2 */ /* La */ { {0x0933,0x0}, {0x0933,0x0} }, /* La + halant -> half La */ { {0x0933,0x094d,0x0}, {0xF803,0x0} }, { {0x0934,0x0} , {0x0934,0x0} }, /* va 4 */ /* va */ { {0x0935,0x0}, {0x0935,0x0} }, /* va + halant -> half va */ { {0x0935,0x094d,0x0}, {0xF804,0x0} }, /* va + halant + ra -> */ { {0x0935,0x094d,0x0930,0x0}, {0xF805,0x093E,0x0} }, /* va + halant + ra + halant -> */ { {0x0935,0x094d,0x0930,0x094d,0x0}, {0xF805,0x0} }, /* sha 6 */ /* sha */ { {0x0936,0x0}, {0x0936,0x0} }, /* sha + halant -> half sha */ { {0x0936,0x094d,0x0}, {0xF806,0x0} }, { {0x0936,0x094d,0x091a,0x0}, {0xF83F,0x0} }, { {0x0936,0x094d,0x0928,0x0}, {0xF840,0x0} }, /* sha + halant + va -> shwa */ { {0x0936,0x094d,0x0935,0x0}, {0xF807,0x093E,0x0} }, /* sha + halant + va + halant -> half shwa */ { {0x0936,0x094d,0x0935,0x094d,0x0}, {0xF807,0x0} }, /* sha + halant + ra -> shra */ { {0x0936,0x094d,0x0930,0x0}, {0xF808,0x093E,0x0} }, /* sha + halant + ra + halant -> half shra */ { {0x0936,0x094d,0x0930,0x094d,0x0}, {0xF808,0x0} }, /* SHa 2 */ /* SHa */ { {0x0937,0x0}, {0x0937,0x0} }, /* SHa + halant -> half SHa */ { {0x0937,0x094d,0x0}, {0xF809,0x0} }, { {0x0937,0x094d,0x091f,0x0}, {0xF841,0xF835,0x0} }, { {0x0937,0x094d,0x0920,0x0}, {0xF842,0xF836,0x0} }, /* sa 4 */ /* sa */ { {0x0938,0x0}, {0x0938,0x0} }, /* sa + halant -> half sa */ { {0x0938,0x094d,0x0}, {0xF80A,0x0} }, /* sa + halant + ra -> */ { {0x0938,0x094d,0x0930,0x0}, {0xF80B,0x093E,0x0} }, /* sa + halan + ra + halant -> */ { {0x0938,0x094d,0x0930,0x094d,0x0}, {0xF80B,0x0} }, { {0x0938,0x094d,0x0924,0x094d,0x0930,0x0}, {0xF843,0x0} }, /* ha 2 */ /* ha + kern space */ { {0x0939,0x0}, {0x0939,0xF83E,0x0} }, /* ha + halant -> half ha */ { {0x0939,0x094d,0x0}, {0xF80C,0xF83E,0x0} }, /* ha + Rii + matra -> */ { {0x0939,0x0943,0x0}, {0xF80D,0xF83E,0x0} }, /* ha + halant + ra -> */ { {0x0939,0x094d,0x0930,0x0}, {0xF80E,0xF83E,0x0} }, /* ha + halant + ra + halant -> */ { {0x0939,0x094d,0x0930,0x094d,0x0}, {0xF80E,0x094d,0xF83E,0x0} }, { {0x0939,0x094d,0x0923,0x0}, {0xF84D,0xF83E,0x0} }, { {0x0939,0x094d,0x0928,0x0}, {0xF84C,0xF83E,0x0} }, /* ha + halant + ma -> */ { {0x0939,0x094d,0x092e,0x0}, {0xF80F,0xF83E,0x0} }, /* ha + halant + ya -> */ { {0x0939,0x094d,0x092f,0x0}, {0xF810,0xF83E,0x0} }, { {0x0939,0x094d,0x0932,0x0}, {0xF84A,0xF83E,0x0} }, { {0x0939,0x094d,0x0935,0x0}, {0xF84B,0xF83E,0x0} }, { {0x0958,0x0}, {0x0958,0xF832,0x0} }, { {0x0959,0x0}, {0x0959,0x0} }, { {0x095a,0x0}, {0x095a,0x0} }, { {0x095b,0x0}, {0x095b,0x0} }, { {0x095c,0x0}, {0x095c,0xF837,0x0} }, { {0x095d,0x0}, {0x095d,0xF838,0x0} }, { {0x095e,0x0}, {0x095e,0xF832,0x0} }, { {0x095f,0x0}, {0x095f,0x0} }, /*"\xd8\x", "", */ /* misc 5 */ /* nukta */ { {0x093c,0x0}, {0x093c,0x0} }, /* nukta + u matra */ { {0x093c,0x0941,0x0}, {0xF81E,0x0} }, /* nukta + Uu matra -> */ { {0x093c,0x0942,0x0}, {0xF821,0x0} }, /* halant */ { {0x094d,0x0}, {0x094d,0x0} }, /* halant + ya -> */ { {0x094d,0x092f,0x0}, {0xF7FE,0x0} }, /* halant + ra */ { {0x094d,0x0930,0x0}, {0xF811,0x0} }, /* halant + ra + halant */ { {0x094d,0x0930,0x094d,0x0}, {0x094d,0x0930,0x0930,0x0} }, /* halant + ra + u matra -> */ { {0x094d,0x0930,0x0941,0x0}, {0xF81F,0x0} }, /* halant + ra + Uu matra -> */ { {0x094d,0x0930,0x0942,0x0}, {0xF822,0x0} }, /* Vedic Characters */ { {0x093d,0x0}, {0x093d,0x0} }, { {0x0950,0x0}, {0x0950,0x0} }, { {0x0951,0x0}, {0x0951,0x0} }, { {0x0952,0x0}, {0x0952,0x0} }, { {0x0953,0x0}, {0x0953,0x0} }, { {0x0954,0x0}, {0x0954,0x0} }, { {0x0964,0x0}, {0x0964,0x0} }, { {0x0965,0x0}, {0x0965,0x0} }, { {0x0970,0x0}, {0x0970,0x0} }, /* Dig09its */ { {0x0966,0x0}, {0x0966,0x0} }, { {0x0967,0x0}, {0x0967,0x0} }, { {0x0968,0x0}, {0x0968,0x0} }, { {0x0969,0x0}, {0x0969,0x0} }, { {0x096a,0x0}, {0x096a,0x0} }, { {0x096b,0x0}, {0x096b,0x0} }, { {0x096c,0x0}, {0x096c,0x0} }, { {0x096d,0x0}, {0x096d,0x0} }, { {0x096e,0x0}, {0x096e,0x0} }, { {0x096f,0x0}, {0x096f,0x0} } }; /* Returns a structure with information we will use to render given the * #PangoliteFont. This is computed once per font and cached for retrieval. */ static DvngFontInfo * get_font_info(const char *fontCharset) { static const char *charsets[] = { "sun.unicode.india-0", }; static const int charset_types[] = { DVNG_FONT_SUN }; DvngFontInfo *font_info = g_new(DvngFontInfo, 1); guint i; font_info->type = DVNG_FONT_NONE; for (i = 0; i < G_N_ELEMENTS(charsets); i++) { if (strcmp(fontCharset, charsets[i]) == 0) { font_info->type = (DvngFontType)charset_types[i]; font_info->subfont = (PangoliteXSubfont)i; break; } } return font_info; } static void add_glyph(PangoliteGlyphString *glyphs, 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].is_cluster_start = combining; glyphs->log_clusters[index] = clusterStart; } static void GetBaseConsGlyphs(gunichar2 *cluster, gint numCoreCons, PangoliteGlyph *glyphList, gint *nGlyphs) { int i, j, delta, nMin, nMaxRuleCt, ruleIdx; gboolean StillMatching; gunichar2 temp_out; gint tmpCt = *nGlyphs; i = 0; while (i < numCoreCons) { nMaxRuleCt = GetDvngRuleCt(cluster[i]); while (nMaxRuleCt) { nMin = MIN(nMaxRuleCt, numCoreCons); ruleIdx = 0; NotFound: j = delta = 0; StillMatching = FALSE; while (((delta < nMin) || sunGlyphTbl[ruleIdx].ISCII[j]) && (ruleIdx < MAP_SIZE) ) { StillMatching = TRUE; if ((delta < nMin) && (j < MAX_CORE_CONS) && (cluster[i + delta] != sunGlyphTbl[ruleIdx].ISCII[j])) { ruleIdx++; goto NotFound; } delta++; j++; } if (StillMatching) /* Found */ break; else nMaxRuleCt--; } i += nMin; /* Can't find entry in the table */ if ((StillMatching == FALSE) || (ruleIdx >= MAP_SIZE)) { for (j = 0; j < numCoreCons; j++) glyphList[tmpCt++] = PANGO_MOZ_MAKE_GLYPH(cluster[j]); } else if (((tmpCt > 0) && IsKern(glyphList[tmpCt - 1])) && IsMatraAtStem(sunGlyphTbl[ruleIdx].ISFOC[0])) { temp_out = glyphList[tmpCt - 1]; for (j=0; sunGlyphTbl[ruleIdx].ISFOC[j]; j++) glyphList[tmpCt - 1] = PANGO_MOZ_MAKE_GLYPH(sunGlyphTbl[ruleIdx].ISFOC[j]); glyphList[tmpCt++] = PANGO_MOZ_MAKE_GLYPH(temp_out); } else { for (j=0; sunGlyphTbl[ruleIdx].ISFOC[j]; j++) glyphList[tmpCt++] = PANGO_MOZ_MAKE_GLYPH(sunGlyphTbl[ruleIdx].ISFOC[j]); } } *nGlyphs = tmpCt; } static gint get_adjusted_glyphs_list(DvngFontInfo *fontInfo, gunichar2 *cluster, gint nChars, PangoliteGlyph *gLst, StateType *DvngClusterState) { int i, k, len; gint nGlyphs = 0; gunichar2 dummy; switch (*DvngClusterState) { case St1: if (IsDvngCharCls(cluster[0], _IM)) { GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF7C0); } else { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF7C0); GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); } break; case St2: case St3: case St4: case St5: case St6: GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); break; case St7: if (IsDvngCharCls(cluster[nChars - 1], _UP)) { if (IsDvngCharCls(cluster[nChars - 2], _RM)) GetBaseConsGlyphs(cluster, nChars - 2, gLst, &nGlyphs); else GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); if (IsDvngCharCls(cluster[nChars - 2], _RM)) { if (IsDvngCharCls(cluster[nChars - 2], _II_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF81B); else if (IsDvngCharCls(cluster[nChars - 2], _AYE_M)) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(0xF82D); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else if (IsDvngCharCls(cluster[nChars - 2], _EE_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF824); else if (IsDvngCharCls(cluster[nChars - 2], _EY_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF827); else if (IsDvngCharCls(cluster[nChars - 2], _AI_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82A); else if (IsDvngCharCls(cluster[nChars - 2], _AWE_M)) { 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], _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 { GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); } break; case St8: GetBaseConsGlyphs(cluster, nChars - 1, gLst, &nGlyphs); if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(cluster[nChars - 1]); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(cluster[nChars - 1]); break; case St9: if (IsDvngCharCls(cluster[0], _MS)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093F); else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF817); GetBaseConsGlyphs(cluster, nChars - 1, gLst, &nGlyphs); break; case St10: if (IsDvngCharCls(cluster[0], _MS)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF814); else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF818); GetBaseConsGlyphs(cluster, nChars - 2, gLst, &nGlyphs); break; case St11: GetBaseConsGlyphs(cluster, nChars, gLst, &nGlyphs); break; case St12: gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x0930); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF83A); break; case St13: gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x0930); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x094D); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF83A); break; case St14: GetBaseConsGlyphs(cluster+2, nChars - 2, gLst, &nGlyphs); if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(0xF812); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF812); break; case St15: GetBaseConsGlyphs(cluster+2, nChars - 3, gLst, &nGlyphs); if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 2]; gLst[nGlyphs - 2] = PANGO_MOZ_MAKE_GLYPH(0xF812); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x094D); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF812); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x094D); } break; case St16: if (IsDvngCharCls(cluster[nChars - 1], _RM)) GetBaseConsGlyphs(cluster+2, nChars - 3, gLst, &nGlyphs); else GetBaseConsGlyphs(cluster+2, nChars - 2, gLst, &nGlyphs); if (IsDvngCharCls(cluster[nChars - 1], ~(_RM))){ if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(0xF812); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF812); } else { if (IsDvngCharCls(cluster[nChars - 1], _II_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF81C); else if (IsDvngCharCls(cluster[nChars - 1], _EY_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF828); else if (IsDvngCharCls(cluster[nChars -1], _AI_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82B); else if (IsDvngCharCls(cluster[nChars - 1], _OW1_M)) { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF828); } else if (IsDvngCharCls(cluster[nChars - 1], _OW2_M)) { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82B); } } break; case St17: if (IsDvngCharCls(cluster[nChars - 1], _UP)) { if (IsDvngCharCls(cluster[nChars - 2], _RM)) GetBaseConsGlyphs(cluster+2, nChars - 4, gLst, &nGlyphs); else GetBaseConsGlyphs(cluster+2, nChars - 3, gLst, &nGlyphs); if (IsDvngCharCls(cluster[nChars - 2], ~(_RM))) { if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(0xF813); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF813); } else { if (IsDvngCharCls(cluster[nChars - 2], _II_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF81D); else if (IsDvngCharCls(cluster[nChars - 2], _EY_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF829); else if (IsDvngCharCls(cluster[nChars - 2], _AI_M)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82C); else if (IsDvngCharCls(cluster[nChars - 2], _OW1_M)) { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF829); } else if (IsDvngCharCls(cluster[nChars - 2], _OW2_M)) { gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0x093E); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF82C); } } /* ? else GetBaseConsGlyphs(); */ break; case St18: GetBaseConsGlyphs(cluster-2, nChars-3, gLst, &nGlyphs); if (IsKern(gLst[nGlyphs - 1])) { dummy = gLst[nGlyphs - 1]; gLst[nGlyphs - 1] = PANGO_MOZ_MAKE_GLYPH(0xF813); gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(dummy); } else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF813); break; case St19: if (IsDvngCharCls(cluster[0], _MS)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF815); else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF819); GetBaseConsGlyphs(cluster+2, nChars-3, gLst, &nGlyphs); break; case St20: if (IsDvngCharCls(cluster[0], _MS)) gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF816); else gLst[nGlyphs++] = PANGO_MOZ_MAKE_GLYPH(0xF81A); GetBaseConsGlyphs(cluster+2, nChars - 4, gLst, &nGlyphs); break; } } return nGlyphs; } static gint get_glyphs_list(DvngFontInfo *fontInfo, gunichar2 *cluster, gint numChars, PangoliteGlyph *glyphLst, StateType *clustState) { PangoliteGlyph glyph; gint i; switch (fontInfo->type) { case DVNG_FONT_NONE: for (i = 0; i < numChars; i++) glyphLst[i] = 0; /*pangolite_x_get_unknown_glyph(fontInfo->font);*/ return numChars; case DVNG_FONT_SUN: return get_adjusted_glyphs_list(fontInfo, cluster, numChars, glyphLst, clustState); } return 0; /* Quiet GCC */ } static void add_cluster(DvngFontInfo *fontInfo, PangoliteGlyphString *glyphs, gint clusterBeg, gunichar2 *cluster, gint numChars, StateType *clustState) { PangoliteGlyph glyphsList[MAX_GLYPHS]; gint i, numGlyphs, ClusterStart=0; numGlyphs = get_glyphs_list(fontInfo, cluster, numChars, glyphsList, clustState); 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 * get_next_cluster(const gunichar2 *text, gint length, gunichar2 *cluster, gint *numChars, StateType *clustState) { const gunichar2 *p; gint n_chars = 0; StateType aSt = *clustState; p = text; while (p < text + length) { gunichar2 cur = *p; if ((n_chars == 0) || ((n_chars > 0) && IsComposible(cluster[n_chars - 1], cur))) { cluster[n_chars++] = cur; aSt = SetClusterState(aSt, cur); p++; } else break; } *numChars = n_chars; *clustState = aSt; return p; } static void dvng_engine_shape(const char *fontCharset, const gunichar2 *text, gint length, PangoliteAnalysis *analysis, PangoliteGlyphString *glyphs) { DvngFontInfo *fontInfo; const gunichar2 *p, *log_cluster; gunichar2 cluster[MAX_CLUSTER_CHRS]; gint num_chrs; StateType aSt = St0; fontInfo = get_font_info(fontCharset); p = text; while (p < text + length) { log_cluster = p; aSt = St0; p = get_next_cluster(p, text + length - p, cluster, &num_chrs, &aSt); add_cluster(fontInfo, glyphs, log_cluster-text, cluster, num_chrs, &aSt); } } static PangoliteCoverage * dvng_engine_get_coverage(const char *fontCharset, const char *lang) { PangoliteCoverage *result = pangolite_coverage_new (); DvngFontInfo *fontInfo = get_font_info (fontCharset); if (fontInfo->type != DVNG_FONT_NONE) { gunichar2 wc; for (wc = 0x901; wc <= 0x903; wc++) pangolite_coverage_set (result, wc, PANGO_COVERAGE_EXACT); for (wc = 0x905; wc <= 0x939; wc++) pangolite_coverage_set (result, wc, PANGO_COVERAGE_EXACT); for (wc = 0x93c; wc <= 0x94d; wc++) pangolite_coverage_set (result, wc, PANGO_COVERAGE_EXACT); for (wc = 0x950; wc <= 0x954; wc++) pangolite_coverage_set (result, wc, PANGO_COVERAGE_EXACT); for (wc = 0x958; wc <= 0x970; wc++) pangolite_coverage_set (result, wc, PANGO_COVERAGE_EXACT); /* pangolite_coverage_set (result, ZWJ, PANGO_COVERAGE_EXACT); */ } return result; } static PangoliteEngine * dvng_engine_x_new () { PangoliteEngineShape *result; result = g_new (PangoliteEngineShape, 1); result->engine.id = SCRIPT_ENGINE_NAME; result->engine.type = PANGO_ENGINE_TYPE_SHAPE; result->engine.length = sizeof (result); result->script_shape = dvng_engine_shape; result->get_coverage = dvng_engine_get_coverage; return (PangoliteEngine *)result; } /* The following three functions provide the public module API for * Pangolite. If we are compiling it is a module, then we name the * entry points script_engine_list, etc. But if we are compiling * it for inclusion directly in Pangolite, then we need them to * to have distinct names for this module, so we prepend * _pangolite_thai_x_ */ #ifdef X_MODULE_PREFIX #define MODULE_ENTRY(func) _pangolite_dvng_x_##func #else #define MODULE_ENTRY(func) func #endif /* List the engines contained within this module */ void MODULE_ENTRY(script_engine_list) (PangoliteEngineInfo **engines, gint *n_engines) { *engines = script_engines; *n_engines = G_N_ELEMENTS (script_engines); } /* Load a particular engine given the ID for the engine */ PangoliteEngine * MODULE_ENTRY(script_engine_load) (const char *id) { if (!strcmp (id, SCRIPT_ENGINE_NAME)) return dvng_engine_x_new (); else return NULL; } void MODULE_ENTRY(script_engine_unload) (PangoliteEngine *engine) { }