From 34b0b1fc11ad6376706c2777e662689b177edb44 Mon Sep 17 00:00:00 2001 From: Onn Ben-Zvi Date: Mon, 13 Nov 2000 16:01:05 +0000 Subject: [PATCH] initial - ONn --- ext/fribidi/Makefile.in | 9 ++ ext/fribidi/README | 53 ++++++++ ext/fribidi/config.m4 | 74 +++++++++++ ext/fribidi/fribidi.c | 265 ++++++++++++++++++++++++++++++++++++++ ext/fribidi/fribidi.php | 10 ++ ext/fribidi/php_fribidi.h | 92 +++++++++++++ 6 files changed, 503 insertions(+) create mode 100644 ext/fribidi/Makefile.in create mode 100644 ext/fribidi/README create mode 100644 ext/fribidi/config.m4 create mode 100755 ext/fribidi/fribidi.c create mode 100644 ext/fribidi/fribidi.php create mode 100644 ext/fribidi/php_fribidi.h diff --git a/ext/fribidi/Makefile.in b/ext/fribidi/Makefile.in new file mode 100644 index 0000000000..d7dd435353 --- /dev/null +++ b/ext/fribidi/Makefile.in @@ -0,0 +1,9 @@ +# $Id$ + +LTLIBRARY_NAME = libfribidi.la +LTLIBRARY_SOURCES = fribidi.c +LTLIBRARY_SHARED_NAME = fribidi.la +LTLIBRARY_SHARED_LIBADD = $(FRIBIDI_SHARED_LIBADD) + +include $(top_srcdir)/build/dynlib.mk +EXTRA_INCLUDES = $(FRIBIDI_INCLUDE) diff --git a/ext/fribidi/README b/ext/fribidi/README new file mode 100644 index 0000000000..832e0fb472 --- /dev/null +++ b/ext/fribidi/README @@ -0,0 +1,53 @@ +Purpose +======= + +This extension is basically a wrapper for the FriBidi implementation +of the Unicode Bidi algorithm. The need for such an algorithm rises +from the bidirectional language usage done by applications. +Arabic/Hebrew embedded within English is such a case. + +Usage +===== + + The only function used is fribidi_log2vis (logical to visual). + Input: 1) The Logical string. + 2) Base direction of application - 'L' or 'R'. + 3) The char code being used, which can be one of the following + constants: + a) FRIBIDI_CHARSET_UTF8 + b) FRIBIDI_CHARSET_8859_6 + c) FRIBIDI_CHARSET_8859_8 + d) FRIBIDI_CHARSET_CP1255 + e) FRIBIDI_CHARSET_CP1256 + f) FRIBIDI_CHARSET_ISIRI_3342 + +Note: Currently, FriBidi supports the above Character Codes alone. + + Output: A Visual string. + + +Compiling +=========== +1) Static - ./configure --with-fribidi=base-directory-of-FriBidi-installation-path + (defaults to /usr/local). + +2) dl - same, just add static, to get .... --with-fribidi=static,base.... + +Prerequisites +============= +1) FriBidi must be installed. Latest version can be obtained thru + http://imagic.weizmann.ac.il/~dov/freesw/FriBidi. + +2) glib header files: glib.h and glibconfig.h. + +Note +===== + +The function fribidi_log2vis computes three more arrays which are currently not passed back as output. +These arrays are: + 1) mapping from the logical to the visual sting. + 2) mapping from the visual to the logical string. + 3) embedding level of characters as figured out by the FriBidi algorithm. + +The extension needs further implementation to support this. +p.s. - If you don't understand this, you probably don't need it. diff --git a/ext/fribidi/config.m4 b/ext/fribidi/config.m4 new file mode 100644 index 0000000000..b05bf395ca --- /dev/null +++ b/ext/fribidi/config.m4 @@ -0,0 +1,74 @@ +dnl $Id$ +dnl config.m4 for extension fribidi +dnl don't forget to call PHP_EXTENSION(fribidi) + + + +PHP_ARG_WITH(fribidi, whether to add fribidi support, +[ --with-fribidi[=DIR] Include fribidi support (requires FriBidi >=0.1.12). + DIR is the fribidi installation directory - + default /usr/local/],"no") + + + +if test "$PHP_FRIBIDI" != "no"; then + +dnl if module was requested with default path of fribidi installation then +dnl $PHP_FRIBIDI will be "yes" + + if test "$PHP_FRIBIDI" == "yes"; then + PHP_FRIBIDI="/usr/local" + fi + + + + dnl check for fribidi header files + + AC_MSG_CHECKING([for header files in "$PHP_FRIBIDI/include/fribidi"]) + if test -f $PHP_FRIBIDI/include/fribidi/fribidi.h && test -f $PHP_FRIBIDI/include/fribidi/fribidi_types.h && test -f $PHP_FRIBIDI/include/fribidi/fribidi_char_sets.h; then + FRIBIDI_INCDIR="$PHP_FRIBIDI/include/fribidi/" + AC_MSG_RESULT([found all]) + else + AC_MSG_RESULT([missing]) + fi + + + + dnl check for fribidi shared library + + AC_MSG_CHECKING([for libfribidi.so file in "$PHP_FRIBIDI/lib/"]) + if test -f "$PHP_FRIBIDI/lib/libfribidi.so" ; then + FRIBIDI_LIBDIR="$PHP_FRIBIDI/lib/" + AC_MSG_RESULT([found]) + else + AC_MSG_RESULT([missing]) + fi + + dnl check for glib header files + + AC_MSG_CHECKING([for glibconfig.h in "usr/lib/glib/include/"]) + if test -f /usr/lib/glib/include/glibconfig.h ; then + AC_MSG_RESULT([found]) + GLIB_INCDIR=/usr/lib/glib/include/ + else + AC_MSG_RESULT([missing]) + fi + + + AC_MSG_CHECKING([sanity to build extension]) + if test -n "$FRIBIDI_INCDIR" && test -n "$FRIBIDI_LIBDIR" && test -n "$GLIB_INCDIR"; then + + AC_MSG_RESULT([yes]) + + + AC_ADD_INCLUDE("$FRIBIDI_INCDIR") + AC_ADD_INCLUDE("$GLIB_INCDIR") + AC_ADD_LIBRARY_WITH_PATH(fribidi,"$FRIBIDI_LIBDIR", FRIBIDI_SHARED_LIBADD) + PHP_SUBST(FRIBIDI_SHARED_LIBADD) + + AC_DEFINE(HAVE_FRIBIDI, 1, [ ]) + PHP_EXTENSION(fribidi, $ext_shared) + else + AC_MSG_RESULT([no]) + fi +fi diff --git a/ext/fribidi/fribidi.c b/ext/fribidi/fribidi.c new file mode 100755 index 0000000000..27e54bde0d --- /dev/null +++ b/ext/fribidi/fribidi.c @@ -0,0 +1,265 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.02 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_02.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +#include "php.h" +#include "php_ini.h" +#include "php_fribidi.h" +#include "fribidi.h" + +/* You should tweak config.m4 so this symbol (or some else suitable) + gets defined. +*/ +#if HAVE_FRIBIDI + +/* If you declare any globals in php_fribidi.h uncomment this: +ZEND_DECLARE_MODULE_GLOBALS(fribidi) +*/ + +/* True global resources - no need for thread safety here */ +/* static int le_fribidi; */ + +/* Every user visible function must have an entry in fribidi_functions[]. +*/ +function_entry fribidi_functions[] = { + ZEND_FE(fribidi_log2vis, NULL) + {NULL, NULL, NULL} /* Must be the last line in fribidi_functions[] */ +}; + +zend_module_entry fribidi_module_entry = { + "fribidi", + fribidi_functions, + PHP_MINIT(fribidi), + PHP_MSHUTDOWN(fribidi), + PHP_RINIT(fribidi), /* Replace with NULL if there's nothing to do at request start */ + PHP_RSHUTDOWN(fribidi), /* Replace with NULL if there's nothing to do at request end */ + PHP_MINFO(fribidi), + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_FRIBIDI +ZEND_GET_MODULE(fribidi) +#endif + +/* Remove comments and fill if you need to have entries in php.ini +PHP_INI_BEGIN() +PHP_INI_END() +*/ + +PHP_MINIT_FUNCTION(fribidi) +{ +/* Remove comments if you have entries in php.ini + REGISTER_INI_ENTRIES(); +*/ + + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_UTF8",FRIBIDI_CHARSET_UTF8, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_8859_6",FRIBIDI_CHARSET_8859_6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_8859_8",FRIBIDI_CHARSET_8859_8, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_CP1255",FRIBIDI_CHARSET_CP1255, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_CP1256",FRIBIDI_CHARSET_CP1256, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FRIBIDI_CHARSET_ISIRI_3342",FRIBIDI_CHARSET_ISIRI_3342, CONST_CS | CONST_PERSISTENT); + + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(fribidi) +{ +/* Remove comments if you have entries in php.ini + UNREGISTER_INI_ENTRIES(); +*/ + return SUCCESS; +} + +/* Remove if there's nothing to do at request start */ +PHP_RINIT_FUNCTION(fribidi) +{ + return SUCCESS; +} + +/* Remove if there's nothing to do at request end */ +PHP_RSHUTDOWN_FUNCTION(fribidi) +{ + return SUCCESS; +} + +PHP_MINFO_FUNCTION(fribidi) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "fribidi support", "enabled"); + php_info_print_table_end(); + + /* Remove comments if you have entries in php.ini + DISPLAY_INI_ENTRIES(); + */ +} + + +/*--------------------------------------------------------------*/ +/* Name: fribidi_log2vis */ +/* Purpose: convert a logical string to a visual one */ +/* Input: 1) The logical string. */ +/* 2) Base direction - */ +/* Possible values: */ +/* a) "L" - base language is left to right. */ +/* b) "R" - base language is right to left. */ +/* c) empty - base language is determined */ +/* automatically by the FriBiDi algorithm */ +/* 3) Character code being used - */ +/* Possible values (i.e., char sets supported) */ +/* FRIBIDI_CHARSET_UTF8 */ +/* FRIBIDI_CHARSET_8859_6 */ +/* FRIBIDI_CHARSET_8859_8 */ +/* FRIBIDI_CHARSET_CP1255 */ +/* FRIBIDI_CHARSET_CP1256 */ +/* FRIBIDI_CHARSET_ISIRI_3342 */ +/* */ +/* Output: on success: The visual string. */ +/* on failure: */ +/*--------------------------------------------------------------*/ + +ZEND_FUNCTION(fribidi_log2vis) +{ + zval **parameter1,**parameter2, **parameter3; + + + FriBidiChar *u_logical_str,*u_visual_str; /* unicode strings .... */ + char *inString; + guchar *outString; + int len,alloc_len,utf8_len; + + + FriBidiCharType base_dir; + + guint16 *position_L_to_V_list; + guint16 *position_V_to_L_list; + guint8 *embedding_level_list; + + /* get parameters from input */ + + if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, ¶meter1, ¶meter2, ¶meter3) == FAILURE) { + WRONG_PARAM_COUNT; + } + + /* convert input to expected type.... */ + + convert_to_string_ex(parameter1); + convert_to_string_ex(parameter2); + convert_to_long_ex(parameter3); + + /* allocate space and prepare all local variables */ + + + len = Z_STRLEN_PP(parameter1); + + inString = estrndup(Z_STRVAL_PP(parameter1), len); + + alloc_len = len+1; + + u_logical_str = (FriBidiChar*) emalloc(sizeof(FriBidiChar)*alloc_len); + u_visual_str = (FriBidiChar*) emalloc(sizeof(FriBidiChar)*alloc_len); + + position_L_to_V_list = (guint16*) emalloc(sizeof(guint16)*alloc_len); + position_V_to_L_list = (guint16*) emalloc(sizeof(guint16)*alloc_len); + embedding_level_list = (guint8*) emalloc(sizeof(guint8)*alloc_len); + + outString = (guchar*)emalloc(sizeof(guchar)*alloc_len); + + if(inString[len-1] == '\n') { + inString[len-1] = '\0'; + } + + switch(Z_LVAL_PP(parameter3)) { + case FRIBIDI_CHARSET_UTF8: + utf8_len=fribidi_utf8_to_unicode(inString,u_logical_str); + break; + case FRIBIDI_CHARSET_8859_6: + fribidi_iso8859_6_to_unicode(inString,u_logical_str); + break; + case FRIBIDI_CHARSET_8859_8: + fribidi_iso8859_8_to_unicode(inString,u_logical_str); + break; + case FRIBIDI_CHARSET_CP1255: + fribidi_cp1255_to_unicode(inString,u_logical_str); + break; + case FRIBIDI_CHARSET_CP1256: + fribidi_cp1256_to_unicode(inString,u_logical_str); + break; + case FRIBIDI_CHARSET_ISIRI_3342: + fribidi_isiri_3342_to_unicode(inString,u_logical_str); + break; + default: + zend_error(E_ERROR,"unknown character set %d
",Z_LVAL_PP(parameter3)); + } + + + /* visualize the logical.... */ + + if ((Z_STRVAL_PP(parameter2))[0] == 'R') { + base_dir = FRIBIDI_TYPE_RTL; + } else if (Z_STRVAL_PP(parameter2)[0] == 'L') + base_dir = FRIBIDI_TYPE_LTR; + else + base_dir = FRIBIDI_TYPE_N; + + fribidi_log2vis(u_logical_str,len,&base_dir,u_visual_str,position_L_to_V_list,position_V_to_L_list,embedding_level_list); + + /* convert back to original char set */ + + switch(Z_LVAL_PP(parameter3)) { + case FRIBIDI_CHARSET_UTF8: + fribidi_unicode_to_utf8(u_visual_str,utf8_len , outString); + break; + case FRIBIDI_CHARSET_8859_6: + fribidi_unicode_to_iso8859_6(u_visual_str,len , outString); + break; + case FRIBIDI_CHARSET_8859_8: + fribidi_unicode_to_iso8859_8(u_visual_str,len , outString); + break; + case FRIBIDI_CHARSET_CP1255: + fribidi_unicode_to_cp1255(u_visual_str,len , outString); + break; + case FRIBIDI_CHARSET_CP1256: + fribidi_unicode_to_cp1256(u_visual_str,len , outString); + break; + case FRIBIDI_CHARSET_ISIRI_3342: + fribidi_unicode_to_isiri_3342(u_visual_str,len , outString); + break; + default: + zend_error(E_ERROR,"unknown character set %d
",Z_LVAL_PP(parameter3)); + } + + + efree(u_logical_str); + efree(u_visual_str); + + efree(position_L_to_V_list); + efree(position_V_to_L_list); + efree(embedding_level_list); + + RETURN_STRING(outString,1); +} + +#endif /* HAVE_FRIBIDI */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/fribidi/fribidi.php b/ext/fribidi/fribidi.php new file mode 100644 index 0000000000..6a603d604e --- /dev/null +++ b/ext/fribidi/fribidi.php @@ -0,0 +1,10 @@ + diff --git a/ext/fribidi/php_fribidi.h b/ext/fribidi/php_fribidi.h new file mode 100644 index 0000000000..e7233fa892 --- /dev/null +++ b/ext/fribidi/php_fribidi.h @@ -0,0 +1,92 @@ +/* + +----------------------------------------------------------------------+ + | PHP version 4.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.02 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_02.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +#ifndef PHP_FRIBIDI_H +#define PHP_FRIBIDI_H + +#if HAVE_FRIBIDI + +#include "fribidi.h" +#include "../standard/info.h" + +extern zend_module_entry fribidi_module_entry; +#define phpext_fribidi_ptr &fribidi_module_entry + + +typedef struct _php_fribidi_rsrc{ + guint16 *position_L_to_V_list; + guint16 *position_V_to_L_list; + guint8 *embedding_level_list; + guchar *out_string; +} php_fribidi_rsrc; + + +#ifdef PHP_WIN32 +#define PHP_FRIBIDI_API __declspec(dllexport) +#else +#define PHP_FRIBIDI_API +#endif + +PHP_MINIT_FUNCTION(fribidi); +PHP_MSHUTDOWN_FUNCTION(fribidi); +PHP_RINIT_FUNCTION(fribidi); +PHP_RSHUTDOWN_FUNCTION(fribidi); +PHP_MINFO_FUNCTION(fribidi); + +ZEND_FUNCTION(fribidi_log2vis); +/*void php_fribidi_free_rsrc(php_fribidi_rsrc* p_rsrc);*/ +/* + Declare any global variables you may need between the BEGIN + and END macros here: + +ZEND_BEGIN_MODULE_GLOBALS(fribidi) + int global_variable; +ZEND_END_MODULE_GLOBALS(fribidi) +*/ + +/* In every function that needs to use variables in php_fribidi_globals, + do call FRIBIDILS_FETCH(); after declaring other variables used by + that function, and always refer to them as FRIBIDIG(variable). + You are encouraged to rename these macros something shorter, see + examples in any other php module directory. +*/ + +#ifdef ZTS +#define FRIBIDIG(v) (fribidi_globals->v) +#define FRIBIDILS_FETCH() php_fribidi_globals *fribidi_globals = ts_resource(fribidi_globals_id) +#else +#define FRIBIDIG(v) (fribidi_globals.v) +#define FRIBIDILS_FETCH() +#endif + +#else + +#define phpext_fribidi_ptr NULL + +#endif + +#endif /* PHP_FRIBIDI_H */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ -- 2.50.1