bug 84380 Need a component that generates thai presentation forms

Updates for *extensions*/ctl for prabhat@Sun, r=ftank for check-in
A Incorporate frank's review fixes (08/07)
B Bugfix in TIS620Encoder
C Fix memory corruption
D Makefile changes in pangoLite directory to install pango.modules
This commit is contained in:
katakai%japan.sun.com 2001-09-18 10:14:38 +00:00
Родитель 950999845c
Коммит a6c2d2710d
12 изменённых файлов: 106 добавлений и 1479 удалений

Просмотреть файл

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* XPCTL : nsILE.h
*
* 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) 2000 SUN
* Microsystems, Inc. All Rights Reserved.
*
* This module 'XPCTL Interface' is based on Pango (www.pango.org)
* by Red Hat Software. Portions created by Redhat are Copyright (C)
* 1999 Red Hat Software.
*
* Contributor(s):
*/
#ifndef nsILE_h__
#define nsILE_h__
#include "nscore.h"
#include "nsISupports.h"
#include "nsCtlCIID.h"
#include "pango-types.h"
#include "pango-glyph.h"
/*
* nsILE Interface declaration
*/
class nsILE : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILE_IID)
NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32, PangoAnalysis*,
PangoGlyphString*) = 0;
NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32,
const char*, char*, PRSize*) = 0;
NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32,
const char*, PRUint32*, PRSize*) = 0;
};
#endif // nsILE_h

Просмотреть файл

@ -46,14 +46,14 @@ PRInt32 g_InstanceCount = 0;
PRInt32 g_LockCount = 0;
NS_IMPL_NSUCONVERTERREGSELF
NS_UCONV_REG_UNREG(nsUnicodeToTIS620, "Unicode", "tis620", NS_UNICODETOTIS620_CID);
NS_UCONV_REG_UNREG(nsUnicodeToTIS620, "Unicode", "tis620-2", NS_UNICODETOTIS620_CID);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToTIS620);
static nsModuleComponentInfo components[] =
{
{ ENCODER_NAME_BASE "tis620" , NS_UNICODETOTIS620_CID,
NS_UNICODEENCODER_CONTRACTID_BASE "tis620",
{ ENCODER_NAME_BASE "tis620-2" , NS_UNICODETOTIS620_CID,
NS_UNICODEENCODER_CONTRACTID_BASE "tis620-2",
nsUnicodeToTIS620Constructor,
nsUnicodeToTIS620RegSelf, nsUnicodeToTIS620UnRegSelf },
{ "Unicode Layout Engine", NS_ULE_CID, NS_ULE_PROGID,

Просмотреть файл

@ -1,200 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* XPCTL : nsULE.cpp
*
* 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) 2000 SUN
* Microsystems, Inc. All Rights Reserved.
*
* This module 'XPCTL Interface' is based on Pango (www.pango.org)
* by Red Hat Software. Portions created by Redhat are Copyright (C)
* 1999 Red Hat Software.
*
* Contributor(s):
*/
#include <stdio.h>
#include <ctype.h> /* isspace */
#include "nsULE.h"
#include "nsString.h"
#include "pango-types.h"
#include "pango-glyph.h"
#include "pango-modules.h"
#include "pango-utils.h"
/*
* Start of nsULE Public Functions
*/
nsULE::nsULE() {
NS_INIT_ISUPPORTS(); // For Reference Counting
}
nsULE::~nsULE() {
// No data to cleanup.
}
NS_IMPL_ISUPPORTS1(nsULE, nsILE);
/* Caller needs to ensure that GetEngine is called with valid state */
PangoEngineShape*
nsULE::GetShaper(const PRUnichar *inBuf,
PRUint32 aLength,
const char *lang)
{
PangoEngineShape *aEngine = NULL;
PangoMap *aMap = NULL;
guint engine_type_id = 0, render_type_id = 0;
PRUnichar wc = inBuf[0];
if ((inBuf == (PRUnichar*)NULL) || (aLength <= 0)) {
aEngine = (PangoEngineShape*)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 = pango_find_map("en_US", engine_type_id, render_type_id);
aEngine = (PangoEngineShape*)pango_map_get_engine(aMap, (PRUint32)wc);
}
return aEngine;
}
// Analysis needs to have valid direction and font charset
NS_IMETHODIMP
nsULE::GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
PangoAnalysis *aAnalysis,
PangoGlyphString *aGlyphs)
{
PangoEngineShape *aShaper = aAnalysis->shape_engine;
PRSize inLen = 0;
char *utf8Str = NULL;
if (aShaper != NULL) {
nsAutoString strBuf(aString);
// Convert Unicode string to UTF8 and store in buffer
utf8Str = strBuf.ToNewUTF8String();
inLen = strlen(utf8Str);
aShaper->script_shape(aAnalysis->fontCharset, utf8Str, inLen,
aAnalysis, aGlyphs);
nsMemory::Free(utf8Str);
}
else {
/* No Shaper - Copy Input to output */
}
return NS_OK;
}
NS_IMETHODIMP
nsULE::GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
char *aGlyphs,
PRSize *aOutLength)
{
PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL);
PangoAnalysis aAnalysis;
PangoGlyphString *tmpGlyphs = pango_glyph_string_new();
PRSize inLen = 0;
int aSize = 0;
char *utf8Str = NULL;
aAnalysis.shape_engine = aShaper;
aAnalysis.aDir = PANGO_DIRECTION_LTR;
aAnalysis.fontCharset = (char*)fontCharset;
if (aShaper != NULL) {
nsAutoString strBuf;
strBuf.Assign(aString, aLength);
// Convert Unicode string to UTF8 and store in buffer
utf8Str = NULL;
utf8Str = strBuf.ToNewUTF8String();
inLen = strlen(utf8Str);
aShaper->script_shape(fontCharset, utf8Str, inLen,
&aAnalysis, tmpGlyphs);
nsMemory::Free(utf8Str);
if (tmpGlyphs->num_glyphs > 0) {
// Note : Does NOT handle 2 byte fonts
aSize = tmpGlyphs->num_glyphs;
// if (*aOutLength < aSize)
// trouble
for (int i = 0; i < aSize; i++)
aGlyphs[i] = tmpGlyphs->glyphs[i].glyph & 0xFF;
}
*aOutLength = (PRSize)aSize;
}
else {
/* No Shaper - Copy Input to output */
}
return NS_OK;
}
NS_IMETHODIMP
nsULE::GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
PRUint32 *aGlyphs,
PRSize *aOutLength)
{
PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL);
PangoAnalysis aAnalysis;
PangoGlyphString *tmpGlyphs = pango_glyph_string_new();
PRSize inLen = 0;
int aSize = 0;
char *utf8Str = NULL;
aAnalysis.shape_engine = aShaper;
aAnalysis.aDir = PANGO_DIRECTION_LTR;
aAnalysis.fontCharset = (char*)fontCharset;
if (aShaper != NULL) {
nsAutoString strBuf;
strBuf.Assign(aString, aLength);
// Convert Unicode string to UTF8 and store in buffer
utf8Str = NULL;
utf8Str = strBuf.ToNewUTF8String();
inLen = strlen(utf8Str);
aShaper->script_shape(fontCharset, utf8Str, inLen,
&aAnalysis, tmpGlyphs);
nsMemory::Free(utf8Str);
if (tmpGlyphs->num_glyphs > 0) {
aSize = tmpGlyphs->num_glyphs;
// if (*aOutLength < aSize)
// trouble
for (int i = 0; i < aSize; i++)
aGlyphs[i] = tmpGlyphs->glyphs[i].glyph;
}
*aOutLength = (PRSize)aSize;
}
else {
// Should not reach here are checks are set
// in upper layers
/* Alternately, if no Shaper - Copy Input to output */
}
return NS_OK;
}

