зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
ec7e89fcd8
Коммит
b95b4ce51b
|
@ -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
|
||||
|
|
18
configure.in
18
configure.in
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
we should add the pango ctl code here
|
|
@ -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)
|
|
@ -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 */
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
}
|
Загрузка…
Ссылка в новой задаче