Fix build bustage with --enable-ctl by moving files from extensions/ctl to intl/ctl. Bug 133212. Author=Roland.Mainz@informatik.med.uni-giessen.de; Makefile changes r=cls. Not part of the default build.

This commit is contained in:
smontagu%netscape.com 2002-08-23 23:09:22 +00:00
Родитель ec7e89fcd8
Коммит b95b4ce51b
61 изменённых файлов: 4951 добавлений и 24 удалений

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

@ -196,6 +196,16 @@ intl/strres/src/Makefile
intl/strres/tests/Makefile
"
if [ "$SUNCTL" ] ; then
MAKEFILES_intl="$MAKEFILES_intl
intl/ctl/Makefile
intl/ctl/public/Makefile
intl/ctl/src/Makefile
intl/ctl/src/pangoLite/Makefile
intl/ctl/src/thaiShaper/Makefile
"
fi
MAKEFILES_js="
js/Makefile
js/src/Makefile
@ -1049,13 +1059,6 @@ for extension in $MOZ_EXTENSIONS; do
extensions/cookie/Makefile
extensions/cookie/tests/Makefile
" ;;
ctl ) MAKEFILES_extensions="$MAKEFILES_extensions
extensions/ctl/Makefile
extensions/ctl/public/Makefile
extensions/ctl/src/Makefile
extensions/ctl/src/pangoLite/Makefile
extensions/ctl/src/thaiShaper/Makefile
" ;;
cview ) MAKEFILES_extensions="$MAKEFILES_extensions
extensions/cview/Makefile
extensions/cview/resources/Makefile

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