Просмотреть файл

@ -1,75 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* XPCTL : nsULE.h
*
* 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) 2000 SUN
* Microsystems, Inc. All Rights Reserved.
*
* This module 'XPCTL Interface' is based on Pango (www.pango.org)
* by Red Hat Software. Portions created by Redhat are Copyright (C)
* 1999 Red Hat Software.
*
* Contributor(s):
*/
#ifndef nsULE_H
#define nsULE_H
#include "nscore.h"
#include "prtypes.h"
#include "nsCtlCIID.h"
#include "nsILE.h"
/* Class nsULE : Declaration */
class nsULE : public nsILE {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ULE_IID)
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
// and selection
NS_IMETHOD GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
PangoAnalysis *aAnalysis,
PangoGlyphString *aGlyphs);
NS_IMETHOD GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
char *aGlyphs,
PRSize *aOutLength);
NS_IMETHOD GetPresentationForm(const PRUnichar *aString,
PRUint32 aLength,
const char *fontCharset,
PRUint32 *aGlyphs,
PRSize *aOutLength);
private:
// Housekeeping Members
void Init(void);
void CleanUp(void);
PangoEngineShape* GetShaper(const PRUnichar *, PRUint32, const char *);
};
#endif /* nsULE_H */

Просмотреть файл

@ -22,19 +22,24 @@
*
* Contributor(s):
*/
#include <stdio.h>
#include <ctype.h> /* isspace */
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsICharsetConverterManager2.h"
#include "nsILanguageAtomService.h"
#include "nsCtlCIID.h"
#include "nsILE.h"
#include "nsULE.h"
#include "nsUnicodeToTIS620.h"
static NS_DEFINE_CID(kCharSetManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
// XPCOM stuff
NS_IMPL_ADDREF(nsUnicodeToTIS620);
NS_IMPL_RELEASE(nsUnicodeToTIS620);
int
PRInt32
nsUnicodeToTIS620::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList)
{
int ct = 0, start = 0;
@ -78,14 +83,13 @@ nsUnicodeToTIS620::Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunLis
tmpChunk->length = ct - start;
}
return (int)aRunList->numRuns;
return (PRInt32)aRunList->numRuns;
}
nsresult nsUnicodeToTIS620::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
if (NULL == aInstancePtr)
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
@ -123,11 +127,28 @@ NS_IMETHODIMP nsUnicodeToTIS620::SetOutputErrorBehavior(PRInt32 aBehavior,
nsUnicodeToTIS620::nsUnicodeToTIS620()
{
static NS_DEFINE_CID(kLECID, NS_ULE_CID);
nsresult rv;
NS_INIT_REFCNT();
mCtlObj = do_CreateInstance(kLECID, &rv);
if (NS_FAILED(rv)) {
#ifdef DEBUG_prabhat
// No other error handling needed here since we
// handle absence of mCtlObj in Convert
printf("ERROR: Cannot create instance of component " NS_ULE_PROGID " [%x].\n",
rv);
#endif
NS_WARNING("Thai Text Layout Will Not Be Supported\n");
mCtlObj = nsnull;
}
}
nsUnicodeToTIS620::~nsUnicodeToTIS620()
{
// Maybe convert nsILE to a service
// No NS_IF_RELEASE(mCtlObj) of nsCOMPtr;
}
/*
@ -135,44 +156,74 @@ nsUnicodeToTIS620::~nsUnicodeToTIS620()
* Note: ConversionBufferFullException is not handled
* since this class is only used for character display.
*/
NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar * input,
PRInt32 * aSrcLength,
char * output, PRInt32 * aDestLength)
NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar* input,
PRInt32* aSrcLength,
char* output,
PRInt32* aDestLength)
{
int i = 0;
nsCOMPtr<nsILE> mCtlObj;
static NS_DEFINE_CID(kLECID, NS_ULE_CID);
nsresult rv;
textRunList txtRuns;
textRun *aPtr, *aTmpPtr;
textRunList txtRuns;
textRun *aPtr, *aTmpPtr;
#ifdef DEBUG_prabhath_no_shaper
printf("Debug/Test Case of No thai pango shaper Object\n");
// Comment out mCtlObj == nsnull for test purposes
#endif
if (mCtlObj == nsnull) {
nsICharsetConverterManager2* gCharSetManager = nsnull;
nsIUnicodeEncoder* gDefaultTISConverter = nsnull;
nsresult res;
nsServiceManager::GetService(kCharSetManagerCID,
NS_GET_IID(nsICharsetConverterManager2), (nsISupports**) &gCharSetManager);
// No question of starting the conversion from an offset
charOff = byteOff = 0;
#ifdef DEBUG_prabhath
printf("ERROR: No CTL IMPLEMENTATION - Default Thai Conversion");
// CP874 is the default converter for thai ;
// In case mCtlObj is absent (no CTL support), use it to convert.
#endif
mCtlObj = do_CreateInstance(kLECID, &rv);
if (NS_FAILED(rv)) {
printf("ERROR: Cannot create instance of component " NS_ULE_PROGID " [%x].\n",
rv);
printf("Thai Text Layout Will Not Be Supported\n");
if (!gCharSetManager)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAtom> charset = getter_AddRefs(NS_NewAtom("TIS-620"));
if (charset)
res = gCharSetManager->GetUnicodeEncoder(charset, &gDefaultTISConverter);
else {
NS_IF_RELEASE(gCharSetManager);
return NS_ERROR_FAILURE;
}
if (!gDefaultTISConverter) {
NS_WARNING("cannot get default converter for tis-620");
NS_IF_RELEASE(gCharSetManager);
return NS_ERROR_FAILURE;
}
gDefaultTISConverter->Convert(input, aSrcLength, output, aDestLength);
NS_IF_RELEASE(gCharSetManager);
NS_IF_RELEASE(gDefaultTISConverter);
return NS_OK;
}
txtRuns.numRuns = 0;
// CTLized shaping conversion starts here
// No question of starting the conversion from an offset
mCharOff = mByteOff = 0;
txtRuns.numRuns = 0;
Itemize(input, *aSrcLength, &txtRuns);
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
// char *tmpDestBuf = output + byteOff;
// PRInt32 tmpDestLen = *aDestLength - byteOff;
for (int i = 0; i < txtRuns.numRuns; i++) {
PRInt32 tmpSrcLen = aPtr->length;
if (aPtr->isOther) {
// PangoThaiShaper does not handle ASCII + thai in same shaper
for (i = 0; i < tmpSrcLen; i++)
output[i + byteOff] = (char)(*(aPtr->start + i));
byteOff += tmpSrcLen;
for (int j = 0; j < tmpSrcLen; j++)
output[j + mByteOff] = (char)(*(aPtr->start + j));
mByteOff += tmpSrcLen;
}
else {
PRSize outLen = *aDestLength;
PRSize outLen = *aDestLength - mByteOff;
// Charset tis620-0, tis620.2533-1, tis620.2529-1 & iso8859-11
// are equivalent and have the same presentation forms
@ -180,24 +231,21 @@ NS_IMETHODIMP nsUnicodeToTIS620::Convert(const PRUnichar * input,
// in Windows-Stye as it is the current defacto-standard for the
// presentation of thai content
mCtlObj->GetPresentationForm(aPtr->start, tmpSrcLen, "tis620-2",
output, &outLen);
byteOff += outLen;
&output[mByteOff], &outLen);
mByteOff += outLen;
}
aPtr = aPtr->next;
}
// Check for free nsILE or convert nsILE to a service
// NS_IF_RELEASE(mCtlObj);
// Cleanup Run Info;
aPtr = txtRuns.head;
for (i = 0; i < txtRuns.numRuns; i++) {
for (int i = 0; i < txtRuns.numRuns; i++) {
aTmpPtr = aPtr;
aPtr = aPtr->next;
delete aTmpPtr;
}
*aDestLength = byteOff;
*aDestLength = mByteOff;
return NS_OK;
}
@ -205,14 +253,14 @@ NS_IMETHODIMP nsUnicodeToTIS620::Finish(char * output, PRInt32 * aDestLength)
{
// Finish does'nt have to do much as Convert already flushes
// to output buffer
byteOff = charOff = 0;
mByteOff = mCharOff = 0;
return NS_OK;
}
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::Reset()
{
byteOff = charOff = 0;
mByteOff = mCharOff = 0;
return NS_OK;
}

Просмотреть файл

@ -35,18 +35,9 @@
#include "nsIUnicodeEncoder.h"
#include "nsICharRepresentable.h"
struct textRun {
PRInt32 length; /* Length of a chunk */
PRBool isOther; /* Outside the range */
const PRUnichar *start; /* Address of start offset */
struct textRun *next;
};
#include "nsILE.h"
typedef struct {
struct textRun *head;
struct textRun *cur;
PRInt32 numRuns;
} textRunList;
struct textRunList;
//----------------------------------------------------------------------
// Class nsUnicodeToTIS620 [declaration]
@ -80,12 +71,14 @@ public:
NS_IMETHOD FillInfo(PRUint32* aInfo);
private:
PRUint8 state;
PRInt32 byteOff;
PRInt32 charOff;
PRUint8 mState;
PRInt32 mByteOff;
PRInt32 mCharOff;
nsCOMPtr<nsILE> mCtlObj;
// beg and end denote ranges and may need to be expanded in the future to
// handle discontinous ranges
int Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList);
PRInt32 Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList);
};
#endif /* nsUnicodeToTIS620_h___ */

