#include "xttversion.h"
#if 0
static char const * const releaseID =
_XTT_RELEASE_NAME;
#endif
#include "X.h"
#include "xttcommon.h"
#include "xttcconv.h"
#include "xttcconvP.h"
#ifndef FONTMODULE
# include "fontmisc.h"
#endif
#ifdef CCONV_MODULE
# ifndef FONTMODULE
# include <dlfcn.h>
# ifndef DL_OPTION
# ifdef RTLD_NOW
# define DL_OPTION RTLD_NOW
# else
# if defined(__NetBSD__) || defined(__OpenBSD__)
# define DL_OPTION DL_LAZY
# else
# define DL_OPTION 1
# endif
# endif
# endif
# ifndef DLOPEN
# define DLOPEN dlopen
# endif
# ifndef DLSYM
# define DLSYM dlsym
# endif
# ifndef DLCLOSE
# define DLCLOSE dlclose
# endif
# ifndef CCONV_MODULE_DIR
# define CCONV_MODULE_DIR "/usr/X11R6/lib/modules"
# endif
# ifndef CCONV_MODULE_SUBDIR
# define CCONV_MODULE_SUBDIR "codeconv"
# endif
# ifndef CCONV_MODULE_EXTENTION
# define CCONV_MODULE_EXTENTION ".so"
# endif
# define LEN_CCONV_MODULE_EXTENTION (sizeof(CCONV_MODULE_EXTENTION)-1)
# ifndef CCONV_ENTRYPOINT_POSTFIX
# define CCONV_ENTRYPOINT_POSTFIX "_entrypoint"
# endif
# define LEN_CCONV_ENTRYPOINT_POSTFIX (sizeof(CCONV_ENTRYPOINT_POSTFIX)-1)
static char *X_TT_CodeConvModulePath = NULL;
# else
# include "misc.h"
# include "fontmod.h"
# include "xf86Module.h"
# ifndef CCONV_MODULE_SUBDIR
# define CCONV_MODULE_SUBDIR "codeconv"
# endif
# ifndef CCONV_MODULE_EXTENTION
# ifndef DLOPEN_HACK
# define CCONV_MODULE_EXTENTION ".a"
# else
# define CCONV_MODULE_EXTENTION ".so"
# endif
# endif
# define LEN_CCONV_MODULE_EXTENTION (sizeof(CCONV_MODULE_EXTENTION)-1)
# ifndef CCONV_ENTRYPOINT_POSTFIX
# define CCONV_ENTRYPOINT_POSTFIX "_entrypoint"
# endif
# define LEN_CCONV_ENTRYPOINT_POSTFIX (sizeof(CCONV_ENTRYPOINT_POSTFIX)-1)
#ifdef CCONV_USE_SYMBOLIC_ENTRY_POINT
char *entryName = NULL;
static int entryNameAllocated = 0;
#endif
# endif
#endif
#if defined(CSRG_BASED) && !defined(__ELF__)
#define PREPEND_UNDERSCORE
#endif
#if 0
void*
mydlopen(const char *path, int mode)
{
void *ret;
ret = dlopen(path, mode);
fprintf(stderr, "dlopen(%s, %d)=%p\n", path, mode, ret);
if (NULL == ret)
fprintf(stderr, " (%s)\n", dlerror());
return ret;
}
mydlsym(void *handle, const char *symbol)
{
void *ret;
ret = dlsym(handle, symbol);
fprintf(stderr, "dlsym(%p, %s)=%p\n", handle, symbol, ret);
return ret;
}
mydlclose(void *handle)
{
int ret;
ret = dlclose(handle);
fprintf(stderr, "dlclose(%p)=%d\n", handle, ret);
return ret;
}
#endif
#ifdef FONTMODULE
extern FontModule xttModule;
DECLARE_SUBREQ(cconvSubReq)
static const char* convModuleSubdir[] = {
CCONV_MODULE_SUBDIR,
#if 0
"fonts/"CCONV_MODULE_SUBDIR,
#endif
NULL,
};
#endif
#ifndef CCONV_MODULE
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_1_entrypoint);
#ifdef OPT_ENCODINGS
ENTRYFUNC_PROTO_TEMPLATE(BIG5_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(BIG5HKSCS_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(GB2312_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(GBK_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(GB18030_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(JISX0201_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(JISX0208_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(JISX0212_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(KSC5601_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(KSCJOHAB_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_2_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_3_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_4_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_5_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_6_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_7_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_8_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_9_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_10_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_11_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_13_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_14_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ISO8859_15_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(KOI8_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(VISCII_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(TCVN_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ARMSCII8_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(ARABIC_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(MULEENCODING_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(DOSENCODING_entrypoint);
ENTRYFUNC_PROTO_TEMPLATE(GEORGIAN_entrypoint);
#endif
#endif
static mod_entrypoint_ptr_t preloadedCodeConverter[] = {
#ifdef CCONV_MODULE
#else
ISO8859_1_entrypoint,
#ifdef OPT_ENCODINGS
BIG5_entrypoint,
BIG5HKSCS_entrypoint,
GB2312_entrypoint,
GBK_entrypoint,
GB18030_entrypoint,
JISX0201_entrypoint,
JISX0208_entrypoint,
JISX0212_entrypoint,
KSC5601_entrypoint,
KSCJOHAB_entrypoint,
ISO8859_2_entrypoint,
ISO8859_3_entrypoint,
ISO8859_4_entrypoint,
ISO8859_5_entrypoint,
ISO8859_6_entrypoint,
ISO8859_7_entrypoint,
ISO8859_8_entrypoint,
ISO8859_9_entrypoint,
ISO8859_10_entrypoint,
ISO8859_11_entrypoint,
ISO8859_13_entrypoint,
ISO8859_14_entrypoint,
ISO8859_15_entrypoint,
KOI8_entrypoint,
VISCII_entrypoint,
TCVN_entrypoint,
ARMSCII8_entrypoint,
ARABIC_entrypoint,
MULEENCODING_entrypoint,
DOSENCODING_entrypoint,
GEORGIAN_entrypoint,
#endif
#endif
NULL
};
#if defined(FONTMODULE)
#define PPC_WORKAROUND
#ifdef PPC_WORKAROUND
typedef struct {
char const *charsetStdName;
char const *charsetYear;
char const *charsetEncoding;
char const *charsetPlane;
char const *moduleName;
} ModuleRelation;
static ModuleRelation moduleRelations[] =
{ { "mulearabic", NULL, "0", NULL, "ARABIC" },
{ "mulearabic", NULL, "1", NULL, "ARABIC" },
{ "mulearabic", NULL, "2", NULL, "ARABIC" },
{ "microsoft", NULL, "cp1256", NULL, "ARABIC" },
{ "xaterm", NULL, "fontspecific", NULL, "ARABIC" },
{ "isiri", NULL, "3342", NULL, "ARABIC" },
{ "iransystem", NULL, "0", NULL, "ARABIC" },
{ "urdunaqsh", NULL, "0", NULL, "ARABIC" },
{ "armscii", NULL, "8", NULL, "ARMSCII8" },
{ "big5", NULL, NULL, NULL, "BIG5" },
{ "big5hkscs", NULL, NULL, NULL, "BIG5HKSCS" },
{ "hkscs", NULL, NULL, NULL, "BIG5HKSCS" },
{ "ibm", NULL, "cp437", NULL, "DOSENCODING" },
{ "ibm", NULL, "cp850", NULL, "DOSENCODING" },
{ "microsoft", NULL, "cp1252", NULL, "DOSENCODING" },
{ "ansi", NULL, "0", NULL, "DOSENCODING" },
{ "microsoft", NULL, "win3.1", NULL, "DOSENCODING" },
{ "microsoft", NULL, "fontspecific", NULL, "DOSENCODING" },
{ "misc", NULL, "fontspecific", NULL, "DOSENCODING" },
{ "gb18030", "2000", "0", NULL, "GB18030" },
{ "gb18030", "2000", "1", NULL, "GB18030" },
{ "gb18030", NULL, "0", NULL, "GB18030" },
{ "gbk2k", NULL, "0", NULL, "GB18030" },
{ "gb2312", NULL, NULL, NULL, "GB2312" },
{ "gbk", NULL, NULL, NULL, "GBK" },
{ "georgian", NULL, "academy", NULL, "GEORGIAN" },
{ "georgian", NULL, "ps", NULL, "GEORGIAN" },
#ifndef I_HATE_UNICODE
{ "unicode", NULL, NULL, NULL, "ISO8859_1" },
{ "iso10646", NULL, "1", NULL, "ISO8859_1" },
#endif
{ "iso8859", NULL, "1", NULL, "ISO8859_1" },
{ "ascii", NULL, NULL, NULL, "ISO8859_1" },
{ "apple", NULL, "roman", NULL, "ISO8859_1" },
{ "apple", NULL, "centeuro", NULL, "ISO8859_1" },
{ "microsoft", NULL, "symbol", NULL, "ISO8859_1" },
{ "microsoft_symbol", NULL, NULL, NULL, "ISO8859_1" },
{ "ms", NULL, "symbol", NULL, "ISO8859_1" },
{ "ms_symbol", NULL, NULL, NULL, "ISO8859_1" },
{ "iso8859", NULL, "10", NULL, "ISO8859_10" },
{ "iso8859", NULL, "11", NULL, "ISO8859_11" },
{ "tis620", NULL, "0", NULL, "ISO8859_11" },
{ "tis620", "2529", NULL, NULL, "ISO8859_11" },
{ "tis620", "2533", NULL, NULL, "ISO8859_11" },
{ "iso8859", NULL, "13", NULL, "ISO8859_13" },
{ "microsoft", NULL, "cp1257", NULL, "ISO8859_13" },
{ "iso8859", NULL, "14", NULL, "ISO8859_14" },
{ "iso8859", NULL, "15", NULL, "ISO8859_15" },
{ "iso8859", NULL, "2", NULL, "ISO8859_2" },
{ "microsoft", NULL, "cp1250", NULL, "ISO8859_2" },
{ "iso8859", NULL, "3", NULL, "ISO8859_3" },
{ "iso8859", NULL, "4", NULL, "ISO8859_4" },
{ "iso8859", NULL, "5", NULL, "ISO8859_5" },
{ "microsoft", NULL, "cp1251", NULL, "ISO8859_5" },
{ "iso8859", NULL, "6", NULL, "ISO8859_6" },
{ "iso8859", NULL, "6.8x", NULL, "ISO8859_6" },
{ "iso8859", NULL, "6_8", NULL, "ISO8859_6" },
{ "iso8859", NULL, "6.16x", NULL, "ISO8859_6" },
{ "iso8859", NULL, "6_16", NULL, "ISO8859_6" },
{ "iso8859", NULL, "6_asmo", NULL, "ISO8859_6" },
{ "asmo", NULL, "449", NULL, "ISO8859_6" },
{ "asmo", NULL, "449+", NULL, "ISO8859_6" },
{ "iso8859", NULL, "7", NULL, "ISO8859_7" },
{ "microsoft", NULL, "cp1253", NULL, "ISO8859_7" },
{ "iso8859", NULL, "8", NULL, "ISO8859_8" },
{ "microsoft", NULL, "cp1255", NULL, "ISO8859_8" },
{ "iso8859", NULL, "9", NULL, "ISO8859_9" },
{ "jisx0201", NULL, NULL, NULL, "JISX0201" },
{ "jisx0208", NULL, NULL, NULL, "JISX0208" },
{ "gt", NULL, NULL, NULL, "JISX0208" },
{ "jisx0212", NULL, NULL, NULL, "JISX0212" },
{ "koi8", NULL, "1", NULL, "KOI8" },
{ "koi8", NULL, "r", NULL, "KOI8" },
{ "koi8", NULL, "u", NULL, "KOI8" },
{ "koi8", NULL, "ru", NULL, "KOI8" },
{ "koi8", NULL, "uni", NULL, "KOI8" },
{ "ksc5601", NULL, "0", NULL, "KSC5601" },
{ "ksc5601", NULL, "1", NULL, "KSC5601" },
{ "ksc5601", NULL, "3", NULL, "KSCJOHAB" },
{ "ksx1001", NULL, "3", NULL, "KSCJOHAB" },
{ "kscjohab", NULL, NULL, NULL, "KSCJOHAB" },
{ "ksc5601johab",NULL, NULL, NULL, "KSCJOHAB" },
{ "mulelao", NULL, "1", NULL, "MULEENCODING" },
{ "ibm", NULL, "cp1133", NULL, "MULEENCODING" },
{ "tcvn", NULL, NULL, NULL, "TCVN" },
{ "viscii1", "1", "1", NULL, "VISCII" },
{ NULL, NULL, NULL, NULL, NULL }
};
Bool
codeconv_search_module( char const *charsetStdName,
char const *charsetYear,
char const *charsetEncoding,
char const *charsetPlane,
char const **result )
{
Bool isFound = False;
ModuleRelation const *p;
int ok_charsetYear=0, ok_charsetEncoding=0;
for (p=moduleRelations; NULL != p->charsetStdName; p++) {
if ( !charsetStdName ) break;
if ( mystrcasecmp(p->charsetStdName, charsetStdName) ) continue;
ok_charsetYear=0;
if ( !p->charsetYear ) ok_charsetYear=1;
else {
if ( charsetYear ) {
if ( !mystrcasecmp(p->charsetYear, charsetYear) ) ok_charsetYear=1;
}
}
if ( !ok_charsetYear ) continue;
ok_charsetEncoding=0;
if ( !p->charsetEncoding ) ok_charsetEncoding=1;
else {
if ( charsetEncoding ) {
if ( !mystrcasecmp(p->charsetEncoding,charsetEncoding) )
ok_charsetEncoding=1;
}
}
if ( ok_charsetYear && ok_charsetEncoding ) {
isFound = True;
*result = p->moduleName;
break;
}
}
return isFound;
}
#endif
#endif
#ifdef CCONV_MODULE
#if !defined(FONTMODULE)
void
X_TT_SetCodeConvModulePath(char const *rstrModulePath)
{
int len;
if ( X_TT_CodeConvModulePath )
xfree(X_TT_CodeConvModulePath);
len = strlen(rstrModulePath);
X_TT_CodeConvModulePath = (char *)xalloc(len+1);
strcpy(X_TT_CodeConvModulePath, rstrModulePath);
}
#endif
#endif
Bool
codeconv_search_code_converter(char const *charsetName,
TT_Face hFace, int numberOfCharMaps,
SRefPropRecValList *refListPropRecVal,
CodeConverterInfo *
refCodeConverterInfo ,
int *refMapID )
{
Bool isFound = False;
CharSetSelectionHints hints;
{
hints.charsetStdName = NULL;
hints.charsetYear = NULL;
hints.charsetEncoding = NULL;
hints.hFace = hFace;
hints.numberOfCharMaps = numberOfCharMaps;
hints.refListPropRecVal = refListPropRecVal;
{
char *p, *q, *r;
hints.charsetStdName = p = xstrdup(charsetName);
if ( p ) {
r = strchr(p, '-');
if (NULL != (q=strchr(p, '.'))) {
if ( NULL == r || (NULL != r && q < r) ) {
*q = '\0'; q++;
hints.charsetYear = q;
}
}
if (NULL != r) {
*r = '\0'; r++;
hints.charsetEncoding = r;
if (NULL != (q=strchr(r, '.'))) {
*q = '\0'; q++;
}
}
}
}
}
{
refCodeConverterInfo->refCharSetInfo = NULL;
refCodeConverterInfo->handleModule = NULL;
refCodeConverterInfo->ptrCodeConverter = NULL;
refCodeConverterInfo->destructor = NULL;
refCodeConverterInfo->work = NULL;
}
{
mod_entrypoint_ptr_t *p;
for (p=preloadedCodeConverter; NULL != *p; p++) {
if (False != (isFound = (*p)(&hints,
refCodeConverterInfo,
refMapID)))
goto quit;
}
}
#ifdef CCONV_MODULE
{
#if !defined(FONTMODULE)
DIR *dir = NULL;
struct dirent *dp;
char *pathListHead = NULL, *pathListTmp, *pathListNext;
if ( X_TT_CodeConvModulePath ) {
pathListHead = (char*)xalloc(strlen(X_TT_CodeConvModulePath)+1);
if ( !pathListHead )
goto endScanMod;
strcpy(pathListHead, X_TT_CodeConvModulePath);
} else {
pathListHead = (char *)xalloc(sizeof(CCONV_MODULE_DIR)+1);
if ( !pathListHead )
goto endScanMod;
strcpy(pathListHead, CCONV_MODULE_DIR);
}
pathListTmp = pathListHead;
do {
char *moduleSubDir = NULL;
pathListNext = strchr(pathListTmp, ',');
if ( pathListNext ) {
*pathListNext = '\0';
pathListNext++;
}
moduleSubDir =
(char *)xalloc(strlen(pathListTmp) +
sizeof(CCONV_MODULE_SUBDIR) + 1 + 1);
strcpy(moduleSubDir, pathListTmp);
strcat(moduleSubDir, "/");
strcat(moduleSubDir, CCONV_MODULE_SUBDIR);
if (NULL == (dir = opendir(moduleSubDir)))
goto nextPathElement;
while (NULL != (dp=readdir(dir)) && !isFound) {
const char *baseName = dp->d_name;
int baseNameLen = strlen(baseName);
if (!strcmp(baseName+(baseNameLen-LEN_CCONV_MODULE_EXTENTION),
CCONV_MODULE_EXTENTION)) {
char* pathModule = NULL;
char *entrypointFuncName = NULL;
{
pathModule =
(char *)xalloc(strlen(moduleSubDir)+1
+baseNameLen +1);
strcpy(pathModule, moduleSubDir);
strcat(pathModule, "/");
strcat(pathModule, baseName);
}
{
int entrypointFuncNameBaseLen = baseNameLen;
#if defined(PREPEND_UNDERSCORE)
entrypointFuncNameBaseLen++;
#endif
entrypointFuncName =
(char *)xalloc(entrypointFuncNameBaseLen
+LEN_CCONV_ENTRYPOINT_POSTFIX+1);
#if defined(PREPEND_UNDERSCORE)
strcpy(entrypointFuncName, "_");
strcat(entrypointFuncName, baseName);
#else
strcpy(entrypointFuncName, baseName);
#endif
entrypointFuncName[entrypointFuncNameBaseLen-
LEN_CCONV_MODULE_EXTENTION] = '\0';
strcat(entrypointFuncName, CCONV_ENTRYPOINT_POSTFIX);
}
{
ft_module_handle_t handle;
if (NULL != (handle = DLOPEN(pathModule, DL_OPTION))) {
mod_entrypoint_ptr_t entryPoint;
entryPoint =
(mod_entrypoint_ptr_t)DLSYM(handle,
entrypointFuncName);
if (NULL != entryPoint)
isFound =
(*entryPoint)(&hints, refCodeConverterInfo,
refMapID);
if (isFound) {
refCodeConverterInfo->handleModule = handle;
} else {
DLCLOSE(handle);
}
} else {
fprintf(stderr, "warning: cannot dlopen - %s\n",
dlerror());
}
}
if ( pathModule ) {
xfree(pathModule);
}
if ( entrypointFuncName ) {
xfree(entrypointFuncName);
}
}
}
nextPathElement:
xfree(moduleSubDir);
if ( dir ) {
closedir(dir);
dir = NULL;
}
pathListTmp = pathListNext;
} while (pathListTmp);
endScanMod:
if ( pathListHead )
xfree(pathListHead);
#else
char** list = NULL;
ModuleSetupArg moduleArg;
moduleArg.charSetHints = &hints;
moduleArg.refCodeConverterInfo = refCodeConverterInfo;
moduleArg.refMapID = refMapID;
if (NULL !=
(list = LoaderListDirs(convModuleSubdir, NULL))) {
#ifdef CCONV_USE_SYMBOLIC_ENTRY_POINT
mod_entrypoint_ptr_t entryPoint = NULL;
{
int length = 0;
char** l;
for (l=list; *l; l++)
if(strlen(*l) > length)
length = strlen(*l);
length += LEN_CCONV_ENTRYPOINT_POSTFIX;
if (NULL == entryName){
entryName = xalloc(length+1);
entryNameAllocated = length;
}
else
if (length > entryNameAllocated) {
entryName = xrealloc(entryName, length+1);
entryNameAllocated = length;
}
if (NULL == entryName)
goto endScanMod;
}
#endif
{
char **l;
char **tryItFirst = NULL;
char **fallback_try = NULL;
char const *target_module = NULL;
#ifdef PPC_WORKAROUND
codeconv_search_module(moduleArg.charSetHints->charsetStdName,
moduleArg.charSetHints->charsetYear,
moduleArg.charSetHints->charsetEncoding,
NULL,
&target_module);
#endif
for (l=list; *l ; l++) {
int breaking=0;
char *tmp_left=NULL;
char *mark_underscore=NULL;
if ( target_module != NULL ) {
if(!mystrcasecmp(*l,target_module)) {
tryItFirst = l;
breaking=1;
}
}
else {
tmp_left=xstrdup(*l);
if ( tmp_left ) mark_underscore=strrchr(tmp_left,'_');
else mark_underscore=NULL;
if( mark_underscore != NULL ){
*mark_underscore = '\0';
if( !mystrcasecmp(tmp_left,moduleArg.charSetHints->charsetStdName) ){
if( !mystrcasecmp( mark_underscore+1,moduleArg.charSetHints->charsetEncoding ) ){
tryItFirst = l;
breaking=1;
}
}
}
else{
if(!mystrcasecmp(*l,moduleArg.charSetHints->charsetStdName)) {
tryItFirst = l;
breaking=1;
}
}
}
if( fallback_try == NULL ){
if( !mystrcasecmp(*l,"ISO8859_1") ){
fallback_try = l;
}
}
if( tmp_left ) xfree(tmp_left);
if( breaking ) break;
}
#if 1
if( tryItFirst == NULL ) tryItFirst=fallback_try;
#endif
if(tryItFirst)
l = tryItFirst;
else
l = list;
while(*l && !isFound) {
pointer handle;
int errorMajor;
int errorMinor;
#ifdef CCONV_USE_SYMBOLIC_ENTRY_POINT
strcpy(entryName, *l);
strcat(entryName, CCONV_ENTRYPOINT_POSTFIX);
#endif
handle = LoadSubModule(xttModule.module,
*l, convModuleSubdir, NULL,
&moduleArg, &cconvSubReq,
&errorMajor, &errorMinor);
if (NULL != handle) {
refCodeConverterInfo->handleModule =
(ft_module_handle_t)handle;
isFound = True;
goto endScanMod;
}
if (NULL != tryItFirst) {
l = list;
tryItFirst = NULL;
}
else
l++;
}
}
endScanMod:
LoaderFreeDirList(list);
}
#endif
}
#endif
quit:
{
if (hints.charsetStdName)
xfree((char *)hints.charsetStdName);
}
return isFound;
}
void
codeconv_free_code_converter(CodeConverterInfo *refCodeConverterInfo)
{
if (refCodeConverterInfo->destructor)
(refCodeConverterInfo->destructor)(refCodeConverterInfo);
#ifdef CCONV_MODULE
if (refCodeConverterInfo->handleModule) {
#ifdef FONTMODULE
UnloadSubModule(refCodeConverterInfo->handleModule);
#else
DLCLOSE(refCodeConverterInfo->handleModule);
#endif
}
#endif
refCodeConverterInfo->handleModule = NULL;
refCodeConverterInfo->destructor = NULL;
}
Bool
codeconv_search_charset(CharSetRelation const *charSetRelations,
char const *charsetStdName,
char const *charsetYear,
char const *charsetEncoding,
int *refMagicNumber ,
CharSetInfo const **refRefCharSetInfo )
{
Bool isFound = False;
CharSetRelation const *p;
int ok_charsetYear=0, ok_charsetEncoding=0;
for (p=charSetRelations; NULL != p->charsetStdName; p++) {
if ( !charsetStdName ) break;
if ( mystrcasecmp(p->charsetStdName, charsetStdName) ) continue;
ok_charsetYear=0;
if ( !p->charsetYear ) ok_charsetYear=1;
else {
if ( charsetYear ) {
if ( !mystrcasecmp(p->charsetYear, charsetYear) ) ok_charsetYear=1;
}
}
if ( !ok_charsetYear ) continue;
ok_charsetEncoding=0;
if ( !p->charsetEncoding ) ok_charsetEncoding=1;
else {
if ( charsetEncoding ) {
if ( !mystrcasecmp(p->charsetEncoding,charsetEncoding) )
ok_charsetEncoding=1;
}
}
if ( ok_charsetYear && ok_charsetEncoding ) {
isFound = True;
if ( refMagicNumber!=NULL ) *refMagicNumber = p->magicNumber;
if ( refRefCharSetInfo!=NULL ) *refRefCharSetInfo = &p->charSetInfo;
break;
}
}
return isFound;
}
Bool
codeconv_search_map_id(CharSetSelectionHints const *charSetHints,
CharSetRelation const *refCharSetRelations,
MapIDRelation const *refMapIDRelations,
CodeConverterInfo *refCodeConverterInfo ,
int *refMapID )
{
Bool isFound = False;
int magic;
{
refCodeConverterInfo->ptrCodeConverter = null_code_converter;
}
if (codeconv_search_charset(refCharSetRelations,
charSetHints->charsetStdName,
charSetHints->charsetYear,
charSetHints->charsetEncoding,
&magic,
&refCodeConverterInfo->refCharSetInfo)) {
MapIDRelation const *p;
for (p=refMapIDRelations;
!isFound && 0<=p->magicNumber;
p++) {
if (p->magicNumber == magic) {
if (p->platform == EPlfmAny) {
isFound = True;
*refMapID = 0;
goto found;
} else {
int i;
for (i=0;
!isFound && i<charSetHints->numberOfCharMaps;
i++) {
TT_UShort platform, encoding;
TT_Get_CharMap_ID(charSetHints->hFace, i,
&platform, &encoding);
if (p->platform == platform) {
if (p->encoding == EEncAny ||
p->encoding == encoding) {
isFound = True;
*refMapID = i;
goto found;
}
}
}
}
}
}
found:
if (isFound) {
if (NULL != p->ptrCodeConverter) {
refCodeConverterInfo->ptrCodeConverter =
p->ptrCodeConverter;
}
if (NULL != p->callback)
(*p->callback)(charSetHints, refCodeConverterInfo, refMapID);
}
}
return isFound;
}
ft_char_code_t
null_code_converter(ft_char_code_t charCodeSrc)
{
return charCodeSrc;
}