@ -3273,12 +3273,7 @@ dnl ========================================================
MOZ_EXTENSIONS_DEFAULT=" cookie wallet content-packs xml-rpc xmlextras help pref transformiix venkman inspector irc universalchardet typeaheadfind"
dnl Check if Thai Rendering Extension needs to be enabled
if test -n "$SUNCTL"; then
MOZ_EXTENSIONS_DEFAULT="$MOZ_EXTENSIONS_DEFAULT ctl"
fi
MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin ctl p3p interfaceinfo"
MOZ_EXTENSIONS_ALL="$MOZ_EXTENSIONS_DEFAULT xmlterm access-builtin p3p interfaceinfo"
MOZ_ARG_ENABLE_STRING(extensions,
[ --enable-extensions Enable extensions],
@ -4334,17 +4329,6 @@ AC_SUBST(HOST_LIBIDL_CONFIG)
AC_SUBST(HOST_LIBIDL_CFLAGS)
AC_SUBST(HOST_LIBIDL_LIBS)
dnl older versions of glib do not seem to have gmodule which ctl needs
if test "`echo $MOZ_EXTENSIONS | grep -c ctl 2>/dev/null`" != 0; then
_SAVE_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $GLIB_CFLAGS"
AC_TRY_COMPILE([#include <gmodule.h>],
[ int x = 1; x++; ],,
[AC_MSG_WARN([Cannot build ctl without gmodule support in glib. Removing ctl from MOZ_EXTENSIONS.])
MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|ctl||'` ])
CFLAGS=$_SAVE_CFLAGS
fi
dnl ========================================================
dnl Check for libart
dnl ========================================================

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -28,6 +28,11 @@ include $(DEPTH)/config/autoconf.mk
DIRS = unicharutil uconv locale strres lwbrk chardet
# Sun's Complex Text Layout support
ifdef SUNCTL
DIRS += ctl
endif
ifeq ($(OS_ARCH),WINNT)
DIRS += compatibility
endif

32
intl/ctl/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,32 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src/pangoLite src/thaiShaper src
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,41 @@
#
# 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):
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = ctl
EXPORTS = \
nsCtlCIID.h \
nsILE.h \
$(NULL)
LOCAL_INCLUDES += -I../src/include
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* XPCTL : nsCtlCIID.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 nsCtlCIID_h___
#define nsCtlCIID_h___
// Class ID for UnicodeToTIS620 charset converter for *nix
#define NS_UNICODETOTIS620_CID \
{ 0xa2297171, 0x41ee, 0x498a, \
{ 0x83, 0x12, 0x1a, 0x63, 0x27, 0xd0, 0x44, 0x3a } }
// 1B285478-11B7-4EA3-AF47-2A7D117845AC
#define NS_ILE_IID \
{ 0x1b285478, 0x11b7, 0x4ea3, \
{ 0xaf, 0x47, 0x2a, 0x7d, 0x11, 0x78, 0x45, 0xac } }
#define NS_ILE_PROGID "@mozilla.org/extensions/ctl;1"
// A47B6D8A-CB2D-439E-B186-AC40F73B8252
#define NS_ULE_CID \
{ 0xa47b6d8a, 0xcb2d, 0x439e, \
{ 0xb1, 0x86, 0xac, 0x40, 0xf7, 0x3b, 0x82, 0x52 } }
// 6898A17D-5933-4D49-9CB4-CB261206FCC0
#define NS_ULE_IID \
{ 0x6898a17d, 0x5933, 0x4d49, \
{ 0x9c, 0xb4, 0xcb, 0x26, 0x12, 0x06, 0xfc, 0xc0 } }
#define NS_ULE_PROGID "@mozilla.org/intl/extensions/nsULE;1"
// D9E30F46-0EB5-4763-A7BD-26DECB30952F
#define NS_ISHAPEDTEXT_IID \
{ 0xd9e30f46, 0x0eb5, 0x4763, \
{ 0xa7, 0xbd, 0x26, 0xde, 0xcb, 0x30, 0x95, 0x2f } }
// {2997A657-AD7B-4036-827C-FBB3B443845B}
#define NS_SHAPEDTEXT_CID \
{ 0x2997a657, 0xad7b, 0x4036, \
{ 0x82, 0x7c, 0xfb, 0xb3, 0xb4, 0x43, 0x84, 0x5b } }
// {A47B6D8A-CB2D-439E-B186-AC40F73B8252}
#define NS_SHAPEDTEXT_IID \
{ 0xa47b6d8a, 0xcb2d, 0x439e, \
{ 0xb1, 0x86, 0xac, 0x40, 0xf7, 0x3b, 0x82, 0x52 } }
#define NS_SHAPEDTEXT_PROGID "component://netscape/extensions/ctl/nsShapedText"
#endif

53
intl/ctl/public/nsILE.h Normal file
Просмотреть файл

@ -0,0 +1,53 @@
/* -*- 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"
/*
* nsILE Interface declaration
*/
class nsILE : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILE_IID)
NS_IMETHOD GetPresentationForm(const PRUnichar*, PRUint32,
const char*, char*, PRSize*) = 0;
NS_IMETHOD PrevCluster(const PRUnichar*, PRUint32,
const PRInt32, PRInt32*) = 0;
NS_IMETHOD NextCluster(const PRUnichar*, PRUint32,
const PRInt32, PRInt32*) = 0;
NS_IMETHOD GetRangeOfCluster(const PRUnichar*, PRUint32,
const PRInt32, PRInt32*, PRInt32*) = 0;
};
#endif // nsILE_h

1
intl/ctl/readme.txt Normal file
Просмотреть файл

@ -0,0 +1 @@
we should add the pango ctl code here

60
intl/ctl/src/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,60 @@
#
# 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):
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = ctl
LIBRARY_NAME = ctl
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
REQUIRES = xpcom \
string \
uconv \
locale \
$(NULL)
EXTRA_DSO_LIBS = mozpango
CPPSRCS = \
nsULE.cpp \
nsUnicodeToTIS620.cpp \
nsCtlLEModule.cpp \
$(NULL)
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += -I$(srcdir)/pangoLite
CXXFLAGS += $(GLIB_CFLAGS)
EXTRA_DSO_LDOPTS += \
$(MOZ_COMPONENT_LIBS) \
-L$(DIST)/lib \
$(EXTRA_DSO_LIBS) \
$(GLIB_GMODULE_LIBS) \
$(NULL)

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

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* XPCTL : nsCtlLEModule.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 "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsIFactory.h"
#include "nsIGenericFactory.h"
#include "nsIModule.h"
#include "nsULE.h"
#include "nsICharsetConverterManager.h"
#include "nsUnicodeToTIS620.h"
//----------------------------------------------------------------------------
// Global functions and data [declaration]
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
#define ENCODER_NAME_BASE "Unicode Encoder-"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsULE)
// Per DLL Globals
PRInt32 g_InstanceCount = 0;
PRInt32 g_LockCount = 0;
NS_CONVERTER_REGISTRY_START
NS_UCONV_REG_UNREG_ENCODER("tis620-2", NS_UNICODETOTIS620_CID)
NS_CONVERTER_REGISTRY_END
NS_IMPL_NSUCONVERTERREGSELF
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUnicodeToTIS620);
static const nsModuleComponentInfo components[] =
{
{ ENCODER_NAME_BASE "tis620-2" , NS_UNICODETOTIS620_CID,
NS_UNICODEENCODER_CONTRACTID_BASE "tis620-2",
nsUnicodeToTIS620Constructor,
nsUConverterRegSelf, nsUConverterUnregSelf },
{ "Unicode Layout Engine", NS_ULE_CID, NS_ULE_PROGID,
nsULEConstructor, NULL, NULL }
};
NS_IMPL_NSGETMODULE("nsCtlLEModule", components)

444
intl/ctl/src/nsULE.cpp Normal file
Просмотреть файл

@ -0,0 +1,444 @@
/* -*- 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 "nsULE.h"
#include "nsString.h"
#include "pango-types.h"
#include "pango-glyph.h"
#include "pango-modules.h"
#include "pango-utils.h"
#define CLEAN_RUN \
aPtr = aRun.head; \
for (int ct=0; (ct < aRun.numRuns); ct++) { \
aTmpPtr = aPtr; \
aPtr = aPtr->next; \
delete(aTmpPtr); \
}
/*
* Start of nsULE Public Functions
*/
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;
}
PRInt32
nsULE::SeparateScript(const PRUnichar* aSrcBuf,
PRInt32 aSrcLen,
textRunList *aRunList)
{
int ct = 0, start = 0;
PRBool isCtl = PR_FALSE;
struct textRun *tmpChunk;
PangoEngineShape *aEngine = NULL;
PangoMap *aMap = NULL;
guint engine_type_id = 0, render_type_id = 0;
engine_type_id = g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string(PANGO_RENDER_TYPE_X);
aMap = pango_find_map("en_US", engine_type_id, render_type_id);
for (ct = 0; ct < aSrcLen;) {
tmpChunk = new textRun;
if (aRunList->numRuns == 0)
aRunList->head = tmpChunk;
else
aRunList->cur->next = tmpChunk;
aRunList->cur = tmpChunk;
aRunList->numRuns++;
tmpChunk->start = &aSrcBuf[ct];
start = ct;
aEngine = (PangoEngineShape*)
pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
isCtl = (aEngine != NULL);
if (isCtl) {
while (isCtl && ct < aSrcLen) {
aEngine = (PangoEngineShape*)
pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
isCtl = (aEngine != NULL);
if (isCtl)
ct++;
}
tmpChunk->isOther = PR_FALSE;
}
else {
while (!isCtl && ct < aSrcLen) {
aEngine = (PangoEngineShape*)
pango_map_get_engine(aMap, (PRUint32)aSrcBuf[ct]);
isCtl = (aEngine != NULL);
if (!isCtl)
ct++;
}
tmpChunk->isOther = PR_TRUE;
}
tmpChunk->length = ct - start;
}
return (PRInt32)aRunList->numRuns;
}
// Analysis needs to have valid direction and font charset
PRInt32
nsULE::GetRawCtlData(const PRUnichar *aString,
PRUint32 aLength,
PangoGlyphString *aGlyphs)
{
PangoEngineShape *aShaper = GetShaper(aString, aLength, (const char*)NULL);
PangoAnalysis aAnalysis;
aAnalysis.shape_engine = aShaper;
aAnalysis.aDir = PANGO_DIRECTION_LTR;
// In future fontCharset hard-coding should be removed
aAnalysis.fontCharset = strdup("tis620-2");
if (aShaper != NULL) {
aShaper->script_shape(aAnalysis.fontCharset, aString, aLength,
&aAnalysis, aGlyphs);
nsMemory::Free(aAnalysis.fontCharset);
}
else {
/* No Shaper - Copy Input to output */
return 0;
}
return aGlyphs->num_glyphs;
}
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();
int aSize = 0;
aAnalysis.shape_engine = aShaper;
aAnalysis.aDir = PANGO_DIRECTION_LTR;
aAnalysis.fontCharset = (char*)fontCharset;
if (aShaper != NULL) {
aShaper->script_shape(fontCharset, aString, aLength,
&aAnalysis, tmpGlyphs);
if (tmpGlyphs->num_glyphs > 0) {
// Note : Does NOT handle 2 byte fonts
aSize = tmpGlyphs->num_glyphs;
// 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;
}
// 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)
{
textRunList aRun;
textRun *aPtr, *aTmpPtr;
PRInt32 aStrCt=0;
PRBool isBoundary=PR_FALSE;
PangoGlyphString *aGlyphData=pango_glyph_string_new();
if (aIndex >= aLength-1) {
*nextOffset = aLength; // End
return NS_OK;
}
aRun.numRuns = 0;
SeparateScript(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;
GetRawCtlData(aPtr->start, runLen, aGlyphData);
numCur=beg=0;
for (j=0; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_glyphs)
j++;
if (j>=aGlyphData->num_glyphs)
end=runLen;
else
end=aGlyphData->log_clusters[j];
numCur += end-beg;
if (startCt+numCur > aIndex)
break;
else
beg=end;
}
// Found Cluster - Start of Next == End Of Current
*nextOffset = startCt+numCur;
CLEAN_RUN
return NS_OK;
}
}
aPtr = aPtr->next;
}
/* UNUSED */
CLEAN_RUN
}
// This routine returns the end-offset of the previous block
// corresponding to string index 'aIndex'
NS_IMETHODIMP
nsULE::PrevCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *prevOffset)
{
textRunList aRun;
textRun *aPtr, *aTmpPtr;
PRInt32 aStrCt=0, startCt=0, glyphct=0;
PangoGlyphString *aGlyphData=pango_glyph_string_new();
if (aIndex<=1) {
*prevOffset=0; // End
return NS_OK;
}
aRun.numRuns=0;
SeparateScript(aString, aLength, &aRun);
// Get the index of current cluster
aPtr=aRun.head;
for (int i=0; i<aRun.numRuns; i++) {
PRInt32 runLen=aPtr->length;
if ((aStrCt+runLen) < aIndex) /* Skip Run */
aStrCt += runLen;
else if ((aStrCt+runLen) == aIndex) {
if (aPtr->isOther) {
*prevOffset=aIndex-1;
CLEAN_RUN
return NS_OK;
}
else { /* Move back a cluster */
startCt=aStrCt;
GetRawCtlData(aPtr->start, runLen, aGlyphData);
glyphct=aGlyphData->num_glyphs-1;
while (glyphct > 0) {
if (aGlyphData->glyphs[glyphct].attr.is_cluster_start) {
*prevOffset=startCt+aGlyphData->log_clusters[glyphct];
CLEAN_RUN
return NS_OK;
}
--glyphct;
}
*prevOffset=startCt;
CLEAN_RUN
return NS_OK;
}
}
else {
if (aPtr->isOther) {
*prevOffset=aIndex-1;
CLEAN_RUN
return NS_OK;
}
else {
PRInt32 j,beg,end,numPrev,numCur;
startCt=aStrCt;
GetRawCtlData(aPtr->start, runLen, aGlyphData);
numPrev=numCur=beg=0;
for (j=1; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_glyphs)
j++;
if (j>=aGlyphData->num_glyphs)
end=runLen;
else
end=aGlyphData->log_clusters[j];
numCur += end-beg;
if (numCur+startCt >= aIndex)
break;
else {
beg=end;
numPrev=numCur;
}
}
*prevOffset=startCt+numPrev;
CLEAN_RUN
return NS_OK;
}
}
aPtr=aPtr->next;
}
/* UNUSED */
CLEAN_RUN
}
// This routine returns the end-offset of the previous block
// corresponding to string index 'aIndex'
NS_IMETHODIMP
nsULE::GetRangeOfCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *aStart,
PRInt32 *aEnd)
{
textRunList aRun;
textRun *aPtr, *aTmpPtr;
PRInt32 aStrCt=0, startCt=0,j;
PangoGlyphString *aGlyphData=pango_glyph_string_new();
*aStart = *aEnd = 0;
aRun.numRuns=0;
SeparateScript(aString, aLength, &aRun);
// Get the index of current cluster
aPtr=aRun.head;
for (int i=0; i<aRun.numRuns; i++) {
PRInt32 runLen=aPtr->length;
if ((aStrCt+runLen) < aIndex) /* Skip Run */
aStrCt += runLen;
else {
if (aPtr->isOther) {
*aStart = *aEnd = aIndex;
CLEAN_RUN
return NS_OK;
}
else {
PRInt32 beg,end,numCur;
startCt=aStrCt;
GetRawCtlData(aPtr->start, runLen, aGlyphData);
numCur=beg=0;
for (j=1; j<aGlyphData->num_glyphs; j++) {
while ((!aGlyphData->glyphs[j].attr.is_cluster_start) &&
j<aGlyphData->num_glyphs)
j++;
if (j>=aGlyphData->num_glyphs)
end=runLen;
else
end=aGlyphData->log_clusters[j];
numCur += end-beg;
if (numCur+startCt >= aIndex)
break;
else
beg=end;
}
*aEnd = startCt+numCur;
if (beg == 0)
*aStart = beg;
else {
if ((end-beg) == 1) /* n=n Condition */
*aStart = *aEnd;
else
*aStart = startCt+beg+1; /* Maintain Mozilla Convention */
}
CLEAN_RUN
return NS_OK;
}
}
aPtr=aPtr->next;
}
CLEAN_RUN
/* UNUSED */
}

102
intl/ctl/src/nsULE.h Normal file
Просмотреть файл

@ -0,0 +1,102 @@
/* -*- 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"
#include "pango-types.h"
#include "pango-glyph.h"
struct textRun {
PRInt32 length; /* Length of a chunk */
PRBool isOther; /* Outside the range */
const PRUnichar *start; /* Address of start offset */
struct textRun *next;
};
struct textRunList {
struct textRun *head;
struct textRun *cur;
PRInt32 numRuns;
};
/* Class nsULE : Declaration */
class nsULE : public nsILE {
public:
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,
const char *fontCharset,
char *aGlyphs,
PRSize *aOutLength);
NS_IMETHOD PrevCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *prevOffset);
NS_IMETHOD NextCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *nextOffset);
NS_IMETHOD GetRangeOfCluster(const PRUnichar *aString,
PRUint32 aLength,
const PRInt32 aIndex,
PRInt32 *aStart,
PRInt32 *aEnd);
private:
// Housekeeping Members
void Init(void);
void CleanUp(void);
PangoEngineShape* GetShaper(const PRUnichar *, PRUint32, const char *);
PRInt32 GetRawCtlData(const PRUnichar*, PRUint32, PangoGlyphString*);
PRInt32 SeparateScript(const PRUnichar*, PRInt32, textRunList*);
};
#endif /* nsULE_H */

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