Просмотреть файл

@ -68,4 +68,6 @@ CXXFLAGS += $(GLIB_CFLAGS)
CFLAGS += $(GLIB_CFLAGS)
EXTRA_DSO_LDOPTS += $(GLIB_LIBS) -lgmodule
#DEFINES += -DSYSCONFDIR=\"$(sysconfdir)\"
# Install pango.modules file for Shaping Modules.
install::
$(INSTALL) $(srcdir)/pango.modules $(DIST)/bin

Просмотреть файл

@ -1,100 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-engine.h: Module handling
*
* 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 the Pango Library (www.pango.org)
*
* The Initial Developer of the Original Code is Red Hat Software
* Portions created by Red Hat are Copyright (C) 2000 Red Hat Software.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Lessor General Public License Version 2 (the
* "LGPL"), in which case the provisions of 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 the LGPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the LGPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* LGPL.
*/
#ifndef __PANGO_ENGINE_H__
#define __PANGO_ENGINE_H__
#include "pango-types.h"
#include "pango-glyph.h"
#include "pango-coverage.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Module API */
#define PANGO_ENGINE_TYPE_SHAPE "PangoEngineShape"
#define PANGO_RENDER_TYPE_X "PangoRenderX"
#define PANGO_RENDER_TYPE_NONE "PangoRenderNone"
typedef struct _PangoEngineInfo PangoEngineInfo;
typedef struct _PangoEngineRange PangoEngineRange;
typedef struct _PangoEngine PangoEngine;
struct _PangoEngineRange
{
guint32 start;
guint32 end;
gchar *langs;
};
struct _PangoEngineInfo
{
gchar *id;
gchar *engine_type;
gchar *render_type;
PangoEngineRange *ranges;
gint n_ranges;
};
struct _PangoEngine
{
gchar *id;
gchar *type;
gint length;
};
struct _PangoEngineShape
{
PangoEngine engine;
void (*script_shape) (const char *fontCharset,
const char *text,
int length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs);
PangoCoverage *(*get_coverage) (const char *fontCharset, const char *lang);
};
/* A module should export the following functions */
void script_engine_list(PangoEngineInfo **engines, int *n_engines);
PangoEngine *script_engine_load(const char *id);
void script_engine_unload(PangoEngine *engine);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_ENGINE_H__ */

Просмотреть файл

@ -1,116 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-glyph.h:
*
* 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 the Pango Library (www.pango.org)
*
* The Initial Developer of the Original Code is Red Hat Software
* Portions created by Red Hat are Copyright (C) 2000 Red Hat Software.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Lessor General Public License Version 2 (the
* "LGPL"), in which case the provisions of 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 the LGPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the LGPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* LGPL.
*/
#ifndef __PANGO_GLYPH_H__
#define __PANGO_GLYPH_H__
#include "pango-types.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _PangoGlyphVisAttr PangoGlyphVisAttr;
typedef struct _PangoGlyphInfo PangoGlyphInfo;
typedef struct _PangoGlyphString PangoGlyphString;
/* 1000ths of a device unit */
typedef gint32 PangoGlyphUnit;
/* Visual attributes of a glyph
*/
struct _PangoGlyphVisAttr
{
guint is_cluster_start : 1;
};
/* A single glyph
*/
struct _PangoGlyphInfo
{
PangoGlyph glyph;
PangoGlyphVisAttr attr;
};
/* A string of glyphs with positional information and visual attributes -
* ready for drawing
*/
struct _PangoGlyphString {
gint num_glyphs;
PangoGlyphInfo *glyphs;
/* This is a memory inefficient way of representing the information
* here - each value gives the byte index within the text
* corresponding to the glyph string of the start of the cluster to
* which the glyph belongs.
*/
gint *log_clusters;
/*< private >*/
gint space;
};
PangoGlyphString *pango_glyph_string_new(void);
void pango_glyph_string_set_size(PangoGlyphString *string, gint new_len);
void pango_glyph_string_free(PangoGlyphString *string);
void pango_glyph_string_index_to_x(PangoGlyphString *glyphs,
char *text,
int length,
PangoAnalysis *analysis,
int index,
gboolean trailing,
int *x_pos);
void pango_glyph_string_x_to_index(PangoGlyphString *glyphs,
char *text,
int length,
PangoAnalysis *analysis,
int x_pos,
int *index,
int *trailing);
/* Turn a string of characters into a string of glyphs */
void pango_shape(const char *text,
gint length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs);
GList *pango_reorder_items(GList *logical_items);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_GLYPH_H__ */

Просмотреть файл

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

Просмотреть файл

@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* shape.c: Convert characters into glyphs.
*
* 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 the Pango Library (www.pango.org)
*
* The Initial Developer of the Original Code is Red Hat Software
* Portions created by Red Hat are Copyright (C) 1999 Red Hat Software.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Lessor General Public License Version 2 (the
* "LGPL"), in which case the provisions of 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 the LGPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the LGPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* LGPL.
*/
#include "pango-glyph.h"
#include "pango-engine.h"
/**
* pango_shape:
* @text: the text to process
* @length: the length (in bytes) of @text
* @analysis: #PangoAnalysis structure from PangoItemize
* @glyphs: glyph string in which to store results
*
* Given a segment of text and the corresponding
* #PangoAnalysis structure returned from pango_itemize(),
* convert the characters into glyphs. You may also pass
* in only a substring of the item from pango_itemize().
*/
void pango_shape(const gchar *text,
gint length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
if (analysis->shape_engine)
analysis->shape_engine->script_shape(analysis->fontCharset, text, length,
analysis, glyphs);
else {
pango_glyph_string_set_size (glyphs, 1);
glyphs->glyphs[0].glyph = 0;
glyphs->log_clusters[0] = 0;
}
g_assert (glyphs->num_glyphs > 0);
}