@ -0,0 +1,298 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ucvth : nsUnicodeToTIS620.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 ucvth is based on the Thai Shaper in Pango by
* Red Hat Software. Portions created by Redhat are Copyright (C)
* 1999 Red Hat Software.
*
* Contributor(s):
*/
#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);
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 (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_IMETHODIMP nsUnicodeToTIS620::SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder * aEncoder,
PRUnichar aChar)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// constructor and destroctor
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;
}
/*
* This method converts the unicode to this font index.
* 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)
{
textRunList txtRuns;
textRun *aPtr, *aTmpPtr;
int i;
#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);
#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
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;
}
// 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++) {
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(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;
return NS_OK;
}
NS_IMETHODIMP nsUnicodeToTIS620::Finish(char * output, PRInt32 * aDestLength)
{
// Finish does'nt have to do much as Convert already flushes
// to output buffer
mByteOff = mCharOff = 0;
return NS_OK;
}
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::Reset()
{
mByteOff = mCharOff = 0;
return NS_OK;
}
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::GetMaxLength(const PRUnichar * aSrc,
PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
*aDestLength = (aSrcLength + 1) * 2; // Each Thai character can generate
// atmost two presentation forms
return NS_OK;
}
//================================================================
NS_IMETHODIMP nsUnicodeToTIS620::FillInfo(PRUint32* aInfo)
{
PRUint16 i;
// 00-0x7f
for (i = 0;i <= 0x7f; i++)
SET_REPRESENTABLE(aInfo, i);
// 0x0e01-0x0e7f
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++)
SET_REPRESENTABLE(aInfo, i);
// U+0E5C - U+0E7F Undefined
return NS_OK;
}

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

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ucvth : nsUnicodeToTIS620.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 ucvth is based on the Thai Shaper in Pango by
* Red Hat Software. Portions created by Redhat are Copyright (C)
* 1999 Red Hat Software.
*
* Contributor(s):
*/
#ifndef nsUnicodeToTIS620_h___
#define nsUnicodeToTIS620_h___
#include "nspr.h"
#include "nsIFactory.h"
#include "nsIRegistry.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsIModule.h"
#include "nsIUnicodeEncoder.h"
#include "nsICharRepresentable.h"
#include "nsILE.h"
struct textRunList;
//----------------------------------------------------------------------
// Class nsUnicodeToTIS620 [declaration]
class nsUnicodeToTIS620 : public nsIUnicodeEncoder, public nsICharRepresentable
{
NS_DECL_ISUPPORTS
public:
/**
* Class constructor.
*/
nsUnicodeToTIS620();
virtual ~nsUnicodeToTIS620();
NS_IMETHOD Convert(const PRUnichar * aSrc, PRInt32 * aSrcLength,
char * aDest, PRInt32 * aDestLength);
NS_IMETHOD Finish(char * aDest, PRInt32 * aDestLength);
NS_IMETHOD GetMaxLength(const PRUnichar * aSrc, PRInt32 aSrcLength,
PRInt32 * aDestLength);
NS_IMETHOD Reset();
NS_IMETHOD SetOutputErrorBehavior(PRInt32 aBehavior,
nsIUnicharEncoder * aEncoder,
PRUnichar aChar);
NS_IMETHOD FillInfo(PRUint32* aInfo);
private:
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
PRInt32 Itemize(const PRUnichar* aSrcBuf, PRInt32 aSrcLen, textRunList *aRunList);
};
#endif /* nsUnicodeToTIS620_h___ */

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

@ -0,0 +1,76 @@
# 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.
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
sysconfdir = $(DIST)/bin
MODULE = mozpango
LIBRARY_NAME = mozpango
EXPORT_LIBRARY = 1
CSRCS = \
glyphstring.c \
modules.c \
pango-utils.c \
pango-coverage.c \
shape.c \
$(NULL)
EXPORTS = \
modules.h \
pango-coverage.h \
pango-engine.h \
pango-glyph.h \
pango-modules.h \
pango-types.h \
pango-utils.h \
pango.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(GLIB_CFLAGS)
CFLAGS += $(GLIB_CFLAGS)
EXTRA_DSO_LDOPTS += $(GLIB_GMODULE_LIBS)
# Install pango.modules file for Shaping Modules.
libs::
$(INSTALL) $(srcdir)/pango.modules $(DIST)/bin
install:: pango.modules
$(SYSINSTALL) $(IFLAGS1) $< $(DESTDIR)$(mozappdir)

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

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* glyphstring.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):
*
* 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 "pango-glyph.h"
/**
* pango_glyph_string_new:
*
* Create a new PangoGlyphString.
*
* Returns the new PangoGlyphString
*/
PangoGlyphString *
pango_glyph_string_new(void)
{
PangoGlyphString *string = g_new(PangoGlyphString, 1);
string->num_glyphs = 0;
string->space = 0;
string->glyphs = NULL;
string->log_clusters = NULL;
return string;
}
/**
* pango_glyph_string_set_size:
* @string: a PangoGlyphString.
* @new_len: the new length of the string.
*
* Resize a glyph string to the given length.
*/
void
pango_glyph_string_set_size(PangoGlyphString *string, gint new_len)
{
g_return_if_fail (new_len >= 0);
while (new_len > string->space) {
if (string->space == 0)
string->space = 1;
else
string->space *= 2;
if (string->space < 0)
g_error("%s: glyph string length overflows maximum integer size",
"pango_glyph_string_set_size");
}
string->glyphs = g_realloc(string->glyphs,
string->space * sizeof(PangoGlyphInfo));
string->log_clusters = g_realloc(string->log_clusters,
string->space * sizeof (gint));
string->num_glyphs = new_len;
}
/**
* pango_glyph_string_free:
* @string: a PangoGlyphString.
*
* Free a glyph string and associated storage.
*/
void
pango_glyph_string_free(PangoGlyphString *string)
{
g_free(string->glyphs);
g_free(string->log_clusters);
g_free(string);
}

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

@ -0,0 +1,516 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* modules.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):
*
* 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <gmodule.h>
#include "pango-modules.h"
#include "pango-utils.h"
typedef struct _PangoMapInfo PangoMapInfo;
typedef struct _PangoEnginePair PangoEnginePair;
typedef struct _PangoSubmap PangoSubmap;
struct _PangoSubmap
{
gboolean is_leaf;
union {
PangoMapEntry entry;
PangoMapEntry *leaves;
} d;
};
struct _PangoMap
{
gint n_submaps;
PangoSubmap submaps[256];
};
struct _PangoMapInfo
{
const gchar *lang;
guint engine_type_id;
guint render_type_id;
PangoMap *map;
};
struct _PangoEnginePair
{
PangoEngineInfo info;
gboolean included;
void *load_info;
PangoEngine *engine;
};
static GList *maps = NULL;
static GSList *builtin_engines = NULL;
static GSList *registered_engines = NULL;
static GSList *dlloaded_engines = NULL;
static void build_map(PangoMapInfo *info);
static void init_modules(void);
/**
* pango_find_map:
* @lang: the language tag for which to find the map (in the form
* en or en_US)
* @engine_type_id: the render type for the map to find
* @render_type_id: the engine type for the map to find
*
* Locate a #PangoMap for a particular engine type and render
* type. The resulting map can be used to determine the engine
* for each character.
*
* Return value:
**/
PangoMap*
pango_find_map(const char *lang, guint engine_type_id, guint render_type_id)
{
GList *tmp_list = maps;
PangoMapInfo *map_info = NULL;
gboolean found_earlier = FALSE;
while (tmp_list) {
map_info = tmp_list->data;
if (map_info->engine_type_id == engine_type_id &&
map_info->render_type_id == render_type_id) {
if (strcmp(map_info->lang, lang) == 0)
break;
else
found_earlier = TRUE;
}
tmp_list = tmp_list->next;
}
if (!tmp_list) {
map_info = g_new(PangoMapInfo, 1);
map_info->lang = g_strdup(lang);
map_info->engine_type_id = engine_type_id;
map_info->render_type_id = render_type_id;
build_map(map_info);
maps = g_list_prepend(maps, map_info);
}
else if (found_earlier) {
/* Move the found map to the beginning of the list
* for speed next time around if we had to do
* any failing strcmps.
*/
maps = g_list_remove_link(maps, tmp_list);
maps = g_list_prepend(maps, tmp_list->data);
g_list_free_1(tmp_list);
}
return map_info->map;
}
static PangoEngine *
pango_engine_pair_get_engine(PangoEnginePair *pair)
{
if (!pair->engine) {
if (pair->included) {
PangoIncludedModule *included_module = pair->load_info;
pair->engine = included_module->load(pair->info.id);
}
else {
GModule *module;
char *module_name = pair->load_info;
PangoEngine *(*load)(const gchar *id);
module = g_module_open(module_name, 0);
if (!module) {
fprintf(stderr, "Cannot load module %s: %s\n",
module_name, g_module_error());
return NULL;
}
g_module_symbol(module, "script_engine_load", (gpointer)&load);
if (!load) {
fprintf(stderr, "cannot retrieve script_engine_load from %s: %s\n",
module_name, g_module_error());
g_module_close(module);
return NULL;
}
pair->engine = (*load)(pair->info.id);
}
}
return pair->engine;
}
static void
handle_included_module(PangoIncludedModule *module, GSList **engine_list)
{
PangoEngineInfo *engine_info;
int n_engines, i;
module->list(&engine_info, &n_engines);
for (i = 0; i < n_engines; i++) {
PangoEnginePair *pair = g_new(PangoEnginePair, 1);
pair->info = engine_info[i];
pair->included = TRUE;
pair->load_info = module;
pair->engine = NULL;
*engine_list = g_slist_prepend(*engine_list, pair);
}
}
static gboolean /* Returns true if succeeded, false if failed */
process_module_file(FILE *module_file)
{
GString *line_buf = g_string_new(NULL);
GString *tmp_buf = g_string_new(NULL);
gboolean have_error = FALSE;
while (pango_read_line(module_file, line_buf)) {
PangoEnginePair *pair = g_new(PangoEnginePair, 1);
PangoEngineRange *range;
GList *ranges = NULL;
GList *tmp_list;
const char *p, *q;
int i, start, end;
pair->included = FALSE;
p = line_buf->str;
if (!pango_skip_space(&p)) {
g_free(pair);
continue;
}
i = 0;
while (1) {
if (!pango_scan_string(&p, tmp_buf)) {
have_error = TRUE;
goto error;
}
switch (i) {
case 0:
pair->load_info = g_strdup(tmp_buf->str);
break;
case 1:
pair->info.id = g_strdup(tmp_buf->str);
break;
case 2:
pair->info.engine_type = g_strdup(tmp_buf->str);
break;
case 3:
pair->info.render_type = g_strdup(tmp_buf->str);
break;
default:
range = g_new(PangoEngineRange, 1);
if (sscanf(tmp_buf->str, "%d-%d:", &start, &end) != 2) {
fprintf(stderr, "Error reading modules file");
have_error = TRUE;
goto error;
}
q = strchr(tmp_buf->str, ':');
if (!q) {
fprintf(stderr, "Error reading modules file");
have_error = TRUE;
goto error;
}
q++;
range->start = start;
range->end = end;
range->langs = g_strdup(q);
ranges = g_list_prepend(ranges, range);
}
if (!pango_skip_space(&p))
break;
i++;
}
if (i<3) {
fprintf(stderr, "Error reading modules file");
have_error = TRUE;
goto error;
}
ranges = g_list_reverse(ranges);
pair->info.n_ranges = g_list_length(ranges);
pair->info.ranges = g_new(PangoEngineRange, pair->info.n_ranges);
tmp_list = ranges;
for (i=0; i<pair->info.n_ranges; i++) {
pair->info.ranges[i] = *(PangoEngineRange *)tmp_list->data;
tmp_list = tmp_list->next;
}
pair->engine = NULL;
dlloaded_engines = g_slist_prepend(dlloaded_engines, pair);
error:
g_list_foreach(ranges, (GFunc)g_free, NULL);
g_list_free(ranges);
if (have_error) {
g_free(pair);
break;
}
}
g_string_free(line_buf, TRUE);
g_string_free(tmp_buf, TRUE);
return !have_error;
}
static void
read_modules(void)
{
FILE *module_file;
char *file_str = pango_config_key_get("Pango/ModuleFiles");
char **files;
int n;
if (!file_str)
file_str = g_strconcat(pango_get_sysconf_subdirectory(),
G_DIR_SEPARATOR_S "pango.modules", NULL);
files = pango_split_file_list(file_str);
n = 0;
while (files[n])
n++;
while (n-- > 0) {
module_file = fopen(files[n], "r");
if (!module_file)
g_warning("Error opening module file '%s': %s\n", files[n], g_strerror(errno));
else {
process_module_file(module_file);
fclose(module_file);
}
}
g_strfreev(files);
g_free(file_str);
dlloaded_engines = g_slist_reverse(dlloaded_engines);
}
static void
set_entry(PangoMapEntry *entry, gboolean is_exact, PangoEngineInfo *info)
{
if ((is_exact && !entry->is_exact) || !entry->info) {
entry->is_exact = is_exact;
entry->info = info;
}
}
static void
init_modules(void)
{
static gboolean init = FALSE;
if (init)
return;
else
init = TRUE;
read_modules();
}
static void
map_add_engine(PangoMapInfo *info, PangoEnginePair *pair)
{
int i, j, submap;
PangoMap *map = info->map;
for (i=0; i<pair->info.n_ranges; i++) {
gchar **langs;
gboolean is_exact = FALSE;
if (pair->info.ranges[i].langs) {
langs = g_strsplit(pair->info.ranges[i].langs, ";", -1);
for (j=0; langs[j]; j++)
if (strcmp(langs[j], "*") == 0 || strcmp(langs[j], info->lang) == 0) {
is_exact = TRUE;
break;
}
g_strfreev(langs);
}
for (submap = pair->info.ranges[i].start / 256;
submap <= pair->info.ranges[i].end / 256; submap ++) {
gunichar start;
gunichar end;
if (submap == pair->info.ranges[i].start / 256)
start = pair->info.ranges[i].start % 256;
else
start = 0;
if (submap == pair->info.ranges[i].end / 256)
end = pair->info.ranges[i].end % 256;
else
end = 255;
if (map->submaps[submap].is_leaf && start == 0 && end == 255) {
set_entry(&map->submaps[submap].d.entry, is_exact, &pair->info);
}
else {
if (map->submaps[submap].is_leaf) {
map->submaps[submap].is_leaf = FALSE;
map->submaps[submap].d.leaves = g_new(PangoMapEntry, 256);
for (j=0; j<256; j++) {
map->submaps[submap].d.leaves[j].info = NULL;
map->submaps[submap].d.leaves[j].is_exact = FALSE;
}
}
for (j=start; j<=end; j++)
set_entry(&map->submaps[submap].d.leaves[j], is_exact, &pair->info);
}
}
}
}
static void
map_add_engine_list(PangoMapInfo *info,
GSList *engines,
const char *engine_type,
const char *render_type)
{
GSList *tmp_list = engines;
while (tmp_list) {
PangoEnginePair *pair = tmp_list->data;
tmp_list = tmp_list->next;
if (strcmp(pair->info.engine_type, engine_type) == 0 &&
strcmp(pair->info.render_type, render_type) == 0) {
map_add_engine(info, pair);
}
}
}
static void
build_map(PangoMapInfo *info)
{
int i;
PangoMap *map;
const char *engine_type = g_quark_to_string(info->engine_type_id);
const char *render_type = g_quark_to_string(info->render_type_id);
init_modules();
info->map = map = g_new(PangoMap, 1);
map->n_submaps = 0;
for (i=0; i<256; i++) {
map->submaps[i].is_leaf = TRUE;
map->submaps[i].d.entry.info = NULL;
map->submaps[i].d.entry.is_exact = FALSE;
}
map_add_engine_list(info, dlloaded_engines, engine_type, render_type);
map_add_engine_list(info, registered_engines, engine_type, render_type);
map_add_engine_list(info, builtin_engines, engine_type, render_type);
}
/**
* pango_map_get_entry:
* @map: a #PangoMap
* @wc: an ISO-10646 codepoint
*
* Returns the entry in the map for a given codepoint. The entry
* contains information about engine that should be used for
* the codepoint and also whether the engine matches the language
* tag for the map was created exactly or just approximately.
*
* Return value: the #PangoMapEntry for the codepoint. This value
* is owned by the #PangoMap and should not be freed.
**/
PangoMapEntry *
pango_map_get_entry(PangoMap *map, guint32 wc)
{
PangoSubmap *submap = &map->submaps[wc / 256];
return submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256];
}
/**
* pango_map_get_engine:
* @map: a #PangoMap
* @wc: an ISO-10646 codepoint
*
* Returns the engine listed in the map for a given codepoint.
*
* Return value: the engine, if one is listed for the codepoint,
* or %NULL. The lookup may cause the engine to be loaded;
* once an engine is loaded
**/
PangoEngine *
pango_map_get_engine(PangoMap *map, guint32 wc)
{
PangoSubmap *submap = &map->submaps[wc / 256];
PangoMapEntry *entry = submap->is_leaf ? &submap->d.entry :
&submap->d.leaves[wc % 256];
if (entry->info)
return pango_engine_pair_get_engine((PangoEnginePair *)entry->info);
else
return NULL;
}
/**
* pango_module_register:
* @module: a #PangoIncludedModule
*
* Registers a statically linked module with Pango. The
* #PangoIncludedModule structure that is passed in contains the
* functions that would otherwise be loaded from a dynamically loaded
* module.
**/
void
pango_module_register(PangoIncludedModule *module)
{
GSList *tmp_list = NULL;
handle_included_module(module, &tmp_list);
registered_engines = g_slist_concat(registered_engines,
g_slist_reverse(tmp_list));
}

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

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* modules.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) 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/pango-engine.h>
#include <pango/pango-modules.h>
#ifndef __MODULES_H__
#define __MODULES_H__
extern PangoIncludedModule _pango_included_x_modules[];
extern PangoIncludedModule _pango_included_xft_modules[];
extern PangoIncludedModule _pango_included_ft2_modules[];
extern PangoIncludedModule _pango_included_win32_modules[];
#endif /* __MODULES_H__ */

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