Просмотреть файл

@ -1,811 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* thai-x.c:
*
* 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 the Pango Library (www.pango.org)
*
* The Initial Developer of the Original Code is Red Hat Software
* Portions created by Red Hat are Copyright (C) 1999 Red Hat Software.
*
* Contributor(s):
* Author: Owen Taylor <otaylor@redhat.com>
*
* Software and Language Engineering Laboratory, NECTEC
* Author: Theppitak Karoonboonyanan <thep@links.nectec.or.th>
*
* Copyright (c) 1996-2000 by Sun Microsystems, Inc.
* Author: Chookij Vanatham <Chookij.Vanatham@Eng.Sun.COM>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Lessor General Public License Version 2 (the
* "LGPL"), in which case the provisions of 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 the LGPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the LGPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* LGPL.
*/
#include <glib.h>
#include <string.h>
#include "pango-engine.h"
#include "pango-coverage.h"
#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
#define ucs2tis(wc) (unsigned int)((unsigned int)(wc) - 0x0E00 + 0xA0)
#define tis2uni(c) ((gunichar)(c) - 0xA0 + 0x0E00)
#define MAX_CLUSTER_CHRS 256
#define MAX_GLYPHS 256
/* Define TACTIS character classes */
#define CTRL 0
#define NON 1
#define CONS 2
#define LV 3
#define FV1 4
#define FV2 5
#define FV3 6
#define BV1 7
#define BV2 8
#define BD 9
#define TONE 10
#define AD1 11
#define AD2 12
#define AD3 13
#define AV1 14
#define AV2 15
#define AV3 16
#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 NoTailCons _NC
#define UpTailCons _UC
#define BotTailCons _BC
#define SpltTailCons _SC
#define Cons (NoTailCons|UpTailCons|BotTailCons|SpltTailCons)
#define AboveVowel _AV
#define BelowVowel _BV
#define Tone _TN
#define AboveDiac _AD
#define BelowDiac _BD
#define SaraAm _AM
#define char_class(wc) TAC_char_class[(unsigned int)(wc)]
#define is_char_type(wc, mask) (char_type_table[ucs2tis((wc))] & (mask))
#define SCRIPT_ENGINE_NAME "ThaiScriptEngineX"
#define PANGO_RENDER_TYPE_X "PangoRenderX"
typedef guint16 PangoXSubfont;
#define PANGO_MOZ_MAKE_GLYPH(index) ((guint32)0 | (index))
char g_utf8_skip[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,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
};
#define g_utf8_next_char(p) (char*)((p) + g_utf8_skip[*(unsigned char*)(p)])
/* We handle the range U+0e01 to U+0e5b exactly
*/
static PangoEngineRange thai_ranges[] = {
{ 0x0e01, 0x0e5b, "*" }, /* Thai */
};
static PangoEngineInfo script_engines[] = {
{
SCRIPT_ENGINE_NAME,
PANGO_ENGINE_TYPE_SHAPE,
PANGO_RENDER_TYPE_X,
thai_ranges,
G_N_ELEMENTS(thai_ranges)
}
};
/*
* X window system script engine portion
*/
typedef struct _ThaiFontInfo ThaiFontInfo;
/* The type of encoding that we will use
*/
typedef enum {
THAI_FONT_NONE,
THAI_FONT_XTIS,
THAI_FONT_TIS,
THAI_FONT_TIS_MAC,
THAI_FONT_TIS_WIN,
THAI_FONT_ISO10646
} ThaiFontType;
struct _ThaiFontInfo
{
ThaiFontType type;
PangoXSubfont subfont;
};
/* All combining marks for Thai fall in the range U+0E30-U+0E50,
* so we confine our data tables to that range, and use
* default values for characters outside those ranges.
*/
/* Map from code point to group used for rendering with XTIS fonts
* (0 == base character)
*/
static const char groups[32] = {
0, 1, 0, 0, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2,
2, 2, 2, 2, 2, 2, 1, 0
};
/* Map from code point to index within group 1
* (0 == no combining mark from group 1)
*/
static const char group1_map[32] = {
0, 1, 0, 0, 2, 3, 4, 5,
6, 7, 8, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* Map from code point to index within group 2
* (0 == no combining mark from group 2)
*/
static const char group2_map[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1,
2, 3, 4, 5, 6, 7, 1, 0
};
static const gint char_type_table[256] = {
/* 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, A, B, C, D, E, F */
/*00*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*10*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*20*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*30*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*40*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*50*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*60*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*70*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*80*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*90*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
/*A0*/ _ND, _NC, _NC, _NC, _NC, _NC, _NC, _NC,
_NC, _NC, _NC, _NC, _NC, _SC, _BC, _BC,
/*B0*/ _SC, _NC, _NC, _NC, _NC, _NC, _NC, _NC,
_NC, _NC, _NC, _UC, _NC, _UC, _NC, _UC,
/*C0*/ _NC, _NC, _NC, _NC, _ND, _NC, _ND, _NC,
_NC, _NC, _NC, _NC, _UC, _NC, _NC, _ND,
/*D0*/ _ND, _AV, _ND, _AM, _AV, _AV, _AV, _AV,
_BV, _BV, _BD, _ND, _ND, _ND, _ND, _ND,
/*E0*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _AD,
_TN, _TN, _TN, _TN, _AD, _AD, _AD, _ND,
/*F0*/ _ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
_ND, _ND, _ND, _ND, _ND, _ND, _ND, _ND,
};
static const gint TAC_char_class[256] = {
/* 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, A, B, C, D, E, F */
/*00*/ CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
/*10*/ CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
/*20*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON, NON,
/*30*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON, NON,
/*40*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON, NON,
/*50*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON, NON,
/*60*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON, NON,
/*70*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON,CTRL,
/*80*/ CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
/*90*/ CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,CTRL,
/*A0*/ NON,CONS,CONS,CONS,CONS,CONS,CONS,CONS,
CONS,CONS,CONS,CONS,CONS,CONS,CONS,CONS,
/*B0*/ CONS,CONS,CONS,CONS,CONS,CONS,CONS,CONS,
CONS,CONS,CONS,CONS,CONS,CONS,CONS,CONS,
/*C0*/ CONS,CONS,CONS,CONS, FV3,CONS, FV3,CONS,
CONS,CONS,CONS,CONS,CONS,CONS,CONS, NON,
/*D0*/ FV1, AV2, FV1, FV1, AV1, AV3, AV2, AV3,
BV1, BV2, BD, NON, NON, NON, NON, NON,
/*E0*/ LV, LV, LV, LV, LV, FV2, NON, AD2,
TONE,TONE,TONE,TONE, AD1, AD1, AD3, NON,
/*F0*/ NON, NON, NON, NON, NON, NON, NON, NON,
NON, NON, NON, NON, NON, NON, NON,CTRL,
};
static const gchar TAC_compose_and_input_check_type_table[17][17] = {
/* Cn */ /* 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, A, B, C, D, E, F */
/* Cn-1 00 */ { 'X', 'A', 'A', 'A', 'A', 'A', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 10 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 20 */ { 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'C',
'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C' },
/* 30 */ {'X', 'S', 'A', 'S', 'S', 'S', 'S', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 40 */ { 'X', 'S', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 50 */ { 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 60 */ { 'X', 'A', 'A', 'A', 'S', 'A', 'S', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 70 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'C', 'C', 'R', 'R', 'R', 'R', 'R' },
/* 80 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'C', 'R', 'R', 'R', 'R', 'R', 'R' },
/* 90 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* A0 */ { 'X', 'A', 'A', 'A', 'A', 'A', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* B0 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* C0 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* D0 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
/* E0 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'C', 'C', 'R', 'R', 'R', 'R', 'R' },
/* F0 */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'C', 'R', 'R', 'R', 'R', 'R', 'R' },
/* */ { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R',
'R', 'R', 'C', 'R', 'C', 'R', 'R', 'R', 'R' }
};
typedef struct {
gint ShiftDown_TONE_AD[8];
gint ShiftDownLeft_TONE_AD[8];
gint ShiftLeft_TONE_AD[8];
gint ShiftLeft_AV[7];
gint ShiftDown_BV_BD[3];
gint TailCutCons[4];
} ThaiShapeTable;
#define shiftdown_tone_ad(c,tbl) ((tbl)->ShiftDown_TONE_AD[(c)-0xE7])
#define shiftdownleft_tone_ad(c,tbl) ((tbl)->ShiftDownLeft_TONE_AD[(c)-0xE7])
#define shiftleft_tone_ad(c,tbl) ((tbl)->ShiftLeft_TONE_AD[(c)-0xE7])
#define shiftleft_av(c,tbl) ((tbl)->ShiftLeft_AV[(c)-0xD1])
#define shiftdown_bv_bd(c,tbl) ((tbl)->ShiftDown_BV_BD[(c)-0xD8])
#define tailcutcons(c,tbl) ((tbl)->TailCutCons[(c)-0xAD])
/* Macintosh
*/
static const ThaiShapeTable Mac_shape_table = {
{ 0xE7, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0xED, 0xEE },
{ 0xE7, 0x83, 0x84, 0x85, 0x86, 0x87, 0x8F, 0xEE },
{ 0x93, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x8F, 0xEE },
{ 0x92, 0x00, 0x00, 0x94, 0x95, 0x96, 0x97 },
{ 0xD8, 0xD9, 0xDA },
{ 0xAD, 0x00, 0x00, 0xB0 }
};
/* Microsoft Window
*/
static const ThaiShapeTable Win_shape_table = {
{ 0xE7, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0xED, 0xEE },
{ 0xE7, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x99, 0xEE },
{ 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x99, 0xEE },
{ 0x98, 0x00, 0x00, 0x81, 0x82, 0x83, 0x84 },
{ 0xFC, 0xFD, 0xFE },
{ 0x90, 0x00, 0x00, 0x80 }
};
/* No adjusted vowel/tonemark glyphs (tis620-0)
*/
static const ThaiShapeTable tis620_0_shape_table = {
{ 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE },
{ 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE },
{ 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE },
{ 0xD1, 0x00, 0x00, 0xD4, 0xD5, 0xD6, 0xD7 },
{ 0xD8, 0xD9, 0xDA },
{ 0xAD, 0x00, 0x00, 0xB0 }
};
/* Returns a structure with information we will use to rendering given the
* #PangoFont. This is computed once per font and cached for later retrieval.
*/
static ThaiFontInfo *
get_font_info (const char *fontCharset)
{
static const char *charsets[] = {
"tis620-2",
"tis620-1",
"tis620-0",
"xtis620.2529-1",
"xtis-0",
"tis620.2533-1",
"tis620.2529-1",
"iso8859-11",
"iso10646-1",
};
static const int charset_types[] = {
THAI_FONT_TIS_WIN,
THAI_FONT_TIS_MAC,
THAI_FONT_TIS,
THAI_FONT_XTIS,
THAI_FONT_XTIS,
THAI_FONT_TIS,
THAI_FONT_TIS,
THAI_FONT_TIS,
THAI_FONT_ISO10646
};
ThaiFontInfo *font_info = g_new(ThaiFontInfo, 1);
gint subfontId, i;
font_info->type = THAI_FONT_NONE;
for (i = 0; i < G_N_ELEMENTS(charsets); i++) {
if (strcmp(fontCharset, charsets[i]) == 0) {
font_info->type = (ThaiFontType)charset_types[i];
font_info->subfont = (PangoXSubfont)i;
break;
}
}
return font_info;
}
static void
add_glyph(ThaiFontInfo *font_info,
PangoGlyphString *glyphs,
gint cluster_start,
PangoGlyph glyph,
gboolean combining)
{
gint index = glyphs->num_glyphs;
pango_glyph_string_set_size(glyphs, index + 1);
glyphs->glyphs[index].glyph = glyph;
glyphs->glyphs[index].attr.is_cluster_start = combining ? 0 : 1;
glyphs->log_clusters[index] = cluster_start;
}
static gint
get_adjusted_glyphs_list(ThaiFontInfo *font_info,
gunichar *cluster,
gint num_chrs,
PangoGlyph *glyph_lists,
const ThaiShapeTable *shaping_table)
{
switch (num_chrs) {
case 1:
if (is_char_type (cluster[0], BelowVowel|BelowDiac|AboveVowel|AboveDiac|Tone)) {
if (font_info->type == THAI_FONT_TIS)
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (0x20);
else
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (0x7F);
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
return 2;
}
else {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
return 1;
}
break;
case 2:
if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], SaraAm)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (0xED);
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (0xD2);
return 3;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], SaraAm)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftleft_tone_ad (0xED, shaping_table));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (0xD2);
return 3;
}
else if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], AboveVowel)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
return 2;
}
else if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftdown_tone_ad (ucs2tis (cluster[1]), shaping_table));
return 2;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], AboveVowel)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftleft_av (ucs2tis (cluster[1]), shaping_table));
return 2;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftdownleft_tone_ad (ucs2tis (cluster[1]), shaping_table));
return 2;
}
else if (is_char_type (cluster[0], NoTailCons|UpTailCons) &&
is_char_type (cluster[1], BelowVowel|BelowDiac)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
return 2;
}
else if (is_char_type (cluster[0], BotTailCons) &&
is_char_type (cluster[1], BelowVowel|BelowDiac)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftdown_bv_bd (ucs2tis (cluster[1]), shaping_table));
return 2;
}
else if (is_char_type (cluster[0], SpltTailCons) &&
is_char_type (cluster[1], BelowVowel|BelowDiac)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (tailcutcons (ucs2tis (cluster[0]), shaping_table));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
return 2;
}
else {
if (font_info->type == THAI_FONT_TIS)
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (0x20);
else
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (0x7F);
glyph_lists[1] =
PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[2] =
PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
return 3;
}
break;
case 3:
if (is_char_type (cluster[0], NoTailCons|BotTailCons|SpltTailCons) &&
is_char_type (cluster[1], Tone) &&
is_char_type (cluster[2], SaraAm)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (0xED);
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
glyph_lists[3] = PANGO_MOZ_MAKE_GLYPH (0xD2);
return 4;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], Tone) &&
is_char_type (cluster[2], SaraAm)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftleft_tone_ad (0xED, shaping_table));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftleft_tone_ad (ucs2tis (cluster[1]), shaping_table));
glyph_lists[3] = PANGO_MOZ_MAKE_GLYPH (0xD2);
return 4;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], AboveVowel) &&
is_char_type (cluster[2], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftleft_av (ucs2tis (cluster[1]), shaping_table));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftleft_tone_ad (ucs2tis (cluster[2]), shaping_table));
return 3;
}
else if (is_char_type (cluster[0], UpTailCons) &&
is_char_type (cluster[1], BelowVowel) &&
is_char_type (cluster[2], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftdownleft_tone_ad (ucs2tis (cluster[2]), shaping_table));
return 3;
}
else if (is_char_type (cluster[0], NoTailCons) &&
is_char_type (cluster[1], BelowVowel) &&
is_char_type (cluster[2], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftdown_tone_ad (ucs2tis (cluster[2]), shaping_table));
return 3;
}
else if (is_char_type (cluster[0], SpltTailCons) &&
is_char_type (cluster[1], BelowVowel) &&
is_char_type (cluster[2], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (tailcutcons (ucs2tis (cluster[0]), shaping_table));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftdown_tone_ad (ucs2tis (cluster[2]), shaping_table));
return 3;
}
else if (is_char_type (cluster[0], BotTailCons) &&
is_char_type (cluster[1], BelowVowel) &&
is_char_type (cluster[2], AboveDiac|Tone)) {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (shiftdown_bv_bd (ucs2tis (cluster[1]), shaping_table));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (shiftdown_tone_ad (ucs2tis (cluster[2]), shaping_table));
return 3;
}
else {
glyph_lists[0] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[0]));
glyph_lists[1] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[1]));
glyph_lists[2] = PANGO_MOZ_MAKE_GLYPH (ucs2tis (cluster[2]));
return 3;
}
break;
}
return 0;
}
static gint
get_glyphs_list(ThaiFontInfo *font_info,
gunichar *cluster,
gint num_chrs,
PangoGlyph *glyph_lists)
{
PangoGlyph glyph;
gint xtis_index, i;
switch (font_info->type) {
case THAI_FONT_NONE:
for (i = 0; i < num_chrs; i++)
/* Change this to remove font dependency */
glyph_lists[i] = 0; /* pango_x_get_unknown_glyph(font_info->font); */
return num_chrs;
case THAI_FONT_XTIS:
/* If we are rendering with an XTIS font, we try to find a precomposed
* glyph for the cluster.
*/
xtis_index = 0x100 * (cluster[0] - 0xe00 + 0x20) + 0x30;
if (cluster[1])
xtis_index +=8 * group1_map[cluster[1] - 0xe30];
if (cluster[2])
xtis_index += group2_map[cluster[2] - 0xe30];
glyph = PANGO_MOZ_MAKE_GLYPH(xtis_index);
/*
if (pango_x_has_glyph(font_info->font, glyph)) {
glyph_lists[0] = glyph;
return 1;
}
*/
for (i=0; i < num_chrs; i++)
glyph_lists[i] = PANGO_MOZ_MAKE_GLYPH(0x100 * (cluster[i] - 0xe00 + 0x20) + 0x30);
return num_chrs;
case THAI_FONT_TIS:
/* TIS620-0 + Wtt2.0 Extension
*/
return get_adjusted_glyphs_list (font_info, cluster,
num_chrs, glyph_lists, &tis620_0_shape_table);
case THAI_FONT_TIS_MAC:
/* MacIntosh Extension
*/
return get_adjusted_glyphs_list(font_info, cluster,
num_chrs, glyph_lists, &Mac_shape_table);
case THAI_FONT_TIS_WIN:
/* Microsoft Extension
*/
return get_adjusted_glyphs_list(font_info, cluster,
num_chrs, glyph_lists, &Win_shape_table);
case THAI_FONT_ISO10646:
for (i=0; i < num_chrs; i++)
glyph_lists[i] = PANGO_MOZ_MAKE_GLYPH(cluster[i]);
return num_chrs;
}
return 0; /* Quiet GCC */
}
static void
add_cluster (ThaiFontInfo *font_info,
PangoGlyphString *glyphs,
gint cluster_start,
gunichar *cluster,
gint num_chrs)
{
PangoGlyph glyphs_list[MAX_GLYPHS];
gint i, num_glyphs;
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);
}
static gboolean
is_wtt_composible (gunichar cur_wc, gunichar nxt_wc)
{
switch (TAC_compose_and_input_check_type_table[char_class(ucs2tis(cur_wc))]
[char_class(ucs2tis(nxt_wc))]) {
case 'A':
case 'S':
case 'R':
case 'X':
return FALSE;
case 'C':
return TRUE;
}
g_assert_not_reached();
return FALSE;
}
static const char *
get_next_cluster(const char *text,
gint length,
gunichar *cluster,
gint *num_chrs)
{
const char *p;
gint n_chars = 0;
p = text;
while (p < text + length && n_chars < 3) {
gunichar current = g_utf8_get_char (p);
if (n_chars == 0 ||
is_wtt_composible ((gunichar)(cluster[n_chars - 1]), current) ||
(n_chars == 1 &&
is_char_type (cluster[0], Cons) &&
is_char_type (current, SaraAm)) ||
(n_chars == 2 &&
is_char_type (cluster[0], Cons) &&
is_char_type (cluster[1], Tone) &&
is_char_type (current, SaraAm))) {
cluster[n_chars++] = current;
p = g_utf8_next_char(p);
}
else
break;
}
*num_chrs = n_chars;
return p;
}
static void
thai_engine_shape(const char *fontCharset,
const char *text,
gint length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
ThaiFontInfo *font_info;
const char *p;
const char *log_cluster;
gunichar cluster[MAX_CLUSTER_CHRS];
gint num_chrs;
pango_glyph_string_set_size(glyphs, 0);
font_info = get_font_info(fontCharset);
p = text;
while (p < text + length) {
log_cluster = p;
p = get_next_cluster(p, text + length - p, cluster, &num_chrs);
add_cluster(font_info, glyphs, log_cluster - text, cluster, num_chrs);
}
}
static PangoCoverage *
thai_engine_get_coverage(const char *fontCharset,
const char *lang)
{
PangoCoverage *result = pango_coverage_new();
ThaiFontInfo *font_info = get_font_info(fontCharset);
if (font_info->type != THAI_FONT_NONE) {
gunichar wc;
for (wc = 0xe01; wc <= 0xe3a; wc++)
pango_coverage_set(result, wc, PANGO_COVERAGE_EXACT);
for (wc = 0xe3f; wc <= 0xe5b; wc++)
pango_coverage_set(result, wc, PANGO_COVERAGE_EXACT);
}
return result;
}
static PangoEngine *
thai_engine_x_new()
{
PangoEngineShape *result;
result = g_new(PangoEngineShape, 1);
result->engine.id = SCRIPT_ENGINE_NAME;
result->engine.type = PANGO_ENGINE_TYPE_SHAPE;
result->engine.length = sizeof(result);
result->script_shape = thai_engine_shape;
result->get_coverage = thai_engine_get_coverage;
return(PangoEngine *)result;
}
/* The following three functions provide the public module API for
* Pango. 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 Pango, then we need them to
* to have distinct names for this module, so we prepend
* _pango_thai_x_
*/
#ifdef X_MODULE_PREFIX
#define MODULE_ENTRY(func) _pango_thai_x_##func
#else
#define MODULE_ENTRY(func) func
#endif
/* List the engines contained within this module
*/
void
MODULE_ENTRY(script_engine_list)(PangoEngineInfo **engines, gint *n_engines)
{
*engines = script_engines;
*n_engines = G_N_ELEMENTS(script_engines);
}
/* Load a particular engine given the ID for the engine
*/
PangoEngine *
MODULE_ENTRY(script_engine_load)(const char *id)
{
if (!strcmp(id, SCRIPT_ENGINE_NAME))
return thai_engine_x_new();
else
return NULL;
}
void
MODULE_ENTRY(script_engine_unload)(PangoEngine *engine)
{
}