@ -0,0 +1,473 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-coverage.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):
*
* 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 <string.h>
#include "pango-coverage.h"
typedef struct _PangoBlockInfo PangoBlockInfo;
#define N_BLOCKS_INCREMENT 256
/* The structure of a PangoCoverage object is a two-level table,
with blocks of size 256. Each block is stored as a packed array of 2 bit
values for each index, in LSB order.
*/
struct _PangoBlockInfo
{
guchar *data;
PangoCoverageLevel level; /* Used if data == NULL */
};
struct _PangoCoverage
{
guint ref_count;
int n_blocks;
int data_size;
PangoBlockInfo *blocks;
};
/**
* pango_coverage_new:
*
* Create a new #PangoCoverage
*
* Return value: a new PangoCoverage object, initialized to
* %PANGO_COVERAGE_NONE with a reference count of 0.
**/
PangoCoverage *
pango_coverage_new (void)
{
PangoCoverage *coverage = g_new (PangoCoverage, 1);
coverage->n_blocks = N_BLOCKS_INCREMENT;
coverage->blocks = g_new0 (PangoBlockInfo, coverage->n_blocks);
coverage->ref_count = 1;
return coverage;
}
/**
* pango_coverage_copy:
* @coverage: a #PangoCoverage
*
* Copy an existing #PangoCoverage. (This function may now be unecessary
* since we refcount the structure. Mail otaylor@redhat.com if you
* use it.)
*
* Return value: a copy of @coverage with a reference count of 1
**/
PangoCoverage *
pango_coverage_copy (PangoCoverage *coverage)
{
int i;
PangoCoverage *result;
g_return_val_if_fail (coverage != NULL, NULL);
result = g_new (PangoCoverage, 1);
result->n_blocks = coverage->n_blocks;
result->blocks = g_new (PangoBlockInfo, coverage->n_blocks);
result->ref_count = 1;
for (i=0; i<coverage->n_blocks; i++) {
if (coverage->blocks[i].data) {
result->blocks[i].data = g_new (guchar, 64);
memcpy (result->blocks[i].data, coverage->blocks[i].data, 64);
}
else
result->blocks[i].data = NULL;
result->blocks[i].level = coverage->blocks[i].level;
}
return result;
}
/**
* pango_coverage_ref:
* @coverage: a #PangoCoverage
*
* Increase the reference count on the #PangoCoverage by one
*
* Returns: @coverage
**/
PangoCoverage *
pango_coverage_ref (PangoCoverage *coverage)
{
g_return_val_if_fail (coverage != NULL, NULL);
coverage->ref_count++;
return coverage;
}
/**
* pango_coverage_unref:
* @coverage: a #PangoCoverage
*
* Increase the reference count on the #PangoCoverage by one.
* if the result is zero, free the coverage and all associated memory.
**/
void
pango_coverage_unref (PangoCoverage *coverage)
{
int i;
g_return_if_fail (coverage != NULL);
g_return_if_fail (coverage->ref_count > 0);
coverage->ref_count--;
if (coverage->ref_count == 0) {
for (i=0; i<coverage->n_blocks; i++) {
if (coverage->blocks[i].data)
g_free (coverage->blocks[i].data);
}
g_free (coverage->blocks);
g_free (coverage);
}
}
/**
* pango_coverage_get:
* @coverage: a #PangoCoverage
* @index: the index to check
*
* Determine whether a particular index is covered by @coverage
*
* Return value:
**/
PangoCoverageLevel
pango_coverage_get (PangoCoverage *coverage, int index)
{
int block_index;
g_return_val_if_fail (coverage != NULL, PANGO_COVERAGE_NONE);
block_index = index / 256;
if (block_index > coverage->n_blocks)
return PANGO_COVERAGE_NONE;
else {
guchar *data = coverage->blocks[block_index].data;
if (data) {
int i = index % 256;
int shift = (i % 4) * 2;
return (data[i/4] >> shift) & 0x3;
}
else
return coverage->blocks[block_index].level;
}
}
/**
* pango_coverage_set:
* @coverage: a #PangoCoverage
* @index: the index to modify
* @level: the new level for @index
*
* Modify a particular index within @coverage
**/
void pango_coverage_set (PangoCoverage *coverage,
int index,
PangoCoverageLevel level)
{
int block_index, i;
guchar *data;
g_return_if_fail (coverage != NULL);
g_return_if_fail (level >= 0 || level <= 3);
block_index = index / 256;
if (block_index > coverage->n_blocks) {
int old_n_blocks = coverage->n_blocks;
coverage->n_blocks =
N_BLOCKS_INCREMENT * ((block_index + N_BLOCKS_INCREMENT - 1) / N_BLOCKS_INCREMENT);
coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks);
memset (coverage->blocks + old_n_blocks, 0,
sizeof (PangoBlockInfo) * (coverage->n_blocks - old_n_blocks));
}
data = coverage->blocks[block_index].data;
if (!data) {
guchar byte;
if (level == coverage->blocks[block_index].level)
return;
data = g_new (guchar, 64);
coverage->blocks[block_index].data = data;
byte = coverage->blocks[block_index].level |
(coverage->blocks[block_index].level << 2) |
(coverage->blocks[block_index].level << 4) |
(coverage->blocks[block_index].level << 6);
memset (data, byte, 64);
}
i = index % 256;
data[i/4] |= level << ((i % 4) * 2);
}
/**
* pango_coverage_max:
* @coverage: a #PangoCoverage
* @other: another #PangoCoverage
*
* Set the coverage for each index in @coverage to be the max (better)
* value of the current coverage for the index and the coverage for
* the corresponding index in @other.
**/
void pango_coverage_max (PangoCoverage *coverage, PangoCoverage *other)
{
int block_index, i;
int old_blocks;
g_return_if_fail (coverage != NULL);
old_blocks = MIN (coverage->n_blocks, other->n_blocks);
if (other->n_blocks > coverage->n_blocks) {
coverage->n_blocks = other->n_blocks;
coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks);
for (block_index = old_blocks; block_index < coverage->n_blocks;
block_index++) {
if (other->blocks[block_index].data) {
coverage->blocks[block_index].data = g_new (guchar, 64);
memcpy (coverage->blocks[block_index].data,
other->blocks[block_index].data, 64);
}
else
coverage->blocks[block_index].data = NULL;
coverage->blocks[block_index].level = other->blocks[block_index].level;
}
}
for (block_index = 0; block_index < old_blocks; block_index++) {
if (!coverage->blocks[block_index].data && !other->blocks[block_index].data) {
coverage->blocks[block_index].level = MAX (coverage->blocks[block_index].level, other->blocks[block_index].level);
}
else if (coverage->blocks[block_index].data && other->blocks[block_index].data) {
guchar *data = coverage->blocks[block_index].data;
for (i=0; i<64; i++) {
int byte1 = data[i];
int byte2 = other->blocks[block_index].data[i];
/* There are almost certainly some clever logical ops to do this */
data[i] =
MAX (byte1 & 0x3, byte2 & 0x3) |
MAX (byte1 & 0xc, byte2 & 0xc) |
MAX (byte1 & 0x30, byte2 & 0x30) |
MAX (byte1 & 0xc0, byte2 & 0xc00);
}
}
else {
guchar *src, *dest;
int level, byte2;
if (coverage->blocks[block_index].data) {
src = dest = coverage->blocks[block_index].data;
level = other->blocks[block_index].level;
}
else {
src = other->blocks[block_index].data;
dest = g_new (guchar, 64);
coverage->blocks[block_index].data = dest;
level = coverage->blocks[block_index].level;
}
byte2 = level | (level << 2) | (level << 4) | (level << 6);
for (i=0; i<64; i++) {
int byte1 = src[i];
/* There are almost certainly some clever logical ops to do this */
dest[i] =
MAX (byte1 & 0x3, byte2 & 0x3) |
MAX (byte1 & 0xc, byte2 & 0xc) |
MAX (byte1 & 0x30, byte2 & 0x30) |
MAX (byte1 & 0xc0, byte2 & 0xc00);
}
}
}
}
#define PANGO_COVERAGE_MAGIC 0xc89dbd5e
/**
* pango_coverage_to_bytes:
* @coverage: a #PangoCoverage
* @bytes: location to store result (must be freed with g_free())
* @n_bytes: location to store size of result
*
* Convert a PangoCoverage structure into a flat binary format
**/
void
pango_coverage_to_bytes(PangoCoverage *coverage,
guchar **bytes,
int *n_bytes)
{
int i, j;
int size = 8 + 4 * coverage->n_blocks;
guchar *data;
int offset;
for (i=0; i<coverage->n_blocks; i++) {
if (coverage->blocks[i].data)
size += 64;
}
data = g_malloc (size);
*(guint32 *)&data[0] = g_htonl (PANGO_COVERAGE_MAGIC); /* Magic */
*(guint32 *)&data[4] = g_htonl (coverage->n_blocks);
offset = 8;
for (i=0; i<coverage->n_blocks; i++) {
guint32 header_val;
/* Check for solid blocks. This is a sort of random place
* to do the optimization, but we care most about getting
* it right when storing it somewhere persistant.
*/
if (coverage->blocks[i].data != NULL) {
guchar *data = coverage->blocks[i].data;
guchar first_val = data[0];
for (j = 1 ; j < 64; j++)
if (data[j] != first_val)
break;
if (j == 64) {
g_free (data);
coverage->blocks[i].data = NULL;
coverage->blocks[i].level = first_val & 0x3;
}
}
if (coverage->blocks[i].data != NULL)
header_val = (guint32)-1;
else
header_val = coverage->blocks[i].level;
*(guint32 *)&data[offset] = g_htonl (header_val);
offset += 4;
if (coverage->blocks[i].data) {
memcpy (data + offset, coverage->blocks[i].data, 64);
offset += 64;
}
}
*bytes = data;
*n_bytes = size;
}
static guint32
pango_coverage_get_uint32 (guchar **ptr)
{
guint32 val;
memcpy (&val, *ptr, 4);
*ptr += 4;
return g_ntohl (val);
}
/**
* pango_coverage_from_bytes:
* @bytes: binary data representing a #PangoCoverage
* @n_bytes: the size of @bytes in bytes
*
* Convert data generated from pango_converage_to_bytes() back
* to a #PangoCoverage
*
* Return value: a newly allocated #PangoCoverage, or NULL if
* the data was invalid.
**/
PangoCoverage *
pango_coverage_from_bytes (guchar *bytes, int n_bytes)
{
PangoCoverage *coverage = g_new0 (PangoCoverage, 1);
guchar *ptr = bytes;
int i;
coverage->ref_count = 1;
if (n_bytes < 8)
goto error;
if (pango_coverage_get_uint32 (&ptr) != PANGO_COVERAGE_MAGIC)
goto error;
coverage->n_blocks = pango_coverage_get_uint32 (&ptr);
coverage->blocks = g_new0 (PangoBlockInfo, coverage->n_blocks);
for (i = 0; i < coverage->n_blocks; i++) {
guint val;
if (ptr + 4 > bytes + n_bytes)
goto error;
val = pango_coverage_get_uint32 (&ptr);
if (val == (guint32)-1) {
if (ptr + 64 > bytes + n_bytes)
goto error;
coverage->blocks[i].data = g_new (guchar, 64);
memcpy (coverage->blocks[i].data, ptr, 64);
ptr += 64;
}
else
coverage->blocks[i].level = val;
}
return coverage;
error:
pango_coverage_unref (coverage);
return NULL;
}

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

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-coverage.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) 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.
*/
#ifndef __PANGO_COVERAGE_H__
#define __PANGO_COVERAGE_H__
#include <glib.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _PangoCoverage PangoCoverage;
typedef enum {
PANGO_COVERAGE_NONE,
PANGO_COVERAGE_FALLBACK,
PANGO_COVERAGE_APPROXIMATE,
PANGO_COVERAGE_EXACT
} PangoCoverageLevel;
PangoCoverage * pango_coverage_new (void);
PangoCoverage * pango_coverage_ref (PangoCoverage *coverage);
void pango_coverage_unref (PangoCoverage *coverage);
PangoCoverage * pango_coverage_copy (PangoCoverage *coverage);
PangoCoverageLevel pango_coverage_get (PangoCoverage *coverage,
int index);
void pango_coverage_set (PangoCoverage *coverage,
int index,
PangoCoverageLevel level);
void pango_coverage_max (PangoCoverage *coverage,
PangoCoverage *other);
void pango_coverage_to_bytes (PangoCoverage *coverage,
guchar **bytes,
int *n_bytes);
PangoCoverage *pango_coverage_from_bytes (guchar *bytes,
int n_bytes);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_COVERAGE_H__ */

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

@ -0,0 +1,100 @@
/* -*- 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 gunichar2 *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__ */

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

@ -0,0 +1,116 @@
/* -*- 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 gunichar2 *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,72 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-modules.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) 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.
*/
#ifndef __PANGO_MODULES_H__
#define __PANGO_MODULES_H__
#include "pango-engine.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _PangoMap PangoMap;
typedef struct _PangoMapEntry PangoMapEntry;
struct _PangoMapEntry
{
PangoEngineInfo *info;
gboolean is_exact;
};
typedef struct _PangoIncludedModule PangoIncludedModule;
struct _PangoIncludedModule
{
void (*list) (PangoEngineInfo **engines, int *n_engines);
PangoEngine *(*load) (const char *id);
void (*unload) (PangoEngine *engine);
};
PangoMap *pango_find_map(const char *lang, guint engine_type_id,
guint render_type_id);
PangoMapEntry *pango_map_get_entry(PangoMap *map, guint32 wc);
PangoEngine *pango_map_get_engine(PangoMap *map, guint32 wc);
void pango_module_register(PangoIncludedModule *module);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_MODULES_H__ */

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

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-types.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) 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.
*/
#ifndef __PANGO_TYPES_H__
#define __PANGO_TYPES_H__
#include <glib.h>
typedef struct _PangoLangRange PangoLangRange;
typedef struct _PangoLogAttr PangoLogAttr;
typedef struct _PangoEngineShape PangoEngineShape;
/* A index of a glyph into a font. Rendering system dependent
*/
typedef guint32 PangoGlyph;
/* Information about a segment of text with a consistent
* shaping/language engine and bidirectional level
*/
typedef enum {
PANGO_DIRECTION_LTR,
PANGO_DIRECTION_RTL,
PANGO_DIRECTION_TTB_LTR,
PANGO_DIRECTION_TTB_RTL
} PangoDirection;
/* Language tagging information
*/
struct _PangoLangRange
{
gint start;
gint length;
gchar *lang;
};
/* Will be of more use when run information is stored */
typedef struct _PangoAnalysis PangoAnalysis;
struct _PangoAnalysis
{
char *fontCharset;
PangoEngineShape *shape_engine;
/* guint8 level; */
PangoDirection aDir;
};
typedef guint32 gunichar;
typedef guint16 gunichar2;
#define G_CONST_RETURN const
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_TYPES_H__ */

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

@ -0,0 +1,766 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-utils.c: Utilities for internal functions and modules
*
* 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.
*/
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "pango-utils.h"
#ifdef HAVE_FRIBIDI
#include <fribidi/fribidi.h>
#endif
#ifndef HAVE_FLOCKFILE
#define flockfile(f) (void)1
#define funlockfile(f) (void)1
#define getc_unlocked(f) getc(f)
#endif /* !HAVE_FLOCKFILE */
#ifdef G_OS_WIN32
#include <sys/types.h>
#define STRICT
#include <windows.h>
#endif
#define UTF8_COMPUTE(Char, Mask, Len) \
if (Char < 128) { \
Len = 1; \
Mask = 0x7f; \
} \
else if ((Char & 0xe0) == 0xc0) { \
Len = 2; \
Mask = 0x1f; \
} \
else if ((Char & 0xf0) == 0xe0) { \
Len = 3; \
Mask = 0x0f; \
} \
else if ((Char & 0xf8) == 0xf0) { \
Len = 4; \
Mask = 0x07; \
} \
else if ((Char & 0xfc) == 0xf8) { \
Len = 5; \
Mask = 0x03; \
} \
else if ((Char & 0xfe) == 0xfc) { \
Len = 6; \
Mask = 0x01; \
} \
else \
Len = -1;
#define UTF8_LENGTH(Char) \
((Char) < 0x80 ? 1 : \
((Char) < 0x800 ? 2 : \
((Char) < 0x10000 ? 3 : \
((Char) < 0x200000 ? 4 : \
((Char) < 0x4000000 ? 5 : 6)))))
#define UTF8_GET(Result, Chars, Count, Mask, Len) \
(Result) = (Chars)[0] & (Mask); \
for ((Count) = 1; (Count) < (Len); ++(Count)) { \
if (((Chars)[(Count)] & 0xc0) != 0x80) { \
(Result) = -1; \
break; \
} \
(Result) <<= 6; \
(Result) |= ((Chars)[(Count)] & 0x3f); \
}
#define UNICODE_VALID(Char) \
((Char) < 0x110000 && ((Char) < 0xD800 || (Char) >= 0xE000) && \
(Char) != 0xFFFE && (Char) != 0xFFFF)
/**
* pango_trim_string:
* @str: a string
*
* Trim leading and trailing whitespace from a string.
*
* Return value: A newly allocated string that must be freed with g_free()
**/
char *
pango_trim_string (const char *str)
{
int len;
g_return_val_if_fail (str != NULL, NULL);
while (*str && isspace (*str))
str++;
len = strlen (str);
while (len > 0 && isspace (str[len-1]))
len--;
return g_strndup (str, len);
}
/**
* pango_split_file_list:
* @str: a comma separated list of filenames
*
* Split a G_SEARCHPATH_SEPARATOR-separated list of files, stripping
* white space and subsituting ~/ with $HOME/
*
* Return value: a list of strings to be freed with g_strfreev()
**/
char **
pango_split_file_list (const char *str)
{
int i = 0;
int j;
char **files;
files = g_strsplit (str, G_SEARCHPATH_SEPARATOR_S, -1);
while (files[i])
{
char *file = pango_trim_string (files[i]);
/* If the resulting file is empty, skip it */
if (file[0] == '\0')
{
g_free(file);
g_free (files[i]);
for (j = i + 1; files[j]; j++)
files[j - 1] = files[j];
files[j - 1] = NULL;
continue;
}
#ifndef G_OS_WIN32
/* '~' is a quite normal and common character in file names on
* Windows, especially in the 8.3 versions of long file names, which
* still occur and then. Also, few Windows user are aware of the
* Unix shell convention that '~' stands for the home directory,
* even if they happen to have a home directory.
*/
if (file[0] == '~' && file[1] == G_DIR_SEPARATOR)
{
char *tmp = g_strconcat (g_get_home_dir(), file + 1, NULL);
g_free (file);
file = tmp;
}
#endif
g_free (files[i]);
files[i] = file;
i++;
}
return files;
}
/**
* pango_read_line:
* @stream: a stdio stream
* @str: #GString buffer into which to write the result
*
* Read an entire line from a file into a buffer. Lines may
* be delimited with '\n', '\r', '\n\r', or '\r\n'. The delimiter
* is not written into the buffer. Text after a '#' character is treated as
* a comment and skipped. '\' can be used to escape a # character.
* '\' proceding a line delimiter combines adjacent lines. A '\' proceding
* any other character is ignored and written into the output buffer
* unmodified.
*
* Return value: 0 if the stream was already at an EOF character, otherwise
* the number of lines read (this is useful for maintaining
* a line number counter which doesn't combine lines with \)
**/
gint
pango_read_line (FILE *stream, GString *str)
{
gboolean quoted = FALSE;
gboolean comment = FALSE;
int n_read = 0;
int lines = 1;
flockfile (stream);
g_string_truncate (str, 0);
while (1)
{
int c;
c = getc_unlocked (stream);
if (c == EOF)
{
if (quoted)
g_string_append_c (str, '\\');
goto done;
}
else
n_read++;
if (quoted)
{
quoted = FALSE;
switch (c)
{
case '#':
g_string_append_c (str, '#');
break;
case '\r':
case '\n':
{
int next_c = getc_unlocked (stream);
if (!(next_c == EOF ||
(c == '\r' && next_c == '\n') ||
(c == '\n' && next_c == '\r')))
ungetc (next_c, stream);
lines++;
break;
}
default:
g_string_append_c (str, '\\');
g_string_append_c (str, c);
}
}
else
{
switch (c)
{
case '#':
comment = TRUE;
break;
case '\\':
if (!comment)
quoted = TRUE;
break;
case '\n':
{
int next_c = getc_unlocked (stream);
if (!(c == EOF ||
(c == '\r' && next_c == '\n') ||
(c == '\n' && next_c == '\r')))
ungetc (next_c, stream);
goto done;
}
default:
if (!comment)
g_string_append_c (str, c);
}
}
}
done:
funlockfile (stream);
return (n_read > 0) ? lines : 0;
}
/**
* pango_skip_space:
* @pos: in/out string position
*
* Skips 0 or more characters of white space.
*
* Return value: %FALSE if skipping the white space leaves
* the position at a '\0' character.
**/
gboolean
pango_skip_space (const char **pos)
{
const char *p = *pos;
while (isspace (*p))
p++;
*pos = p;
return !(*p == '\0');
}
/**
* pango_scan_word:
* @pos: in/out string position
* @out: a #GString into which to write the result
*
* Scan a word into a #GString buffer. A word consists
* of [A-Za-z_] followed by zero or more [A-Za-z_0-9]
* Leading white space is skipped.
*
* Return value: %FALSE if a parse error occured.
**/
gboolean
pango_scan_word (const char **pos, GString *out)
{
const char *p = *pos;
while (isspace (*p))
p++;
if (!((*p >= 'A' && *p <= 'Z') ||
(*p >= 'a' && *p <= 'z') ||
*p == '_'))
return FALSE;
g_string_truncate (out, 0);
g_string_append_c (out, *p);
p++;
while ((*p >= 'A' && *p <= 'Z') ||
(*p >= 'a' && *p <= 'z') ||
(*p >= '0' && *p <= '9') ||
*p == '_')
{
g_string_append_c (out, *p);
p++;
}
*pos = p;
return TRUE;
}
/**
* pango_scan_string:
* @pos: in/out string position
* @out: a #GString into which to write the result
*
* Scan a string into a #GString buffer. The string may either
* be a sequence of non-white-space characters, or a quoted
* string with '"'. Instead a quoted string, '\"' represents
* a literal quote. Leading white space outside of quotes is skipped.
*
* Return value: %FALSE if a parse error occured.
**/
gboolean
pango_scan_string (const char **pos, GString *out)
{
const char *p = *pos;
while (isspace (*p))
p++;
if (!*p)
return FALSE;
else if (*p == '"')
{
gboolean quoted = FALSE;
g_string_truncate (out, 0);
p++;
while (TRUE)
{
if (quoted)
{
int c = *p;
switch (c)
{
case '\0':
return FALSE;
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
}
quoted = FALSE;
g_string_append_c (out, c);
}
else
{
switch (*p)
{
case '\0':
return FALSE;
case '\\':
quoted = TRUE;
break;
case '"':
p++;
goto done;
default:
g_string_append_c (out, *p);
break;
}
}
p++;
}
done:
;
}
else
{
g_string_truncate (out, 0);
while (*p && !isspace (*p))
{
g_string_append_c (out, *p);
p++;
}
}
*pos = p;
return TRUE;
}
gboolean
pango_scan_int (const char **pos, int *out)
{
int i = 0;
char buf[32];
const char *p = *pos;
while (isspace (*p))
p++;
if (*p < '0' || *p > '9')
return FALSE;
while ((*p >= '0') && (*p <= '9') && i < sizeof(buf))
{
buf[i] = *p;
i++;
p++;
}
if (i == sizeof(buf))
return FALSE;
else
buf[i] = '\0';
*out = atoi (buf);
return TRUE;
}
static GHashTable *config_hash = NULL;
static void
read_config_file (const char *filename, gboolean enoent_error)
{
FILE *file;
GString *line_buffer;
GString *tmp_buffer1;
GString *tmp_buffer2;
char *errstring = NULL;
const char *pos;
char *section = NULL;
int line = 0;
file = fopen (filename, "r");
if (!file)
{
if (errno != ENOENT || enoent_error)
fprintf (stderr, "Pango:%s: Error opening config file: %s\n",
filename, g_strerror (errno));
return;
}
line_buffer = g_string_new (NULL);
tmp_buffer1 = g_string_new (NULL);
tmp_buffer2 = g_string_new (NULL);
while (pango_read_line (file, line_buffer))
{
line++;
pos = line_buffer->str;
if (!pango_skip_space (&pos))
continue;
if (*pos == '[') /* Section */
{
pos++;
if (!pango_skip_space (&pos) ||
!pango_scan_word (&pos, tmp_buffer1) ||
!pango_skip_space (&pos) ||
*(pos++) != ']' ||
pango_skip_space (&pos))
{
errstring = g_strdup ("Error parsing [SECTION] declaration");
goto error;
}
section = g_strdup (tmp_buffer1->str);
}
else /* Key */
{
gboolean empty = FALSE;
gboolean append = FALSE;
char *k, *v;
if (!section)
{
errstring = g_strdup ("A [SECTION] declaration must occur first");
goto error;
}
if (!pango_scan_word (&pos, tmp_buffer1) ||
!pango_skip_space (&pos))
{
errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
goto error;
}
if (*pos == '+')
{
append = TRUE;
pos++;
}
if (*(pos++) != '=')
{
errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
goto error;
}
if (!pango_skip_space (&pos))
{
empty = TRUE;
}
else
{
if (!pango_scan_string (&pos, tmp_buffer2))
{
errstring = g_strdup ("Error parsing value string");
goto error;
}
if (pango_skip_space (&pos))
{
errstring = g_strdup ("Junk after value string");
goto error;
}
}
g_string_prepend_c (tmp_buffer1, '/');
g_string_prepend (tmp_buffer1, section);
/* Remove any existing values */
if (g_hash_table_lookup_extended (config_hash, tmp_buffer1->str,
(gpointer *)&k, (gpointer *)&v))
{
g_free (k);
if (append)
{
g_string_prepend (tmp_buffer2, v);
g_free (v);
}
}
if (!empty)
{
g_hash_table_insert (config_hash,
g_strdup (tmp_buffer1->str),
g_strdup (tmp_buffer2->str));
}
}
}
if (ferror (file))
errstring = g_strdup ("g_strerror(errno)");
error:
if (errstring)
{
fprintf (stderr, "Pango:%s:%d: %s\n", filename, line, errstring);
g_free (errstring);
}
g_free (section);
g_string_free (line_buffer, TRUE);
g_string_free (tmp_buffer1, TRUE);
g_string_free (tmp_buffer2, TRUE);
fclose (file);
}
static void
read_config ()
{
if (!config_hash)
{
char *filename;
char *home;
config_hash = g_hash_table_new (g_str_hash, g_str_equal);
filename = g_strconcat (pango_get_sysconf_subdirectory (),
G_DIR_SEPARATOR_S "pangorc",
NULL);
read_config_file (filename, FALSE);
g_free (filename);
home = g_get_home_dir ();
if (home && *home)
{
filename = g_strconcat (home,
G_DIR_SEPARATOR_S ".pangorc",
NULL);
read_config_file (filename, FALSE);
g_free (filename);
}
filename = g_getenv ("PANGO_RC_FILE");
if (filename)
read_config_file (filename, TRUE);
}
}
/**
* pango_config_key_get:
* @key: Key to look up, in the form "SECTION/KEY".
*
* Look up a key in the pango config database
* (pseudo-win.ini style, read from $sysconfdir/pango/pangorc,
* ~/.pangorc, and getenv (PANGO_RC_FILE).)
*
* Return value: the value, if found, otherwise %NULL. The value is a
* newly-allocated string and must be freed with g_free().
**/
char *
pango_config_key_get (const char *key)
{
g_return_val_if_fail (key != NULL, NULL);
read_config ();
return g_strdup (g_hash_table_lookup (config_hash, key));
}
G_CONST_RETURN char *
pango_get_sysconf_subdirectory (void)
{
#ifdef G_OS_WIN32
static gchar *result = NULL;
if (result == NULL)
result = g_win32_get_package_installation_subdirectory
("pango", g_strdup_printf ("pango-%s.dll", PANGO_VERSION), "etc\\pango");
return result;
// Am open to any other way of doing this
// Bottomline : need to provide path to pango.modules
/* Currently set to dist/bin - Am open to other location */
#else
char *tmp = getenv("MOZILLA_FIVE_HOME");
return tmp;
#endif
}
G_CONST_RETURN char *
pango_get_lib_subdirectory (void)
{
#ifdef G_OS_WIN32
static gchar *result = NULL;
if (result == NULL)
result = g_win32_get_package_installation_subdirectory
("pango", g_strdup_printf ("pango-%s.dll", PANGO_VERSION), "lib\\pango");
return result;
// Open to any other way of doing this
// Bottomline : need to provide path to pango libraries
// Currently set to dist/bin - Open to other locations
#else
char *tmp = getenv("MOZILLA_FIVE_HOME");
return tmp;
/* return "/home/prabhath/PROJ/opt/lib"; */
#endif
}
/**
* g_utf8_get_char:
* @p: a pointer to unicode character encoded as UTF-8
*
* Convert a sequence of bytes encoded as UTF-8 to a unicode character.
*
* Return value: the resulting character or (gunichar)-1 if @p does
* not point to a valid UTF-8 encoded unicode character
**/
gunichar
g_utf8_get_char (const gchar *p)
{
int i, mask = 0, len;
gunichar result;
unsigned char c = (unsigned char) *p;
UTF8_COMPUTE (c, mask, len);
if (len == -1)
return (gunichar)-1;
UTF8_GET (result, p, i, mask, len);
return result;
}
#ifdef HAVE_FRIBIDI
void
pango_log2vis_get_embedding_levels (gunichar *str,
int len,
PangoDirection *pbase_dir,
guint8 *embedding_level_list)
{
FriBidiCharType fribidi_base_dir;
fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ?
FRIBIDI_TYPE_L : FRIBIDI_TYPE_R;
fribidi_log2vis_get_embedding_levels(str, len, &fribidi_base_dir,
embedding_level_list);
*pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ?
PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;
}
gboolean
pango_get_mirror_char (gunichar ch, gunichar *mirrored_ch)
{
return fribidi_get_mirror_char (ch, mirrored_ch);
}
#endif /* HAVE_FRIBIDI */

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

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango-utils.h: Utilities for internal functions and modules
*
* 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.
*/
#include <stdio.h>
#include <glib.h>
#include "pango-types.h"
char *pango_trim_string(const char *str);
char **pango_split_file_list(const char *str);
gint pango_read_line(FILE *stream, GString *str);
gboolean pango_skip_space(const char **pos);
gboolean pango_scan_word(const char **pos, GString *out);
gboolean pango_scan_string(const char **pos, GString *out);
gboolean pango_scan_int(const char **pos, int *out);
char * pango_config_key_get(const char *key);
/* On Unix, return the name of the "pango" subdirectory of SYSCONFDIR
* (which is set at compile time). On Win32, return the Pango
* installation directory (which is set at installation time, and
* stored in the registry). The returned string should not be
* g_free'd.
*/
const char *pango_get_sysconf_subdirectory(void);
/* Ditto for LIBDIR/pango. On Win32, use the same Pango
* installation directory. This returned string should not be
* g_free'd either.
*/
const char *pango_get_lib_subdirectory (void);

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

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* pango.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) 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.
*/
#ifndef __PANGO_H__
#define __PANGO_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <pango/pango-engine.h>
#include <pango/pango-glyph.h>
#include <pango/pango-types.h>
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PANGO_H__ */

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

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

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

@ -0,0 +1,192 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* Pango
* querymodules.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):
*
* 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 "config.h"
#include <glib.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <gmodule.h>
#include "pango-break.h"
#include "pango-context.h"
#include "pango-utils.h"
#include "pango-engine.h"
#include <errno.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#ifdef G_OS_WIN32
#define SOEXT ".dll"
#ifndef PATH_MAX
#include <stdlib.h>
#define PATH_MAX _MAX_PATH
#endif /* PATH_MAX */
#include <direct.h> /* for getcwd() with MSVC */
#include <io.h> /* for getcwd() with mingw */
#define getcwd _getcwd
#else
#define SOEXT ".so"
#endif
void
query_module (const char *dir, const char *name)
{
void (*list) (PangoEngineInfo **engines, gint *n_engines);
PangoEngine *(*load) (const gchar *id);
void (*unload) (PangoEngine *engine);
GModule *module;
gchar *path;
if (name[0] == G_DIR_SEPARATOR)
path = g_strdup (name);
else
path = g_strconcat (dir, G_DIR_SEPARATOR_S, name, NULL);
module = g_module_open (path, 0);
if (!module)
fprintf(stderr, "Cannot load module %s: %s\n", path, g_module_error());
if (module &&
g_module_symbol (module, "script_engine_list", (gpointer)&list) &&
g_module_symbol (module, "script_engine_load", (gpointer)&load) &&
g_module_symbol (module, "script_engine_unload", (gpointer)&unload))
{
gint i,j;
PangoEngineInfo *engines;
gint n_engines;
(*list) (&engines, &n_engines);
for (i=0; i<n_engines; i++)
{
const gchar *quote;
gchar *quoted_path;
if (strchr (path, ' ') != NULL)
{
quote = "\"";
quoted_path = g_strescape (path, NULL);
}
else
{
quote = "";
quoted_path = g_strdup (path);
}
g_print ("%s%s%s %s %s %s ", quote, quoted_path, quote,
engines[i].id, engines[i].engine_type, engines[i].render_type);
g_free (quoted_path);
for (j=0; j < engines[i].n_ranges; j++)
{
if (j != 0)
g_print (" ");
g_print ("%d-%d:%s",
engines[i].ranges[j].start,
engines[i].ranges[j].end,
engines[i].ranges[j].langs);
}
g_print ("\n");
}
}
else
{
fprintf (stderr, "%s does not export Pango module API\n", path);
}
g_free (path);
if (module)
g_module_close (module);
}
int main (int argc, char **argv)
{
char cwd[PATH_MAX];
int i;
char *path;
printf ("# Pango Modules file\n"
"# Automatically generated file, do not edit\n"
"#\n");
if (argc == 1) /* No arguments given */
{
char **dirs;
int i;
path = pango_config_key_get ("Pango/ModulesPath");
if (!path)
path = g_strconcat (pango_get_lib_subdirectory (),
G_DIR_SEPARATOR_S "modules",
NULL);
printf ("# ModulesPath = %s\n#\n", path);
dirs = pango_split_file_list (path);
for (i=0; dirs[i]; i++)
{
DIR *dir = opendir (dirs[i]);
if (dir)
{
struct dirent *dent;
while ((dent = readdir (dir)))
{
int len = strlen (dent->d_name);
if (len > 3 && strcmp (dent->d_name + len - strlen (SOEXT), SOEXT) == 0)
query_module (dirs[i], dent->d_name);
}
closedir (dir);
}
}
}
else
{
getcwd (cwd, PATH_MAX);
for (i=1; i<argc; i++)
query_module (cwd, argv[i]);
}
return 0;
}

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

@ -0,0 +1,66 @@
/* -*- 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 gunichar2 *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);
}

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

@ -0,0 +1,59 @@
# 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.
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = mozpango-thaix
LIBRARY_NAME = mozpango-thaix
EXPORT_LIBRARY = 1
EXTRA_DSO_LIBS = mozpango
CSRCS = \
thai-x.c \
$(NULL)
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir)/../pangoLite \
$(NULL)
CFLAGS += $(GLIB_CFLAGS)
EXTRA_DSO_LDOPTS += \
-L$(DIST)/lib \
$(EXTRA_DSO_LIBS) \
$(GLIB_LIBS) \
$(GLIB_GMODULE_LIBS) \
$(NULL)

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

@ -0,0 +1,811 @@
/* -*- 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) ((gunichar2)(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,
gunichar2 *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,
gunichar2 *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,
gunichar2 *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 (gunichar2 cur_wc, gunichar2 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 gunichar2 *
get_next_cluster(const gunichar2 *text,
gint length,
gunichar2 *cluster,
gint *num_chrs)
{
const gunichar2 *p;
gint n_chars = 0;
p = text;
while (p < text + length && n_chars < 3) {
gunichar2 current = *p;
if (n_chars == 0 ||
is_wtt_composible ((gunichar2)(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++;
}
else
break;
}
*num_chrs = n_chars;
return p;
}
static void
thai_engine_shape(const char *fontCharset,
const gunichar2 *text,
gint length,
PangoAnalysis *analysis,
PangoGlyphString *glyphs)
{
ThaiFontInfo *font_info;
const gunichar2 *p;
const gunichar2 *log_cluster;
gunichar2 cluster[MAX_CLUSTER_CHRS];
gint num_chrs;
pango_glyph_string_set_size(glyphs, 0);
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) {
gunichar2 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)
{
}