summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDov Grobgeld <dov.grobgeld@gmail.com>2017-08-01 20:18:38 +0300
committerDov Grobgeld <dov.grobgeld@gmail.com>2017-08-01 20:18:38 +0300
commitf20b6480b9cd46dae8d82a6f95d9c53558fcfd20 (patch)
tree07683bb54bdd0fab520a6b3e3edcc1383f9c36bd
parent654e3f3436b90da4ec6479aa35b6f0d86e696c41 (diff)
downloadfribidi-f20b6480b9cd46dae8d82a6f95d9c53558fcfd20.tar.gz
Added Unicode 6.3 support (and beyond)
- N0 support - Isolate character support (LRI, RLI, FSI) - Added test program test.c by Behdad that tests BidiTest.txt compliance. - Added test program test-character.c that tests BidiCharacterTest.txt compliance.
-rw-r--r--NEWS5
-rw-r--r--README2
-rw-r--r--THANKS12
-rw-r--r--bin/fribidi-benchmark.c2
-rw-r--r--bin/fribidi-main.c2
-rw-r--r--charset/fribidi-char-sets-cap-rtl.c38
-rw-r--r--charset/fribidi-char-sets-cap-rtl.h2
-rw-r--r--charset/fribidi-char-sets-cp1255.c2
-rw-r--r--charset/fribidi-char-sets-cp1255.h2
-rw-r--r--charset/fribidi-char-sets-cp1256.c2
-rw-r--r--charset/fribidi-char-sets-cp1256.h2
-rw-r--r--charset/fribidi-char-sets-iso8859-6.c2
-rw-r--r--charset/fribidi-char-sets-iso8859-6.h2
-rw-r--r--charset/fribidi-char-sets-iso8859-8.c2
-rw-r--r--charset/fribidi-char-sets-iso8859-8.h2
-rw-r--r--charset/fribidi-char-sets-list.h2
-rw-r--r--charset/fribidi-char-sets-utf8.c2
-rw-r--r--charset/fribidi-char-sets-utf8.h2
-rw-r--r--charset/fribidi-char-sets.c2
-rw-r--r--charset/fribidi-char-sets.h2
-rw-r--r--configure.ac11
-rw-r--r--doc/Makefile.am3
-rw-r--r--fribidi-vs-unicode/Makefile.am27
-rw-r--r--fribidi-vs-unicode/test-character.c409
-rw-r--r--fribidi-vs-unicode/test.c391
-rw-r--r--gen.tab/Makefile.am32
-rw-r--r--gen.tab/gen-arabic-shaping-tab.c2
-rw-r--r--gen.tab/gen-bidi-type-tab.c2
-rw-r--r--gen.tab/gen-brackets-tab.c345
-rw-r--r--gen.tab/gen-brackets-type-tab.c238
-rw-r--r--gen.tab/gen-joining-type-tab.c2
-rw-r--r--gen.tab/gen-mirroring-tab.c2
-rw-r--r--gen.tab/gen-unicode-version.c2
-rw-r--r--lib/Headers.mk1
-rw-r--r--lib/Makefile.am9
-rw-r--r--lib/bidi-types.h2
-rw-r--r--lib/common.h8
-rw-r--r--lib/debug.h10
-rw-r--r--lib/fribidi-arabic.c2
-rw-r--r--lib/fribidi-arabic.h2
-rw-r--r--lib/fribidi-bidi-types-list.h6
-rw-r--r--lib/fribidi-bidi-types.c2
-rw-r--r--lib/fribidi-bidi-types.h31
-rw-r--r--lib/fribidi-bidi.c681
-rw-r--r--lib/fribidi-bidi.h4
-rw-r--r--lib/fribidi-brackets.c106
-rw-r--r--lib/fribidi-brackets.h90
-rw-r--r--lib/fribidi-common.h2
-rw-r--r--lib/fribidi-deprecated.c15
-rw-r--r--lib/fribidi-deprecated.h4
-rw-r--r--lib/fribidi-flags.h2
-rw-r--r--lib/fribidi-joining-types-list.h2
-rw-r--r--lib/fribidi-joining-types.c2
-rw-r--r--lib/fribidi-joining-types.h2
-rw-r--r--lib/fribidi-joining.c3
-rw-r--r--lib/fribidi-joining.h2
-rw-r--r--lib/fribidi-mem.c2
-rw-r--r--lib/fribidi-mirroring.c4
-rw-r--r--lib/fribidi-mirroring.h4
-rw-r--r--lib/fribidi-run.c77
-rw-r--r--lib/fribidi-shape.c2
-rw-r--r--lib/fribidi-shape.h2
-rw-r--r--lib/fribidi-types.h14
-rw-r--r--lib/fribidi-unicode.h15
-rw-r--r--lib/fribidi.c7
-rw-r--r--lib/fribidi.h3
-rw-r--r--lib/joining-types.h2
-rw-r--r--lib/mem.h2
-rw-r--r--lib/run.h13
-rw-r--r--test/test_CapRTL_isolate.input8
-rw-r--r--test/test_CapRTL_isolate.reference8
71 files changed, 2494 insertions, 212 deletions
diff --git a/NEWS b/NEWS
index 28f074c..9d25575 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Overview of changes between 0.19.6 and 0.19.8
+=============================================
+* Full isolate and parenthesis support as per Unicode 6.3
+* This version is not backwards compatible.
+
Overview of changes between 0.19.6 and 0.19.7
=============================================
* Disable thread-unsafe memory pool by default. (bug #79385)
diff --git a/README b/README
index 16b7a10..dd08b47 100644
--- a/README
+++ b/README
@@ -58,7 +58,7 @@ along with GNU FriBidi, in a file named COPYING; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA
-For licensing issues, contact <license@farsiweb.info>.
+For licensing issues, contact <fribidi.license@gmail.com>.
Implementation
==============
diff --git a/THANKS b/THANKS
index e2b75eb..a934939 100644
--- a/THANKS
+++ b/THANKS
@@ -3,16 +3,20 @@ Thanks to:
Behnam Esfahbod <behnam@esfahbod.info>
* Testing and auditing code.
+Dov Grobgeld <dov.grobgeld@gmail.com>
+ * Initial author, maintainer before the 0.9 releases. Implementation
+ of the BiDi algorithms changes in Unicode 6.3.
+
+Behdad Esfahbod <behdad@behdad.org>
+ * Maintainer. Author of the entire 0.9 release series up to Unicode 6.3
+ support.
-And for the previous versions of FriBidi (pre 2002), thanks to:
+And for the previous versions of FriBidi (pre 2002), thanks to:
Tomas Frydrych <tomas@frydrych.uklinux.net>
* Contirbuted patches for compiling GNU FriBidi under other OSes.
-Dov Grobgeld <dov.grobgeld@gmail.com>
- * Initial author, and maintainer before the 0.9 releases.
-
Franck Portaneri
* For the Mozilla BiDi languges support document;
diff --git a/bin/fribidi-benchmark.c b/bin/fribidi-benchmark.c
index 53eeaf1..2c77a9f 100644
--- a/bin/fribidi-benchmark.c
+++ b/bin/fribidi-benchmark.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/bin/fribidi-main.c b/bin/fribidi-main.c
index b95e856..cd2fb93 100644
--- a/bin/fribidi-main.c
+++ b/bin/fribidi-main.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-cap-rtl.c b/charset/fribidi-char-sets-cap-rtl.c
index 9d70c51..24a2d1b 100644
--- a/charset/fribidi-char-sets-cap-rtl.c
+++ b/charset/fribidi-char-sets-cap-rtl.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
@@ -64,7 +64,7 @@ enum
static FriBidiCharType CapRTLCharTypes[] = {
/* *INDENT-OFF* */
ON, ON, ON, ON, LTR,RTL,ON, ON, ON, ON, ON, ON, ON, BS, RLO,RLE, /* 00-0f */
- LRO,LRE,PDF,WS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, /* 10-1f */
+ LRO,LRE,PDF,WS, LRI, RLI, FSI, PDI, ON, ON, ON, ON, ON, ON, ON, ON, /* 10-1f */
WS, ON, ON, ON, ET, ON, ON, ON, ON, ON, ON, ET, CS, ON, ES, ES, /* 20-2f */
EN, EN, EN, EN, EN, EN, AN, AN, AN, AN, CS, ON, ON, ON, ON, ON, /* 30-3f */
RTL,AL, AL, AL, AL, AL, AL, RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL, /* 40-4f */
@@ -216,6 +216,18 @@ fribidi_cap_rtl_to_unicode (
case 'R':
us[j++] = FRIBIDI_CHAR_RLO;
break;
+ case 'i':
+ us[j++] = FRIBIDI_CHAR_LRI;
+ break;
+ case 'y':
+ us[j++] = FRIBIDI_CHAR_RLI;
+ break;
+ case 'f':
+ us[j++] = FRIBIDI_CHAR_FSI;
+ break;
+ case 'I':
+ us[j++] = FRIBIDI_CHAR_PDI;
+ break;
case '_':
us[j++] = '_';
break;
@@ -248,8 +260,9 @@ fribidi_unicode_to_cap_rtl (
for (i = 0; i < len; i++)
{
FriBidiChar ch = us[i];
- if (!FRIBIDI_IS_EXPLICIT (fribidi_get_bidi_type (ch)) && ch != '_'
- && ch != FRIBIDI_CHAR_LRM && ch != FRIBIDI_CHAR_RLM)
+ if (!FRIBIDI_IS_EXPLICIT (fribidi_get_bidi_type (ch))
+ && !FRIBIDI_IS_ISOLATE (fribidi_get_bidi_type (ch))
+ && ch != '_' && ch != FRIBIDI_CHAR_LRM && ch != FRIBIDI_CHAR_RLM)
s[j++] = fribidi_unicode_to_cap_rtl_c (ch);
else
{
@@ -277,6 +290,18 @@ fribidi_unicode_to_cap_rtl (
case FRIBIDI_CHAR_RLO:
s[j++] = 'R';
break;
+ case FRIBIDI_CHAR_LRI:
+ s[j++] = 'i';
+ break;
+ case FRIBIDI_CHAR_RLI:
+ s[j++] = 'y';
+ break;
+ case FRIBIDI_CHAR_FSI:
+ s[j++] = 'f';
+ break;
+ case FRIBIDI_CHAR_PDI:
+ s[j++] = 'I';
+ break;
case '_':
s[j++] = '_';
break;
@@ -333,7 +358,10 @@ fribidi_char_set_desc_cap_rtl (
" * _> LRM\n" " * _< RLM\n"
" * _l LRE\n" " * _r RLE\n"
" * _L LRO\n" " * _R RLO\n"
- " * _o PDF\n" " * __ `_' itself\n" "\n");
+ " * _o PDF\n" " * _i LRI\n"
+ " * _y RLI\n" " * _f FSI\n"
+ " * _I PDI\n" " * __ `_' itself\n"
+ "\n");
return s;
}
diff --git a/charset/fribidi-char-sets-cap-rtl.h b/charset/fribidi-char-sets-cap-rtl.h
index 4bf933f..a2d3126 100644
--- a/charset/fribidi-char-sets-cap-rtl.h
+++ b/charset/fribidi-char-sets-cap-rtl.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_CAP_RTL_H
diff --git a/charset/fribidi-char-sets-cp1255.c b/charset/fribidi-char-sets-cp1255.c
index 156a83f..24f5419 100644
--- a/charset/fribidi-char-sets-cp1255.c
+++ b/charset/fribidi-char-sets-cp1255.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-cp1255.h b/charset/fribidi-char-sets-cp1255.h
index c9c3e8e..1c340a9 100644
--- a/charset/fribidi-char-sets-cp1255.h
+++ b/charset/fribidi-char-sets-cp1255.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_CP1255_H
diff --git a/charset/fribidi-char-sets-cp1256.c b/charset/fribidi-char-sets-cp1256.c
index d939f70..5516f37 100644
--- a/charset/fribidi-char-sets-cp1256.c
+++ b/charset/fribidi-char-sets-cp1256.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-cp1256.h b/charset/fribidi-char-sets-cp1256.h
index 1c6635a..6fe8951 100644
--- a/charset/fribidi-char-sets-cp1256.h
+++ b/charset/fribidi-char-sets-cp1256.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_CP1256_H
diff --git a/charset/fribidi-char-sets-iso8859-6.c b/charset/fribidi-char-sets-iso8859-6.c
index 5a52205..e3a0249 100644
--- a/charset/fribidi-char-sets-iso8859-6.c
+++ b/charset/fribidi-char-sets-iso8859-6.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-iso8859-6.h b/charset/fribidi-char-sets-iso8859-6.h
index b01830f..6a09a39 100644
--- a/charset/fribidi-char-sets-iso8859-6.h
+++ b/charset/fribidi-char-sets-iso8859-6.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_ISO8859_6_H
diff --git a/charset/fribidi-char-sets-iso8859-8.c b/charset/fribidi-char-sets-iso8859-8.c
index f7b18c9..3209484 100644
--- a/charset/fribidi-char-sets-iso8859-8.c
+++ b/charset/fribidi-char-sets-iso8859-8.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-iso8859-8.h b/charset/fribidi-char-sets-iso8859-8.h
index 456d2fb..579d0bf 100644
--- a/charset/fribidi-char-sets-iso8859-8.h
+++ b/charset/fribidi-char-sets-iso8859-8.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_ISO8859_8_H
diff --git a/charset/fribidi-char-sets-list.h b/charset/fribidi-char-sets-list.h
index 72a40cf..166a8ec 100644
--- a/charset/fribidi-char-sets-list.h
+++ b/charset/fribidi-char-sets-list.h
@@ -29,7 +29,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
/* *INDENT-OFF* */
diff --git a/charset/fribidi-char-sets-utf8.c b/charset/fribidi-char-sets-utf8.c
index dac66b3..7428a19 100644
--- a/charset/fribidi-char-sets-utf8.c
+++ b/charset/fribidi-char-sets-utf8.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets-utf8.h b/charset/fribidi-char-sets-utf8.h
index 2538775..fbf84ad 100644
--- a/charset/fribidi-char-sets-utf8.h
+++ b/charset/fribidi-char-sets-utf8.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_UTF8_H
diff --git a/charset/fribidi-char-sets.c b/charset/fribidi-char-sets.c
index 214105f..b62a079 100644
--- a/charset/fribidi-char-sets.c
+++ b/charset/fribidi-char-sets.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/charset/fribidi-char-sets.h b/charset/fribidi-char-sets.h
index bc391b4..a0e5a19 100644
--- a/charset/fribidi-char-sets.h
+++ b/charset/fribidi-char-sets.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_CHAR_SETS_H
#define _FRIBIDI_CHAR_SETS_H
diff --git a/configure.ac b/configure.ac
index 8d20a4a..cc76f03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,10 +28,10 @@ dnl FRIBIDI_BINARY_AGE = FRIBIDI_INTERFACE_AGE = 0;
dnl
m4_define(fribidi_major_version, 0)dnl
m4_define(fribidi_minor_version, 19)dnl
-m4_define(fribidi_micro_version, 7)dnl
-m4_define(fribidi_interface_version, 3)dnl
-m4_define(fribidi_interface_age, 6)dnl
-m4_define(fribidi_binary_age, 3)dnl
+m4_define(fribidi_micro_version, 8)dnl
+m4_define(fribidi_interface_version, 4)dnl
+m4_define(fribidi_interface_age, 0)dnl
+m4_define(fribidi_binary_age, 0)dnl
dnl
m4_define(fribidi_version,
m4_if(m4_eval(fribidi_micro_version()),0,
@@ -213,5 +213,6 @@ AC_CONFIG_FILES([fribidi.pc
lib/Makefile
bin/Makefile
doc/Makefile
- test/Makefile])
+ test/Makefile
+ fribidi-vs-unicode/Makefile])
AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7fe8d37..fd1d160 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -40,8 +40,7 @@ man3 = $(dist_man_MANS) $(dist_noinst_MANS)
C2MANFLAGS = $(includepath) \
-D__FRIBIDI_DOC \
-DDONT_HAVE_FRIBIDI_CONFIG_H \
- -M "Programmer's Manual" \
- -m "$(PACKAGE_NAME) $(PACKAGE_VERSION)"
+ -M "Programmer's Manual"
VPATH += $(includevpath)
diff --git a/fribidi-vs-unicode/Makefile.am b/fribidi-vs-unicode/Makefile.am
new file mode 100644
index 0000000..22e4931
--- /dev/null
+++ b/fribidi-vs-unicode/Makefile.am
@@ -0,0 +1,27 @@
+
+TESTS_ENVIRONMENT = \
+ srcdir=${srcdir}; export srcdir; \
+ top_builddir=${top_builddir}; export top_builddir; \
+ EXEEXT=${EXEEXT}; export EXEEXT;
+
+AM_TESTS_ENVIRONMENT = $(TESTS_ENVIRONMENT)
+
+AM_CPPFLAGS = \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/charset \
+ $(MISC_CFLAGS)
+LDADD = $(top_builddir)/lib/libfribidi.la $(MISC_LIBS)
+
+if FRIBIDI_USE_GLIB
+check_PROGRAMS = test test-character
+bin_PROGRAMS = $(check_PROGRAMS)
+#TESTS = \
+# test \
+# test-character
+endif
+
+test_SOURCES = test.c
+test_character_SOURCES = test-character.c
+
+-include $(top_srcdir)/git.mk
diff --git a/fribidi-vs-unicode/test-character.c b/fribidi-vs-unicode/test-character.c
new file mode 100644
index 0000000..a4087ee
--- /dev/null
+++ b/fribidi-vs-unicode/test-character.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2015, 2017 Dov Grobgeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library, in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA
+ */
+
+#include "fribidi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <glib.h>
+#include <ctype.h>
+#include <errno.h>
+
+static void die(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+
+ vfprintf(stderr, fmt, ap);
+ exit(-1);
+}
+
+FriBidiChar parse_uni_char(const char *start, int len)
+{
+ return strtoul(start, NULL, 16);
+}
+
+void parse_test_line (char *line,
+ int line_no,
+ FriBidiChar **code_points, /* Field 0 */
+ int *code_points_len,
+ int *paragraph_dir, /* Field 1 */
+ int *resolved_paragraph_embedding_level, /* Field 2 */
+ FriBidiLevel **resolved_levels, /* Field 3 */
+ int **visual_ordering, /* Field 4 */
+ int *visual_ordering_len
+ )
+{
+ GArray *code_points_array, *levels_array, *visual_ordering_array;
+ char *end;
+ int level;
+
+
+ code_points_array = g_array_new (FALSE, FALSE, sizeof (FriBidiChar));
+ levels_array = g_array_new (FALSE, FALSE, sizeof (FriBidiLevel));
+
+ /* Field 0. Code points */
+ for(;;)
+ {
+ FriBidiChar c;
+ while (isspace (*line))
+ line++;
+ end = line;
+ while (isxdigit (*end))
+ end++;
+ if (line == end)
+ break;
+
+ c = parse_uni_char (line, end - line);
+ g_array_append_val (code_points_array, c);
+
+ line = end;
+ }
+
+ *code_points_len = code_points_array->len;
+ *code_points = (FriBidiChar *) g_array_free (code_points_array, FALSE);
+
+ if (*line == ';')
+ line++;
+ else
+ die("Oops! Didn't find expected ;\n");
+
+ /* Field 1. Paragraph direction */
+ end = line;
+ while (isdigit (*end))
+ end++;
+ *paragraph_dir = atoi(line);
+ line = end;
+
+ if (*line == ';')
+ line++;
+ else
+ die("Oops! Didn't find expected ;\n");
+
+ /* Field 2. resolved paragraph_dir */
+ end = line;
+ while (isdigit (*end))
+ end++;
+ *resolved_paragraph_embedding_level = atoi(line);
+ line = end;
+
+ if (*line == ';')
+ line++;
+ else
+ die("Oops! Didn't find expected ; at line %d\n", line_no);
+
+ while (*line)
+ {
+ FriBidiLevel level;
+ char *end;
+
+ errno = 0;
+ level = strtol (line, &end, 10);
+ if (errno != EINVAL && line != end)
+ {
+ g_array_append_val (levels_array, level);
+ line = end;
+ continue;
+ }
+
+ while (isspace (*line))
+ line++;
+
+ if (*line == 'x')
+ {
+ level = (FriBidiLevel) -1;
+ g_array_append_val (levels_array, level);
+ line++;
+ continue;
+ }
+
+ if (*line == ';')
+ break;
+
+ g_assert_not_reached ();
+ }
+
+ if (levels_array->len != *code_points_len)
+ die("Oops! Different lengths for levels and codepoints at line %d!\n", line_no);
+
+ *resolved_levels = (FriBidiLevel*)g_array_free (levels_array, FALSE);
+
+ if (*line == ';')
+ line++;
+ else
+ die("Oops! Didn't find expected ; at line %d\n", line_no);
+
+ /* Field 4 - resulting visual ordering */
+ visual_ordering_array = g_array_new (FALSE, FALSE, sizeof(int));
+ for(; errno = 0, level = strtol (line, &end, 10), line != end && errno != EINVAL; line = end) {
+ g_array_append_val (visual_ordering_array, level);
+ }
+
+ *visual_ordering_len = visual_ordering_array->len;
+ *visual_ordering = (int*)g_array_free (visual_ordering_array, FALSE);
+}
+
+int
+main (int argc, char **argv)
+{
+ GError *error;
+ int next_arg;
+ GIOChannel *channel;
+ GIOStatus status;
+ const char *filename;
+ gchar *line = NULL;
+ gsize length, terminator_pos;
+ int numerrs = 0;
+ int line_no = 0;
+ FriBidiChar *code_points = NULL;
+ int code_points_len = 0;
+ int expected_ltor_len = 0;
+ int base_dir_mode = 0, paragraph_dir;
+ FriBidiLevel *expected_levels = NULL;
+ int *expected_ltor = NULL;
+ int resolved_paragraph_embedding_level;
+ FriBidiLevel *levels = NULL;
+ FriBidiCharType *types = NULL;
+ FriBidiBracketType *bracket_types = NULL;
+ FriBidiStrIndex *ltor = NULL;
+ int ltor_len;
+ gboolean debug = FALSE;
+
+ if (argc < 2)
+ {
+ g_printerr ("usage: %s [--debug] test-file-name\n", argv[0]);
+ exit (1);
+ }
+
+ next_arg = 1;
+ while(next_arg < argc && argv[next_arg][0]=='-')
+ {
+ const char *arg = argv[next_arg++];
+ if (strcmp(arg, "--debug")==0)
+ {
+ debug=TRUE;
+ continue;
+ }
+ die("Unknown option %s!\n", arg);
+ }
+
+ filename = argv[next_arg++];
+
+ error = NULL;
+ channel = g_io_channel_new_file (filename, "r", &error);
+ if (!channel)
+ {
+ g_printerr ("%s\n", error->message);
+ exit (1);
+ }
+
+ fribidi_set_debug(debug);
+
+ while (TRUE)
+ {
+ error = NULL;
+ g_free (line);
+ status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error);
+ switch (status)
+ {
+ case G_IO_STATUS_ERROR:
+ g_printerr ("%s\n", error->message);
+ exit (1);
+
+ case G_IO_STATUS_EOF:
+ goto done;
+
+ case G_IO_STATUS_AGAIN:
+ continue;
+
+ case G_IO_STATUS_NORMAL:
+ line[terminator_pos] = '\0';
+ break;
+ }
+
+ line_no++;
+
+ if (line[0] == '#' || line[0] == '\0')
+ continue;
+
+ parse_test_line (line,
+ line_no,
+ &code_points, /* Field 0 */
+ &code_points_len,
+ &paragraph_dir, /* Field 1 */
+ &resolved_paragraph_embedding_level, /* Field 2 */
+ &expected_levels, /* Field 3 */
+ &expected_ltor, /* Field 4 */
+ &expected_ltor_len
+ );
+
+ /* Test it */
+ g_free(bracket_types);
+ bracket_types = g_malloc ( sizeof(FriBidiBracketType) * code_points_len);
+
+ g_free(types);
+ types = g_malloc ( sizeof(FriBidiCharType) * code_points_len);
+
+ g_free(levels);
+ levels = g_malloc (sizeof (FriBidiLevel) * code_points_len);
+
+ g_free (ltor);
+ ltor = g_malloc (sizeof (FriBidiStrIndex) * code_points_len);
+
+
+ {
+ FriBidiParType base_dir;
+ int i, j;
+ gboolean matches;
+ int types_len = code_points_len;
+ int levels_len = types_len;
+ FriBidiBracketType NoBracket = FRIBIDI_NO_BRACKET;
+
+ for (i=0; i<code_points_len; i++)
+ {
+ types[i] = fribidi_get_bidi_type(code_points[i]);
+
+ /* Note the optimization that a bracket is always
+ of type neutral */
+ if (types[i] == FRIBIDI_TYPE_ON)
+ bracket_types[i] = fribidi_get_bracket(code_points[i]);
+ else
+ bracket_types[i] = NoBracket;
+ }
+
+ if ((paragraph_dir & (1<<base_dir_mode)) == 0)
+ continue;
+
+ switch (paragraph_dir)
+ {
+ case 0: base_dir = FRIBIDI_PAR_LTR; break;
+ case 1: base_dir = FRIBIDI_PAR_RTL; break;
+ case 2: base_dir = FRIBIDI_PAR_ON; break;
+ }
+
+ fribidi_get_par_embedding_levels (types,
+ bracket_types,
+ types_len,
+ &base_dir,
+ levels);
+
+ for (i = 0; i < types_len; i++)
+ ltor[i] = i;
+
+ fribidi_reorder_line (0 /*FRIBIDI_FLAG_REORDER_NSM*/,
+ types, types_len,
+ 0, base_dir,
+ levels,
+ NULL,
+ ltor);
+
+ j = 0;
+ for (i = 0; i < types_len; i++)
+ if (!FRIBIDI_IS_EXPLICIT_OR_BN (types[ltor[i]]))
+ ltor[j++] = ltor[i];
+ ltor_len = j;
+
+ /* Compare */
+ matches = TRUE;
+ if (matches)
+ for (i = 0; i < code_points_len; i++)
+ if (levels[i] != expected_levels[i] &&
+ expected_levels[i] != (FriBidiLevel) -1) {
+ matches = FALSE;
+ break;
+ }
+
+ if (ltor_len != expected_ltor_len)
+ matches = FALSE;
+ if (matches)
+ for (i = 0; i < ltor_len; i++)
+ if (ltor[i] != expected_ltor[i]) {
+ matches = FALSE;
+ break;
+ }
+
+ if (!matches)
+ {
+ numerrs++;
+
+ g_printerr ("failure on line %d\n", line_no);
+ g_printerr ("input is: %s\n", line);
+ g_printerr ("base dir: %s\n", paragraph_dir==0 ? "LTR"
+ : paragraph_dir==1 ? "RTL" : "AUTO");
+
+ g_printerr ("expected levels:");
+ for (i = 0; i < code_points_len; i++)
+ if (expected_levels[i] == (FriBidiLevel) -1)
+ g_printerr (" x");
+ else
+ g_printerr (" %d", expected_levels[i]);
+ g_printerr ("\n");
+ g_printerr ("returned levels:");
+ for (i = 0; i < levels_len; i++)
+ g_printerr (" %d", levels[i]);
+ g_printerr ("\n");
+
+ g_printerr ("expected order:");
+ for (i = 0; i < expected_ltor_len; i++)
+ g_printerr (" %d", expected_ltor[i]);
+ g_printerr ("\n");
+ g_printerr ("returned order:");
+ for (i = 0; i < ltor_len; i++)
+ g_printerr (" %d", ltor[i]);
+ g_printerr ("\n");
+
+ if (debug)
+ {
+ FriBidiParType base_dir;
+
+ fribidi_set_debug (1);
+
+ switch (base_dir_mode)
+ {
+ case 0: base_dir = FRIBIDI_PAR_ON; break;
+ case 1: base_dir = FRIBIDI_PAR_LTR; break;
+ case 2: base_dir = FRIBIDI_PAR_RTL; break;
+ }
+
+ fribidi_get_par_embedding_levels (types,
+ bracket_types,
+ types_len,
+ &base_dir,
+ levels);
+
+ fribidi_set_debug (0);
+ }
+
+ g_printerr ("\n");
+ }
+ }
+ }
+
+done:
+ if (error)
+ g_error_free (error);
+
+ if (numerrs)
+ g_printerr ("%d errors\n", numerrs);
+ else
+ printf("No errors found! :-)\n");
+
+ return numerrs;
+}
diff --git a/fribidi-vs-unicode/test.c b/fribidi-vs-unicode/test.c
new file mode 100644
index 0000000..35d74d2
--- /dev/null
+++ b/fribidi-vs-unicode/test.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2009 Behdad Esfahbod
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library, in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA
+ */
+
+#include <fribidi.h>
+#include <glib.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+static FriBidiCharType
+parse_char_type (const char *s, int len)
+{
+#define MATCH(name, value) \
+ if (!strncmp (name, s, len) && name[len] == '\0') return value;
+
+ MATCH ("L", FRIBIDI_TYPE_LTR);
+ MATCH ("R", FRIBIDI_TYPE_RTL);
+ MATCH ("AL", FRIBIDI_TYPE_AL);
+ MATCH ("EN", FRIBIDI_TYPE_EN);
+ MATCH ("AN", FRIBIDI_TYPE_AN);
+ MATCH ("ES", FRIBIDI_TYPE_ES);
+ MATCH ("ET", FRIBIDI_TYPE_ET);
+ MATCH ("CS", FRIBIDI_TYPE_CS);
+ MATCH ("NSM", FRIBIDI_TYPE_NSM);
+ MATCH ("BN", FRIBIDI_TYPE_BN);
+ MATCH ("B", FRIBIDI_TYPE_BS);
+ MATCH ("S", FRIBIDI_TYPE_SS);
+ MATCH ("WS", FRIBIDI_TYPE_WS);
+ MATCH ("ON", FRIBIDI_TYPE_ON);
+ MATCH ("LRE", FRIBIDI_TYPE_LRE);
+ MATCH ("RLE", FRIBIDI_TYPE_RLE);
+ MATCH ("LRO", FRIBIDI_TYPE_LRO);
+ MATCH ("RLO", FRIBIDI_TYPE_RLO);
+ MATCH ("PDF", FRIBIDI_TYPE_PDF);
+ MATCH ("LRI", FRIBIDI_TYPE_LRI);
+ MATCH ("RLI", FRIBIDI_TYPE_RLI);
+ MATCH ("FSI", FRIBIDI_TYPE_FSI);
+ MATCH ("PDI", FRIBIDI_TYPE_PDI);
+
+ g_assert_not_reached ();
+}
+
+static FriBidiLevel *
+parse_levels_line (const char *line,
+ FriBidiLevel *len)
+{
+ GArray *levels;
+
+ if (!strncmp (line, "@Levels:", 8))
+ line += 8;
+
+ levels = g_array_new (FALSE, FALSE, sizeof (FriBidiLevel));
+
+ while (*line)
+ {
+ FriBidiLevel l;
+ char *end;
+
+ errno = 0;
+ l = strtol (line, &end, 10);
+ if (errno != EINVAL && line != end)
+ {
+ g_array_append_val (levels, l);
+ line = end;
+ continue;
+ }
+
+ while (isspace (*line))
+ line++;
+
+ if (*line == 'x')
+ {
+ l = (FriBidiLevel) -1;
+ g_array_append_val (levels, l);
+ line++;
+ continue;
+ }
+
+ if (!*line)
+ break;
+
+ g_assert_not_reached ();
+ }
+
+ *len = levels->len;
+ return (FriBidiLevel *) g_array_free (levels, FALSE);
+}
+
+static FriBidiStrIndex *
+parse_reorder_line (const char *line,
+ FriBidiStrIndex *len)
+{
+ GArray *map;
+ FriBidiStrIndex l;
+ char *end;
+
+ if (!strncmp (line, "@Reorder:", 9))
+ line += 9;
+
+ map = g_array_new (FALSE, FALSE, sizeof (FriBidiStrIndex));
+
+ for(; errno = 0, l = strtol (line, &end, 10), line != end && errno != EINVAL; line = end) {
+ g_array_append_val (map, l);
+ }
+
+ *len = map->len;
+ return (FriBidiStrIndex *) g_array_free (map, FALSE);
+}
+
+static FriBidiCharType *
+parse_test_line (const char *line,
+ FriBidiStrIndex *len,
+ int *base_dir_flags)
+{
+ GArray *types;
+ FriBidiCharType c;
+ const char *end;
+
+ types = g_array_new (FALSE, FALSE, sizeof (FriBidiCharType));
+
+ for(;;) {
+ while (isspace (*line))
+ line++;
+ end = line;
+ while (isalpha (*end))
+ end++;
+ if (line == end)
+ break;
+
+ c = parse_char_type (line, end - line);
+ g_array_append_val (types, c);
+
+ line = end;
+ }
+
+ if (*line == ';')
+ line++;
+ *base_dir_flags = strtol (line, NULL, 10);
+
+ *len = types->len;
+ return (FriBidiCharType *) g_array_free (types, FALSE);
+}
+
+int
+main (int argc, char **argv)
+{
+ GIOChannel *channel;
+ GIOStatus status;
+ GError *error;
+ gchar *line = NULL;
+ gsize length, terminator_pos;
+ FriBidiStrIndex *expected_ltor = NULL;
+ FriBidiStrIndex expected_ltor_len = 0;
+ FriBidiStrIndex *ltor = NULL;
+ FriBidiStrIndex ltor_len = 0;
+ FriBidiCharType *types = NULL;
+ FriBidiStrIndex types_len = 0;
+ FriBidiLevel *expected_levels = NULL;
+ FriBidiLevel expected_levels_len = 0;
+ FriBidiLevel *levels = NULL;
+ FriBidiStrIndex levels_len = 0;
+ int base_dir_flags, base_dir_mode;
+ int numerrs = 0;
+ int numtests = 0;
+ int line_no = 0;
+ gboolean debug = FALSE;
+ const char *filename;
+ int next_arg;
+
+ if (argc < 2) {
+ g_printerr ("usage: %s [--debug] test-file-name\n", argv[0]);
+ exit (1);
+ }
+
+ next_arg = 1;
+ if (!strcmp (argv[next_arg], "--debug")) {
+ debug = TRUE;
+ next_arg++;
+ }
+
+ filename = argv[next_arg++];
+
+ error = NULL;
+ channel = g_io_channel_new_file (filename, "r", &error);
+ if (!channel) {
+ g_printerr ("%s\n", error->message);
+ exit (1);
+ }
+
+ while (TRUE) {
+ error = NULL;
+ g_free (line);
+ status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error);
+ switch (status) {
+ case G_IO_STATUS_ERROR:
+ g_printerr ("%s\n", error->message);
+ exit (1);
+
+ case G_IO_STATUS_EOF:
+ goto done;
+
+ case G_IO_STATUS_AGAIN:
+ continue;
+
+ case G_IO_STATUS_NORMAL:
+ line[terminator_pos] = '\0';
+ break;
+ }
+
+ line_no++;
+
+ if (line[0] == '#' || line[0] == '\0')
+ continue;
+
+ if (line[0] == '@')
+ {
+ if (!strncmp (line, "@Reorder:", 9)) {
+ g_free (expected_ltor);
+ expected_ltor = parse_reorder_line (line, &expected_ltor_len);
+ continue;
+ }
+ if (!strncmp (line, "@Levels:", 8)) {
+ g_free (expected_levels);
+ expected_levels = parse_levels_line (line, &expected_levels_len);
+ continue;
+ }
+ continue;
+ }
+
+ /* Test line */
+ g_free (types);
+ types = parse_test_line (line, &types_len, &base_dir_flags);
+
+ g_free (levels);
+ levels = g_malloc (sizeof (FriBidiLevel) * types_len);
+ levels_len = types_len;
+
+ g_free (ltor);
+ ltor = g_malloc (sizeof (FriBidiStrIndex) * types_len);
+
+ /* Test it */
+ for (base_dir_mode = 0; base_dir_mode < 3; base_dir_mode++) {
+ FriBidiParType base_dir;
+ int i, j;
+ gboolean matches;
+
+ if ((base_dir_flags & (1<<base_dir_mode)) == 0)
+ continue;
+
+ numtests++;
+
+ switch (base_dir_mode) {
+ case 0: base_dir = FRIBIDI_PAR_ON; break;
+ case 1: base_dir = FRIBIDI_PAR_LTR; break;
+ case 2: base_dir = FRIBIDI_PAR_RTL; break;
+ }
+
+ fribidi_get_par_embedding_levels (types,
+ NULL, /* Brackets are not used in the BidiTest.txt file */
+ types_len,
+ &base_dir,
+ levels);
+
+ for (i = 0; i < types_len; i++)
+ ltor[i] = i;
+
+ fribidi_reorder_line (0 /*FRIBIDI_FLAG_REORDER_NSM*/,
+ types, types_len,
+ 0, base_dir,
+ levels,
+ NULL,
+ ltor);
+
+ j = 0;
+ for (i = 0; i < types_len; i++)
+ if (!FRIBIDI_IS_EXPLICIT_OR_BN (types[ltor[i]]))
+ ltor[j++] = ltor[i];
+ ltor_len = j;
+
+ /* Compare */
+ matches = TRUE;
+ if (levels_len != expected_levels_len)
+ matches = FALSE;
+ if (matches)
+ for (i = 0; i < levels_len; i++)
+ if (levels[i] != expected_levels[i] &&
+ expected_levels[i] != (FriBidiLevel) -1) {
+ matches = FALSE;
+ break;
+ }
+
+ if (ltor_len != expected_ltor_len)
+ matches = FALSE;
+ if (matches)
+ for (i = 0; i < ltor_len; i++)
+ if (ltor[i] != expected_ltor[i]) {
+ matches = FALSE;
+ break;
+ }
+
+ if (!matches)
+ {
+ numerrs++;
+
+ g_printerr ("failure on line %d\n", line_no);
+ g_printerr ("input is: %s\n", line);
+ g_printerr ("base dir: %s\n", base_dir_mode==0 ? "auto"
+ : base_dir_mode==1 ? "LTR" : "RTL");
+
+ g_printerr ("expected levels:");
+ for (i = 0; i < expected_levels_len; i++)
+ if (expected_levels[i] == (FriBidiLevel) -1)
+ g_printerr (" x");
+ else
+ g_printerr (" %d", expected_levels[i]);
+ g_printerr ("\n");
+ g_printerr ("returned levels:");
+ for (i = 0; i < levels_len; i++)
+ g_printerr (" %d", levels[i]);
+ g_printerr ("\n");
+
+ g_printerr ("expected order:");
+ for (i = 0; i < expected_ltor_len; i++)
+ g_printerr (" %d", expected_ltor[i]);
+ g_printerr ("\n");
+ g_printerr ("returned order:");
+ for (i = 0; i < ltor_len; i++)
+ g_printerr (" %d", ltor[i]);
+ g_printerr ("\n");
+
+ if (debug) {
+ FriBidiParType base_dir;
+
+ fribidi_set_debug (1);
+
+ switch (base_dir_mode) {
+ case 0: base_dir = FRIBIDI_PAR_ON; break;
+ case 1: base_dir = FRIBIDI_PAR_LTR; break;
+ case 2: base_dir = FRIBIDI_PAR_RTL; break;
+ }
+
+ fribidi_get_par_embedding_levels (types,
+ NULL, /* No bracket types */
+ types_len,
+ &base_dir,
+ levels);
+
+ fribidi_set_debug (0);
+ }
+
+ g_printerr ("\n");
+ }
+ }
+ }
+
+done:
+ g_free (ltor);
+ g_free (levels);
+ g_free (expected_ltor);
+ g_free (types);
+ g_free (line);
+ g_io_channel_unref (channel);
+ if (error)
+ g_error_free (error);
+
+ if (numerrs)
+ g_printerr ("%d errors out of %d total tests\n", numerrs, numtests);
+ else
+ printf("No errors found! :-)\n");
+
+ return numerrs;
+}
diff --git a/gen.tab/Makefile.am b/gen.tab/Makefile.am
index 3b185a9..b5cfd9c 100644
--- a/gen.tab/Makefile.am
+++ b/gen.tab/Makefile.am
@@ -3,13 +3,17 @@ EXTRA_PROGRAMS = \
gen-bidi-type-tab \
gen-joining-type-tab \
gen-arabic-shaping-tab \
- gen-mirroring-tab
+ gen-mirroring-tab \
+ gen-brackets-tab \
+ gen-brackets-type-tab
gen_unicode_version_SOURCES = gen-unicode-version.c
gen_bidi_type_tab_SOURCES = gen-bidi-type-tab.c packtab.c packtab.h
gen_joining_type_tab_SOURCES = gen-joining-type-tab.c packtab.c packtab.h
gen_arabic_shaping_tab_SOURCES = gen-arabic-shaping-tab.c
gen_mirroring_tab_SOURCES = gen-mirroring-tab.c packtab.c packtab.h
+gen_brackets_tab_SOURCES = gen-brackets-tab.c packtab.c packtab.h
+gen_brackets_type_tab_SOURCES = gen-brackets-type-tab.c packtab.c packtab.h
CLEANFILES = $(EXTRA_PROGRAMS)
DISTCLEANFILES =
@@ -34,6 +38,7 @@ UCD_FILES = \
unidata/ReadMe.txt \
unidata/UnicodeData.txt \
unidata/BidiMirroring.txt \
+ unidata/BidiBrackets.txt \
unidata/ArabicShaping.txt
EXTRA_DIST = $(UCD_FILES)
@@ -99,6 +104,31 @@ mirroring.tab.i: \
./$(gen_mirroring_tab) $(COMPRESSION) $^ > $@ \
|| ($(RM) $@ && false)
+# generate brackets.tab.i
+
+gen_brackets_tab = gen-brackets-tab$(EXEEXT)
+
+brackets.tab.i: \
+ BidiBrackets.txt \
+ UnicodeData.txt \
+ fribidi-unicode-version.h \
+ $(gen_brackets_tab_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) $(gen_brackets_tab)
+ ./$(gen_brackets_tab) $(COMPRESSION) $^ > $@ \
+ || ($(RM) $@ && false)
+
+# generate brackets-type.tab.i
+
+gen_brackets_type_tab = gen-brackets-type-tab$(EXEEXT)
+
+brackets-type.tab.i: \
+ BidiBrackets.txt \
+ fribidi-unicode-version.h \
+ $(gen_brackets_type_tab_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) $(gen_brackets_tab)
+ ./$(gen_brackets_type_tab) $(COMPRESSION) $^ > $@ \
+ || ($(RM) $@ && false)
+
# generate fribidi-unicode-version.h
gen_unicode_version = gen-unicode-version$(EXEEXT)
diff --git a/gen.tab/gen-arabic-shaping-tab.c b/gen.tab/gen-arabic-shaping-tab.c
index fc21db2..93ea40e 100644
--- a/gen.tab/gen-arabic-shaping-tab.c
+++ b/gen.tab/gen-arabic-shaping-tab.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/gen.tab/gen-bidi-type-tab.c b/gen.tab/gen-bidi-type-tab.c
index aacd768..a29a3f8 100644
--- a/gen.tab/gen-bidi-type-tab.c
+++ b/gen.tab/gen-bidi-type-tab.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/gen.tab/gen-brackets-tab.c b/gen.tab/gen-brackets-tab.c
new file mode 100644
index 0000000..3142a1a
--- /dev/null
+++ b/gen.tab/gen-brackets-tab.c
@@ -0,0 +1,345 @@
+/* FriBidi
+ * gen-brackets-tab.c - generate brackets.tab.i
+ *
+ * Author:
+ * Behdad Esfahbod, 2001, 2002, 2004
+ * Dov Grobgeld 2017
+ *
+ * Copyright (C) 2004 Sharif FarsiWeb, Inc
+ * Copyright (C) 2001,2002,2004 Behdad Esfahbod
+ * Copyright (C) 2017 Dov Grobgeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library, in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA
+ *
+ * For licensing issues, contact <fribidi.license@gmail.com>.
+ */
+
+#include <common.h>
+#include <ctype.h>
+#include <fribidi-unicode.h>
+
+#include <stdio.h>
+#if STDC_HEADERS+0
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H+0
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H+0
+# include <strings.h>
+#endif
+
+#include "packtab.h"
+
+#define appname "gen-brackets-tab"
+#define outputname "brackets.tab.i"
+
+static void
+die (
+ const char *msg
+)
+{
+ fprintf (stderr, appname ": %s\n", msg);
+ exit (1);
+}
+
+static void
+die2 (
+ const char *fmt,
+ const char *p
+)
+{
+ fprintf (stderr, appname ": ");
+ fprintf (stderr, fmt, p);
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+static void
+die3 (
+ const char *fmt,
+ const char *p,
+ const char *q
+)
+{
+ fprintf (stderr, appname ": ");
+ fprintf (stderr, fmt, p, q);
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+static void
+die4 (
+ const char *fmt,
+ unsigned long l,
+ unsigned long p,
+ unsigned long q
+)
+{
+ fprintf (stderr, appname ": ");
+ fprintf (stderr, fmt, l, p, q);
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+#define table_name "Brk"
+#define macro_name "FRIBIDI_GET_BRACKETS"
+
+static signed int table[FRIBIDI_UNICODE_CHARS];
+static signed int equiv_table[FRIBIDI_UNICODE_CHARS];
+static char buf[4000];
+static signed long max_dist;
+
+static void
+init (
+ void
+)
+{
+ max_dist = 0;
+}
+
+static void
+clear_tabs (
+ void
+)
+{
+ register FriBidiChar c;
+
+ for (c = 0; c < FRIBIDI_UNICODE_CHARS; c++)
+ {
+ table[c] = 0;
+ equiv_table[c] = 0;
+ }
+}
+
+static signed int table[FRIBIDI_UNICODE_CHARS];
+static char buf[4000];
+
+/* Read the canonical mapping of unicode characters and store them in the
+ equiv_table array. */
+static void
+read_unicode_data_txt_equivalence (
+ FILE *f
+)
+{
+ unsigned long c, l;
+
+ l = 0;
+ while (fgets (buf, sizeof buf, f))
+ {
+ int i;
+ const char *s = buf;
+ char ce_string[100]; /* For parsing the equivalence */
+
+ l++;
+
+ while (*s == ' ')
+ s++;
+
+ if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
+ continue;
+ /* Field: 0 ; 1 ; 2 ; 3 ; 4 ; 5 */
+ i = sscanf (s, "%lx;%*[^;];%*[^;];%*[^;];%*[^;];%[^;]", &c, ce_string);
+ if (c >= FRIBIDI_UNICODE_CHARS)
+ {
+ fprintf (stderr, "invalid input at line %ld: %s", l, s);
+ exit(1);
+ }
+ if (i==1)
+ continue;
+
+ /* split and parse ce */
+ char *p = ce_string;
+ int ce = -1;
+ int in_tag = 0;
+ while(*p)
+ {
+ if (*p==';')
+ break;
+ else if (*p=='<')
+ in_tag = 1;
+ else if (*p=='>')
+ in_tag = 0;
+ else if (!in_tag && isalnum(*p))
+ {
+ /* Assume we got a hexa decimal */
+ ce = strtol(p,NULL,16);
+ break;
+ }
+ p++;
+ }
+
+ /* FIXME: We don't handle First..Last parts of UnicodeData.txt,
+ * but it works, since all those are LTR. */
+ equiv_table[c] = ce;
+ }
+}
+
+static void
+read_bidi_brackets_txt (
+ FILE *f
+)
+{
+ unsigned long l;
+
+ l = 0;
+ while (fgets (buf, sizeof buf, f))
+ {
+ unsigned long i, j;
+ signed long dist;
+ int k;
+ const char *s = buf;
+ char open_close;
+
+ l++;
+
+ while (*s == ' ')
+ s++;
+
+ if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
+ continue;
+
+ k = sscanf (s, "%lx; %lx; %c", &i, &j, &open_close);
+ if (k != 3 || i >= FRIBIDI_UNICODE_CHARS || j >= FRIBIDI_UNICODE_CHARS)
+ die4 ("invalid pair in input at line %ld: %04lX, %04lX", l, i, j);
+
+ /* Open braces map to themself */
+ if (open_close=='o')
+ j = i;
+
+ /* Turn j into the unicode equivalence if it exists */
+ if (equiv_table[j])
+ {
+ /* printf("Found match for %04x->%04x\n", j, equiv_table[j]); */
+ j = equiv_table[j];
+ }
+
+ dist = ((signed long) j - (signed long) i);
+ table[i] = dist;
+ if (dist > max_dist)
+ max_dist = dist;
+ else if (-dist > max_dist)
+ max_dist = -dist;
+ }
+}
+
+static void
+read_data (
+ const char *bracket_datafile_type,
+ const char *bracket_datafile_name,
+ const char *uni_datafile_type,
+ const char *uni_datafile_name
+)
+{
+ FILE *f;
+
+ clear_tabs ();
+
+ fprintf (stderr, "Reading `%s'\n", uni_datafile_name);
+ if (!(f = fopen (uni_datafile_name, "rt")))
+ die2 ("error: cannot open `%s' for reading", bracket_datafile_name);
+
+ if (!strcmp (uni_datafile_type, "UnicodeData.txt"))
+ read_unicode_data_txt_equivalence (f);
+ else
+ die2 ("error: unknown data-file-type %s", uni_datafile_type);
+
+ fprintf (stderr, "Reading `%s'\n", bracket_datafile_name);
+ if (!(f = fopen (bracket_datafile_name, "rt")))
+ die2 ("error: cannot open `%s' for reading", bracket_datafile_name);
+
+ if (!strcmp (bracket_datafile_type, "BidiBrackets.txt"))
+ read_bidi_brackets_txt (f);
+ else
+ die2 ("error: unknown data-file-type %s", bracket_datafile_type);
+
+ fclose (f);
+}
+
+static void
+gen_brackets_tab (
+ int max_depth,
+ const char *data_file_type
+)
+{
+ int key_bytes;
+ const char *key_type;
+
+ fprintf (stderr,
+ "Generating `" outputname "', it may take up to a few minutes\n");
+ printf ("/* " outputname "\n * generated by " appname " (" FRIBIDI_NAME " "
+ FRIBIDI_VERSION ")\n" " * from the file %s of Unicode version "
+ FRIBIDI_UNICODE_VERSION ". */\n\n", data_file_type);
+
+ printf ("#define PACKTAB_UINT8 fribidi_uint8\n"
+ "#define PACKTAB_UINT16 fribidi_uint16\n"
+ "#define PACKTAB_UINT32 fribidi_uint32\n\n");
+
+ key_bytes = max_dist <= 0x7f ? 1 : max_dist < 0x7fff ? 2 : 4;
+ key_type = key_bytes == 1 ? "fribidi_int8" : key_bytes == 2 ?
+ "fribidi_int16" : "fribidi_int32";
+
+ if (!pack_table
+ (table, FRIBIDI_UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL,
+ key_type, table_name, macro_name "_DELTA", stdout))
+ die ("error: insufficient memory, decrease max_depth");
+
+ printf ("#undef PACKTAB_UINT8\n"
+ "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n");
+
+ printf ("#define " macro_name "(x) ((x) + " macro_name "_DELTA(x))\n\n");
+
+ printf ("/* End of generated " outputname " */\n");
+}
+
+int
+main (
+ int argc,
+ const char **argv
+)
+{
+ const char *bracket_datafile_type = "BidiBrackets.txt";
+ const char *uni_datafile_type = "UnicodeData.txt";
+
+ if (argc < 4)
+ die3 ("usage:\n " appname " max-depth /path/to/%s /path/to/%s [junk...]",
+ bracket_datafile_type,
+ uni_datafile_type);
+
+ {
+ int max_depth = atoi (argv[1]);
+ const char *bracket_datafile_name = argv[2];
+ const char *uni_datafile_name = argv[3];
+
+ if (max_depth < 2)
+ die ("invalid depth");
+
+ init ();
+ read_data (bracket_datafile_type, bracket_datafile_name,
+ uni_datafile_type, uni_datafile_name);
+ gen_brackets_tab (max_depth, bracket_datafile_type);
+ }
+
+ return 0;
+}
diff --git a/gen.tab/gen-brackets-type-tab.c b/gen.tab/gen-brackets-type-tab.c
new file mode 100644
index 0000000..6c7334c
--- /dev/null
+++ b/gen.tab/gen-brackets-type-tab.c
@@ -0,0 +1,238 @@
+/* FriBidi
+ * gen-brackets-type-tab.c - generate brackets.tab.i
+ *
+ * Author:
+ * Behdad Esfahbod, 2001, 2002, 2004
+ * Dov Grobgeld 2017
+ *
+ * Copyright (C) 2004 Sharif FarsiWeb, Inc
+ * Copyright (C) 2001,2002,2004 Behdad Esfahbod
+ * Copyright (C) 2017 Dov Grobgeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library, in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA
+ *
+ * For licensing issues, contact <fribidi.license@gmail.com>.
+ */
+
+#include <common.h>
+
+#include <fribidi-unicode.h>
+
+#include <stdio.h>
+#if STDC_HEADERS+0
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H+0
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H+0
+# include <strings.h>
+#endif
+
+#include "packtab.h"
+
+#define appname "gen-brackets-type-tab"
+#define outputname "brackets-type.tab.i"
+
+static void
+die (
+ const char *msg
+)
+{
+ fprintf (stderr, appname ": %s\n", msg);
+ exit (1);
+}
+
+static void
+die2 (
+ const char *fmt,
+ const char *p
+)
+{
+ fprintf (stderr, appname ": ");
+ fprintf (stderr, fmt, p);
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+static void
+die4 (
+ const char *fmt,
+ unsigned long l,
+ unsigned long p,
+ unsigned long q
+)
+{
+ fprintf (stderr, appname ": ");
+ fprintf (stderr, fmt, l, p, q);
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+#define table_name "Brt"
+#define macro_name "FRIBIDI_GET_BRACKET_TYPE"
+
+static signed int table[FRIBIDI_UNICODE_CHARS];
+static char buf[4000];
+static signed long max_dist;
+
+static void
+init (
+ void
+)
+{
+ max_dist = 0;
+}
+
+static void
+clear_tab (
+ void
+)
+{
+ register FriBidiChar c;
+
+ for (c = 0; c < FRIBIDI_UNICODE_CHARS; c++)
+ table[c] = 0;
+}
+
+static void
+init_tab_brackets_type_txt (
+ void
+)
+{
+ clear_tab ();
+}
+
+static void
+read_bidi_brackets_type_txt (
+ FILE *f
+)
+{
+ unsigned long l;
+
+ init_tab_brackets_type_txt ();
+
+ l = 0;
+ while (fgets (buf, sizeof buf, f))
+ {
+ unsigned long i, j;
+ int k;
+ const char *s = buf;
+ char open_close;
+
+ l++;
+
+ while (*s == ' ')
+ s++;
+
+ if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
+ continue;
+
+ k = sscanf (s, "%lx; %lx; %c", &i, &j, &open_close);
+ if (k != 3 || i >= FRIBIDI_UNICODE_CHARS || j >= FRIBIDI_UNICODE_CHARS)
+ die4 ("invalid pair in input at line %ld: %04lX, %04lX", l, i, j);
+ table[i] = 1 + (0x2 * (open_close=='o'));
+ }
+}
+
+static void
+read_data (
+ const char *data_file_type,
+ const char *data_file_name
+)
+{
+ FILE *f;
+
+ fprintf (stderr, "Reading `%s'\n", data_file_name);
+ if (!(f = fopen (data_file_name, "rt")))
+ die2 ("error: cannot open `%s' for reading", data_file_name);
+
+ if (!strcmp (data_file_type, "BidiBrackets.txt"))
+ read_bidi_brackets_type_txt (f);
+ else
+ die2 ("error: unknown data-file-type %s", data_file_type);
+
+ fclose (f);
+}
+
+static void
+gen_brackets_tab (
+ int max_depth,
+ const char *data_file_type
+)
+{
+ int key_bytes;
+ const char *key_type;
+
+ fprintf (stderr,
+ "Generating `" outputname "', it may take up to a few minutes\n");
+ printf ("/* " outputname "\n * generated by " appname " (" FRIBIDI_NAME " "
+ FRIBIDI_VERSION ")\n" " * from the file %s of Unicode version "
+ FRIBIDI_UNICODE_VERSION ". */\n\n", data_file_type);
+
+ printf ("#define PACKTAB_UINT8 fribidi_uint8\n"
+ "#define PACKTAB_UINT16 fribidi_uint16\n"
+ "#define PACKTAB_UINT32 fribidi_uint32\n\n");
+
+ key_bytes = 1;
+ key_type = key_bytes == 1 ? "fribidi_int8" : key_bytes == 2 ?
+ "fribidi_int16" : "fribidi_int32";
+
+ if (!pack_table
+ (table, FRIBIDI_UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL,
+ key_type, table_name, macro_name, stdout))
+ die ("error: insufficient memory, decrease max_depth");
+
+ printf ("#undef PACKTAB_UINT8\n"
+ "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n");
+
+ printf ("/* End of generated " outputname " */\n");
+}
+
+int
+main (
+ int argc,
+ const char **argv
+)
+{
+ const char *data_file_type = "BidiBrackets.txt";
+
+ if (argc < 3)
+ die2 ("usage:\n " appname " max-depth /path/to/%s [junk...]",
+ data_file_type);
+
+ {
+ int max_depth = atoi (argv[1]);
+ const char *data_file_name = argv[2];
+
+ if (max_depth < 2)
+ die ("invalid depth");
+
+ init ();
+ read_data (data_file_type, data_file_name);
+ gen_brackets_tab (max_depth, data_file_type);
+ }
+
+ return 0;
+}
diff --git a/gen.tab/gen-joining-type-tab.c b/gen.tab/gen-joining-type-tab.c
index 809d113..3d2a7f4 100644
--- a/gen.tab/gen-joining-type-tab.c
+++ b/gen.tab/gen-joining-type-tab.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/gen.tab/gen-mirroring-tab.c b/gen.tab/gen-mirroring-tab.c
index 4256d36..f577e68 100644
--- a/gen.tab/gen-mirroring-tab.c
+++ b/gen.tab/gen-mirroring-tab.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/gen.tab/gen-unicode-version.c b/gen.tab/gen-unicode-version.c
index ea9a9b5..f73e3d7 100644
--- a/gen.tab/gen-unicode-version.c
+++ b/gen.tab/gen-unicode-version.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include <common.h>
diff --git a/lib/Headers.mk b/lib/Headers.mk
index 898c16d..b8f54ef 100644
--- a/lib/Headers.mk
+++ b/lib/Headers.mk
@@ -12,6 +12,7 @@ libfribidi_la_headers = \
fribidi-joining-types.h \
fribidi-joining-types-list.h \
fribidi-mirroring.h \
+ fribidi-brackets.h \
fribidi-shape.h \
fribidi-types.h \
fribidi-unicode.h \
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f96bc6d..fd15292 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -43,14 +43,15 @@ libfribidi_la_SOURCES = \
fribidi-deprecated.c \
fribidi-joining.c \
fribidi-joining-types.c \
- fribidi-mem.c \
fribidi-mirroring.c \
+ fribidi-brackets.c \
fribidi-run.c \
fribidi-shape.c \
joining-type.tab.i \
joining-types.h \
- mem.h \
mirroring.tab.i \
+ brackets.tab.i \
+ brackets-type.tab.i \
run.h
GENERATEDSOURCES = \
@@ -58,7 +59,9 @@ GENERATEDSOURCES = \
arabic-shaping.tab.i \
bidi-type.tab.i \
joining-type.tab.i \
- mirroring.tab.i
+ mirroring.tab.i \
+ brackets.tab.i \
+ brackets-type.tab.i
BUILT_SOURCES = \
$(GENERATEDSOURCES) \
diff --git a/lib/bidi-types.h b/lib/bidi-types.h
index acdd174..19a12d0 100644
--- a/lib/bidi-types.h
+++ b/lib/bidi-types.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _BIDI_TYPES_H
#define _BIDI_TYPES_H
diff --git a/lib/common.h b/lib/common.h
index 3e484b0..739e647 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -27,7 +27,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _COMMON_H
#define _COMMON_H
@@ -113,7 +113,7 @@
# define fribidi_free free
#else /* fribidi_malloc */
# ifndef fribidi_free
-# error You should define fribidi_free too when you define fribidi_malloc.
+# error "You should define fribidi_free too when you define fribidi_malloc."
# endif /* !fribidi_free */
#endif /* fribidi_malloc */
@@ -140,7 +140,7 @@
# endif /* !HAVE_ASM_PAGE_H */
#else /* FRIBIDI_CHUNK_SIZE */
# if FRIBIDI_CHUNK_SIZE < 256
-# error FRIBIDI_CHUNK_SIZE now should define the size of a chunk in bytes.
+# error "FRIBIDI_CHUNK_SIZE now should define the size of a chunk in bytes."
# endif /* FRIBIDI_CHUNK_SIZE < 256 */
#endif /* FRIBIDI_CHUNK_SIZE */
@@ -166,7 +166,7 @@
#if HAVE_STRINGIZE+0
# define STRINGIZE(symbol) #symbol
#else /* !HAVE_STRINGIZE */
-# define STRINGIZE(symbol) (no stringize operator available)
+# error "No stringize operator available?"
#endif /* !HAVE_STRINGIZE */
/* As per recommendation of GNU Coding Standards. */
diff --git a/lib/debug.h b/lib/debug.h
index 78c659a..d0cff71 100644
--- a/lib/debug.h
+++ b/lib/debug.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _DEBUG_H
#define _DEBUG_H
@@ -66,10 +66,18 @@
FRIBIDI_BEGIN_STMT \
FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t); \
FRIBIDI_END_STMT
+#define MSG3(s, t, u) \
+ FRIBIDI_BEGIN_STMT \
+ FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t, u); \
+ FRIBIDI_END_STMT
#define MSG5(s, t, u, v, w) \
FRIBIDI_BEGIN_STMT \
FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t, u, v, w); \
FRIBIDI_END_STMT
+#define MSG6(s, t, u, v, w, z) \
+ FRIBIDI_BEGIN_STMT \
+ FRIBIDI_FPRINTF(FRIBIDI_STDERR_ s, t, u, v, w, z); \
+ FRIBIDI_END_STMT
#endif /* !MSG */
#ifndef DBG
diff --git a/lib/fribidi-arabic.c b/lib/fribidi-arabic.c
index 9e95de4..b2d10e3 100644
--- a/lib/fribidi-arabic.c
+++ b/lib/fribidi-arabic.c
@@ -18,7 +18,7 @@
* along with GNU FriBidi; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * For licensing issues, contact <license@farsiweb.info> or write to
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
* Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
*/
/* $Id: fribidi-arabic.c,v 1.3 2007-04-05 16:14:39 behdad Exp $
diff --git a/lib/fribidi-arabic.h b/lib/fribidi-arabic.h
index 889013c..6076256 100644
--- a/lib/fribidi-arabic.h
+++ b/lib/fribidi-arabic.h
@@ -18,7 +18,7 @@
* along with GNU FriBidi; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * For licensing issues, contact <license@farsiweb.info> or write to
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
* Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
*/
/* $Id: fribidi-arabic.h,v 1.1 2005-11-03 01:39:01 behdad Exp $
diff --git a/lib/fribidi-bidi-types-list.h b/lib/fribidi-bidi-types-list.h
index fa8c32b..73ae2ca 100644
--- a/lib/fribidi-bidi-types-list.h
+++ b/lib/fribidi-bidi-types-list.h
@@ -29,7 +29,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
/* *INDENT-OFF* */
#endif /* !__FRIBIDI_DOC */
@@ -61,6 +61,10 @@ _FRIBIDI_ADD_TYPE (RLE, '+') /* Right-to-Left Embedding */
_FRIBIDI_ADD_TYPE (LRO, '+') /* Left-to-Right Override */
_FRIBIDI_ADD_TYPE (RLO, '+') /* Right-to-Left Override */
_FRIBIDI_ADD_TYPE (PDF, '-') /* Pop Directional Flag */
+_FRIBIDI_ADD_TYPE (LRI, '+') /* Left-to-Right Isolate */
+_FRIBIDI_ADD_TYPE (RLI, '+') /* Right-to-Left Isolate */
+_FRIBIDI_ADD_TYPE (FSI, '+') /* First-Strong Isolate */
+_FRIBIDI_ADD_TYPE (PDI, '-') /* Pop Directional Isolate */
#if defined(_FRIBIDI_ADD_ALIAS)
_FRIBIDI_ADD_ALIAS (L, LTR)
diff --git a/lib/fribidi-bidi-types.c b/lib/fribidi-bidi-types.c
index 5bbc980..fe4f64f 100644
--- a/lib/fribidi-bidi-types.c
+++ b/lib/fribidi-bidi-types.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
diff --git a/lib/fribidi-bidi-types.h b/lib/fribidi-bidi-types.h
index 0f6abda..bff0021 100644
--- a/lib/fribidi-bidi-types.h
+++ b/lib/fribidi-bidi-types.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_BIDI_TYPES_H
#define _FRIBIDI_BIDI_TYPES_H
@@ -57,17 +57,20 @@ typedef signed char FriBidiLevel;
#define FRIBIDI_MASK_SENTINEL 0x00000080L /* Is sentinel */
/* Sentinels are not valid chars, just identify the start/end of strings. */
-/* Each char can be only one of the five following. */
+/* Each char can be only one of the six following. */
#define FRIBIDI_MASK_LETTER 0x00000100L /* Is letter: L, R, AL */
#define FRIBIDI_MASK_NUMBER 0x00000200L /* Is number: EN, AN */
#define FRIBIDI_MASK_NUMSEPTER 0x00000400L /* Is separator or terminator: ES, ET, CS */
#define FRIBIDI_MASK_SPACE 0x00000800L /* Is space: BN, BS, SS, WS */
-#define FRIBIDI_MASK_EXPLICIT 0x00001000L /* Is expilict mark: LRE, RLE, LRO, RLO, PDF */
+#define FRIBIDI_MASK_EXPLICIT 0x00001000L /* Is explicit mark: LRE, RLE, LRO, RLO, PDF */
+#define FRIBIDI_MASK_ISOLATE 0x00008000L /* Is isolate mark: LRI, RLI, FSI, PDI */
/* Can be set only if FRIBIDI_MASK_SPACE is also set. */
#define FRIBIDI_MASK_SEPARATOR 0x00002000L /* Is text separator: BS, SS */
/* Can be set only if FRIBIDI_MASK_EXPLICIT is also set. */
#define FRIBIDI_MASK_OVERRIDE 0x00004000L /* Is explicit override: LRO, RLO */
+#define FRIBIDI_MASK_FIRST 0x02000000L /* Whether direction is determined by first strong */
+
/* The following exist to make types pairwise different, some of them can
* be removed but are here because of efficiency (make queries faster). */
@@ -167,6 +170,18 @@ typedef signed char FriBidiLevel;
#define FRIBIDI_TYPE_PRIVATE ( FRIBIDI_MASK_PRIVATE )
+/* New types in Unicode 6.3 */
+
+/* Left-to-Right Isolate */
+#define FRIBIDI_TYPE_LRI_VAL ( FRIBIDI_MASK_NEUTRAL | FRIBIDI_MASK_ISOLATE )
+/* Right-to-Left Isolate */
+#define FRIBIDI_TYPE_RLI_VAL ( FRIBIDI_MASK_NEUTRAL | FRIBIDI_MASK_ISOLATE | FRIBIDI_MASK_RTL )
+/* First strong isolate */
+#define FRIBIDI_TYPE_FSI_VAL ( FRIBIDI_MASK_NEUTRAL | FRIBIDI_MASK_ISOLATE | FRIBIDI_MASK_FIRST )
+
+/* Pop Directional Isolate*/
+#define FRIBIDI_TYPE_PDI_VAL ( FRIBIDI_MASK_NEUTRAL | FRIBIDI_MASK_WEAK | FRIBIDI_MASK_ISOLATE )
+
/* Define Enums only if sizeof(int) == 4 (UTF-32), and not compiling C++.
* The problem with C++ is that then casts between int32 and enum will fail!
*/
@@ -214,6 +229,10 @@ typedef fribidi_uint32 FriBidiCharType;
# define FRIBIDI_TYPE_LRO FRIBIDI_TYPE_LRO_VAL
# define FRIBIDI_TYPE_RLO FRIBIDI_TYPE_RLO_VAL
# define FRIBIDI_TYPE_PDF FRIBIDI_TYPE_PDF_VAL
+# define FRIBIDI_TYPE_LRI FRIBIDI_TYPE_PDF_LRI
+# define FRIBIDI_TYPE_RLI FRIBIDI_TYPE_PDF_RLI
+# define FRIBIDI_TYPE_FSI FRIBIDI_TYPE_PDF_FSI
+# define FRIBIDI_TYPE_PDI FRIBIDI_TYPE_PDF_PDI
typedef fribidi_uint32 FriBidiParType;
# define FRIBIDI_PAR_LTR FRIBIDI_TYPE_LTR_VAL
@@ -273,6 +292,8 @@ typedef fribidi_uint32 FriBidiParType;
#define FRIBIDI_IS_SPACE(p) ((p) & FRIBIDI_MASK_SPACE)
/* Is explicit mark: LRE, RLE, LRO, RLO, PDF? */
#define FRIBIDI_IS_EXPLICIT(p) ((p) & FRIBIDI_MASK_EXPLICIT)
+/* Is isolator */
+#define FRIBIDI_IS_ISOLATE(p) ((p) & FRIBIDI_MASK_ISOLATE)
/* Is text separator: BS, SS? */
#define FRIBIDI_IS_SEPARATOR(p) ((p) & FRIBIDI_MASK_SEPARATOR)
@@ -303,6 +324,10 @@ typedef fribidi_uint32 FriBidiParType;
#define FRIBIDI_IS_EXPLICIT_OR_BN_OR_NSM(p) \
((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_BN | FRIBIDI_MASK_NSM))
+/* Is explicit or BN or NSM: LRE, RLE, LRO, RLO, PDF, BN, NSM? */
+#define FRIBIDI_IS_EXPLICIT_OR_ISOLATE_OR_BN_OR_NSM(p) \
+ ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_ISOLATE | FRIBIDI_MASK_BN | FRIBIDI_MASK_NSM))
+
/* Is explicit or BN or WS: LRE, RLE, LRO, RLO, PDF, BN, WS? */
#define FRIBIDI_IS_EXPLICIT_OR_BN_OR_WS(p) \
((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_BN | FRIBIDI_MASK_WS))
diff --git a/lib/fribidi-bidi.c b/lib/fribidi-bidi.c
index 89d6546..e000323 100644
--- a/lib/fribidi-bidi.c
+++ b/lib/fribidi-bidi.c
@@ -9,11 +9,11 @@
*
* Authors:
* Behdad Esfahbod, 2001, 2002, 2004
- * Dov Grobgeld, 1999, 2000
+ * Dov Grobgeld, 1999, 2000, 2017
*
* Copyright (C) 2004 Sharif FarsiWeb, Inc
* Copyright (C) 2001,2002 Behdad Esfahbod
- * Copyright (C) 1999,2000 Dov Grobgeld
+ * Copyright (C) 1999,2000,2017 Dov Grobgeld
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,16 +30,16 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
#include <fribidi-bidi.h>
#include <fribidi-mirroring.h>
+#include <fribidi-brackets.h>
#include <fribidi-unicode.h>
-#include "mem.h"
#include "bidi-types.h"
#include "run.h"
@@ -57,6 +57,17 @@
#define RL_POS(list) ((list)->pos)
#define RL_LEVEL(list) ((list)->level)
+/* "Within this scope, bidirectional types EN and AN are treated as R" */
+#define RL_TYPE_AN_EN_AS_RTL(list) ( \
+ (((list)->type == FRIBIDI_TYPE_AN) || ((list)->type == FRIBIDI_TYPE_EN) | ((list)->type == FRIBIDI_TYPE_RTL)) ? FRIBIDI_TYPE_RTL : (list)->type)
+#define RL_BRACKET_TYPE(list) ((list)->bracket_type)
+#define RL_ISOLATE_LEVEL(list) ((list)->isolate_level)
+
+/* Compare for equality */
+#define RL_BRACKET_TYPE_EQUAL(list1,list2) ( \
+ (list1)->bracket_type.bracket_id == (list2)->bracket_type.bracket_id \
+ && (list1)->bracket_type.is_open == (list2)->bracket_type.is_open)
+
static FriBidiRun *
merge_with_prev (
FriBidiRun *second
@@ -72,7 +83,11 @@ merge_with_prev (
first->next = second->next;
first->next->prev = first;
RL_LEN (first) += RL_LEN (second);
- free_run (second);
+ if (second->next_isolate)
+ second->next_isolate->prev_isolate = first;
+ first->next_isolate = second->next_isolate;
+
+ fribidi_free (second);
return first;
}
@@ -86,7 +101,10 @@ compact_list (
if (list->next)
for_run_list (list, list)
if (RL_TYPE (list->prev) == RL_TYPE (list)
- && RL_LEVEL (list->prev) == RL_LEVEL (list))
+ && RL_LEVEL (list->prev) == RL_LEVEL (list)
+ && RL_BRACKET_TYPE(list).bracket_id == 0 /* Don't join brackets! */
+ && RL_BRACKET_TYPE(list->prev).bracket_id == 0
+ )
list = merge_with_prev (list);
}
@@ -103,15 +121,58 @@ compact_neutrals (
{
if (RL_LEVEL (list->prev) == RL_LEVEL (list)
&&
- ((RL_TYPE
- (list->prev) == RL_TYPE (list)
+ ((RL_TYPE (list->prev) == RL_TYPE (list)
|| (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev))
- && FRIBIDI_IS_NEUTRAL (RL_TYPE (list))))))
+ && FRIBIDI_IS_NEUTRAL (RL_TYPE (list)))))
+ && RL_BRACKET_TYPE(list).bracket_id == 0 /* Don't join brackets! */
+ && RL_BRACKET_TYPE(list->prev).bracket_id == 0
+ )
list = merge_with_prev (list);
}
}
}
+/* Search for an adjacent run in the forward or backward direction.
+ It uses the next_isolate and prev_isolate run for short circuited searching.
+ */
+
+/* The static sentinel is used to signal the end of an isolating
+ sequence */
+static FriBidiRun sentinel = { NULL, NULL, 0,0, FRIBIDI_TYPE_SENTINEL, -1,-1,FRIBIDI_NO_BRACKET, NULL, NULL };
+
+static FriBidiRun *get_adjacent_run(FriBidiRun *list, fribidi_boolean forward, fribidi_boolean skip_neutral)
+{
+ FriBidiRun *ppp = forward ? list->next_isolate : list->prev_isolate;
+ if (!ppp)
+ return &sentinel;
+
+ while (ppp)
+ {
+ FriBidiCharType ppp_type = RL_TYPE (ppp);
+
+ if (ppp_type == _FRIBIDI_TYPE_SENTINEL)
+ break;
+
+ /* Note that when sweeping forward we continue one run
+ beyond the PDI to see what lies behind. When looking
+ backwards, this is not necessary as the leading isolate
+ run has already been assigned the resolved level. */
+ if (ppp->isolate_level > list->isolate_level /* <- How can this be true? */
+ || (forward && ppp_type == FRIBIDI_TYPE_PDI)
+ || (skip_neutral && !FRIBIDI_IS_STRONG(ppp_type)))
+ {
+ ppp = forward ? ppp->next_isolate : ppp->prev_isolate;
+ if (!ppp)
+ ppp = &sentinel;
+
+ continue;
+ }
+ break;
+ }
+
+ return ppp;
+}
+
#if DEBUG+0
/*======================================================================
* For debugging, define some functions for printing the types and the
@@ -131,6 +192,8 @@ static char char_from_level_array[] = {
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z',
+ /* TBD - insert another 125-64 levels */
+
'@', /* 62 == only must appear after resolving
* implicits. */
@@ -153,8 +216,8 @@ print_types_re (
MSG (" Run types : ");
for_run_list (pp, pp)
{
- MSG5 ("%d:%d(%s)[%d] ",
- pp->pos, pp->len, fribidi_get_bidi_type_name (pp->type), pp->level);
+ MSG6 ("%d:%d(%s)[%d,%d] ",
+ pp->pos, pp->len, fribidi_get_bidi_type_name (pp->type), pp->level, pp->isolate_level);
}
MSG ("\n");
}
@@ -219,20 +282,23 @@ print_bidi_string (
/* There are a few little points in pushing into and poping from the status
stack:
1. when the embedding level is not valid (more than
- FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61), you must reject it, and not to push
+ FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=125), you must reject it, and not to push
into the stack, but when you see a PDF, you must find the matching code,
and if it was pushed in the stack, pop it, it means you must pop if and
only if you have pushed the matching code, the over_pushed var counts the
number of rejected codes so far.
+
2. there's a more confusing point too, when the embedding level is exactly
- FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1=60, an LRO or LRE is rejected
- because the new level would be FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL+1=62, that
- is invalid; but an RLO or RLE is accepted because the new level is
- FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=61, that is valid, so the rejected codes
+ FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL-1=124, an LRO, LRE, or LRI is rejected
+ because the new level would be FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL+1=126, that
+ is invalid; but an RLO, RLE, or RLI is accepted because the new level is
+ FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL=125, that is valid, so the rejected codes
may be not continuous in the logical order, in fact there are at most two
- continuous intervals of codes, with an RLO or RLE between them. To support
- this case, the first_interval var counts the number of rejected codes in
- the first interval, when it is 0, means that there is only one interval.
+ continuous intervals of codes, with an RLO, RLE, or RLI between them. To
+ support this case, the first_interval var counts the number of rejected
+ codes in the first interval, when it is 0, means that there is only one
+ interval.
+
*/
/* a. If this new level would be valid, then this embedding code is valid.
@@ -244,16 +310,20 @@ print_bidi_string (
*/
#define PUSH_STATUS \
FRIBIDI_BEGIN_STMT \
- if LIKELY(new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL) \
+ if LIKELY(over_pushed == 0 \
+ && isolate_overflow == 0 \
+ && new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL) \
{ \
if UNLIKELY(level == FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL - 1) \
first_interval = over_pushed; \
status_stack[stack_size].level = level; \
+ status_stack[stack_size].isolate_level = isolate_level; \
+ status_stack[stack_size].isolate = isolate; \
status_stack[stack_size].override = override; \
stack_size++; \
level = new_level; \
override = new_override; \
- } else \
+ } else if LIKELY(isolate_overflow == 0) \
over_pushed++; \
FRIBIDI_END_STMT
@@ -273,6 +343,8 @@ print_bidi_string (
stack_size--; \
level = status_stack[stack_size].level; \
override = status_stack[stack_size].override; \
+ isolate = status_stack[stack_size].isolate; \
+ isolate_level = status_stack[stack_size].isolate_level; \
} \
} \
FRIBIDI_END_STMT
@@ -321,10 +393,121 @@ fribidi_get_par_direction (
return FRIBIDI_PAR_ON;
}
+/* Pairing nodes are used for holding a pair of open/close brackets as
+ described in BD16. */
+struct _FriBidiPairingNodeStruct {
+ FriBidiRun *open;
+ FriBidiRun *close;
+ struct _FriBidiPairingNodeStruct *next;
+};
+typedef struct _FriBidiPairingNodeStruct FriBidiPairingNode;
+
+/* Push a new entry to the pairing linked list */
+static FriBidiPairingNode * pairing_nodes_push(FriBidiPairingNode *nodes,
+ FriBidiRun *open,
+ FriBidiRun *close)
+{
+ FriBidiPairingNode *node = fribidi_malloc(sizeof(FriBidiPairingNode));
+ node->open = open;
+ node->close = close;
+ node->next = nodes;
+ nodes = node;
+ return nodes;
+}
+
+static void print_pairing_nodes(FriBidiPairingNode *nodes)
+{
+ MSG ("Pairs: ");
+ while (nodes)
+ {
+ MSG3 ("(%d, %d) ", nodes->open->pos, nodes->close->pos);
+ nodes = nodes->next;
+ }
+ MSG ("\n");
+}
+
+/* Sort by merge sort */
+static void pairing_nodes_front_back_split(FriBidiPairingNode *source,
+ /* output */
+ FriBidiPairingNode **front,
+ FriBidiPairingNode **back)
+{
+ FriBidiPairingNode *pfast, *pslow;
+ if (!source || !source->next)
+ {
+ *front = source;
+ *back = NULL;
+ }
+ else
+ {
+ pslow = source;
+ pfast = source->next;
+ while (pfast)
+ {
+ pfast= pfast->next;
+ if (pfast)
+ {
+ pfast = pfast->next;
+ pslow = pslow->next;
+ }
+ }
+ *front = source;
+ *back = pslow->next;
+ pslow->next = NULL;
+ }
+}
+
+static FriBidiPairingNode *
+pairing_nodes_sorted_merge(FriBidiPairingNode *nodes1,
+ FriBidiPairingNode *nodes2)
+{
+ FriBidiPairingNode *res = NULL;
+ if (!nodes1)
+ return nodes2;
+ if (!nodes2)
+ return nodes1;
+
+ if (nodes1->open->pos < nodes2->open->pos)
+ {
+ res = nodes1;
+ res->next = pairing_nodes_sorted_merge(nodes1->next, nodes2);
+ }
+ else
+ {
+ res = nodes2;
+ res->next = pairing_nodes_sorted_merge(nodes1, nodes2->next);
+ }
+ return res;
+}
+
+static void sort_pairing_nodes(FriBidiPairingNode **nodes)
+{
+ /* 0 or 1 node case */
+ if (!*nodes || !(*nodes)->next)
+ return;
+
+ FriBidiPairingNode *front, *back;
+ pairing_nodes_front_back_split(*nodes, &front, &back);
+ sort_pairing_nodes(&front);
+ sort_pairing_nodes(&back);
+ *nodes = pairing_nodes_sorted_merge(front, back);
+}
+
+static void free_pairing_nodes(FriBidiPairingNode *nodes)
+{
+ while (nodes)
+ {
+ FriBidiPairingNode *p = nodes;
+ nodes = nodes->next;
+ fribidi_free(p);
+ }
+}
+
FRIBIDI_ENTRY FriBidiLevel
fribidi_get_par_embedding_levels (
/* input */
const FriBidiCharType *bidi_types,
+ const FriBidiBracketType *bracket_types,
const FriBidiStrIndex len,
/* input and output */
FriBidiParType *pbase_dir,
@@ -332,7 +515,7 @@ fribidi_get_par_embedding_levels (
FriBidiLevel *embedding_levels
)
{
- FriBidiLevel base_level, max_level = 0;
+ FriBidiLevel base_level, *base_level_per_iso_level = NULL, max_level = 0;
FriBidiParType base_dir;
FriBidiRun *main_run_list = NULL, *explicits_list = NULL, *pp;
fribidi_boolean status = false;
@@ -353,7 +536,7 @@ fribidi_get_par_embedding_levels (
/* Determinate character types */
{
/* Get run-length encoded character types */
- main_run_list = run_list_encode_bidi_types (bidi_types, len);
+ main_run_list = run_list_encode_bidi_types (bidi_types, bracket_types, len);
if UNLIKELY
(!main_run_list) goto out;
}
@@ -366,17 +549,33 @@ fribidi_get_par_embedding_levels (
/* P2. P3. Search for first strong character and use its direction as
base direction */
{
- for_run_list (pp, main_run_list) if (FRIBIDI_IS_LETTER (RL_TYPE (pp)))
- {
- base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp));
- *pbase_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
- break;
- }
+ int valid_isolate_count = 0;
+ for_run_list (pp, main_run_list)
+ {
+ if (RL_TYPE(pp) == FRIBIDI_TYPE_PDI)
+ {
+ /* Ignore if there is no matching isolate */
+ if (valid_isolate_count>0)
+ valid_isolate_count--;
+ }
+ else if (FRIBIDI_IS_ISOLATE(RL_TYPE(pp)))
+ valid_isolate_count++;
+ else if (valid_isolate_count==0 && FRIBIDI_IS_LETTER (RL_TYPE (pp)))
+ {
+ base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp));
+ *pbase_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
+ break;
+ }
+ }
}
base_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
DBG2 (" base level : %c", fribidi_char_from_level (base_level));
DBG2 (" base dir : %c", fribidi_char_from_bidi_type (base_dir));
+ base_level_per_iso_level = fribidi_malloc(sizeof(base_level_per_iso_level[0]) *
+ FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL);
+ base_level_per_iso_level[0] = base_level;
+
# if DEBUG
if UNLIKELY
(fribidi_debug_status ())
@@ -388,16 +587,28 @@ fribidi_get_par_embedding_levels (
/* Explicit Levels and Directions */
DBG ("explicit levels and directions");
{
- FriBidiLevel level, new_level;
+ FriBidiLevel level, new_level = 0;
+ int isolate_level = 0;
FriBidiCharType override, new_override;
FriBidiStrIndex i;
int stack_size, over_pushed, first_interval;
+ int valid_isolate_count = 0;
+ int isolate_overflow = 0;
+ int isolate = 0; /* The isolate status flag */
struct
{
FriBidiCharType override; /* only LTR, RTL and ON are valid */
FriBidiLevel level;
+ int isolate;
+ int isolate_level;
} *status_stack;
FriBidiRun temp_link;
+ FriBidiRun **run_per_isolate_level; /* Connect the isolate levels */
+
+ run_per_isolate_level = fribidi_malloc(sizeof(run_per_isolate_level[0])
+ * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
+ memset(run_per_isolate_level, 0, sizeof(run_per_isolate_level[0])
+ * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
/* explicits_list is a list like main_run_list, that holds the explicit
codes that are removed from main_run_list, to reinsert them later by
@@ -408,9 +619,11 @@ fribidi_get_par_embedding_levels (
(!explicits_list) goto out;
/* X1. Begin by setting the current embedding level to the paragraph
- embedding level. Set the directional override status to neutral.
- Process each character iteratively, applying rules X2 through X9.
- Only embedding levels from 0 to 61 are valid in this phase. */
+ embedding level. Set the directional override status to neutral,
+ and directional isolate status to false.
+
+ Process each character iteratively, applying rules X2 through X8.
+ Only embedding levels from 0 to 123 are valid in this phase. */
level = base_level;
override = FRIBIDI_TYPE_ON;
@@ -418,12 +631,16 @@ fribidi_get_par_embedding_levels (
stack_size = 0;
over_pushed = 0;
first_interval = 0;
+ valid_isolate_count = 0;
+ isolate_overflow = 0;
status_stack = fribidi_malloc (sizeof (status_stack[0]) *
FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
for_run_list (pp, main_run_list)
{
FriBidiCharType this_type = RL_TYPE (pp);
+ RL_ISOLATE_LEVEL (pp) = isolate_level;
+
if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type))
{
if (FRIBIDI_IS_STRONG (this_type))
@@ -444,6 +661,7 @@ fribidi_get_par_embedding_levels (
new_level =
((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) -
FRIBIDI_DIR_TO_LEVEL (this_type);
+ isolate = 0;
PUSH_STATUS;
}
}
@@ -452,8 +670,12 @@ fribidi_get_par_embedding_levels (
/* 3. Terminating Embeddings and overrides */
/* X7. With each PDF, determine the matching embedding or
override code. */
- for (i = RL_LEN (pp); i; i--)
- POP_STATUS;
+ for (i = RL_LEN (pp); i; i--)
+ {
+ if (stack_size && status_stack[stack_size-1].isolate != 0)
+ break;
+ POP_STATUS;
+ }
}
/* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */
@@ -463,6 +685,96 @@ fribidi_get_par_embedding_levels (
move_node_before (pp, explicits_list);
pp = &temp_link;
}
+ else if (this_type == FRIBIDI_TYPE_PDI)
+ /* X6a. pop the direction of the stack */
+ {
+ for (i = RL_LEN (pp); i; i--)
+ {
+ if (isolate_overflow > 0)
+ {
+ isolate_overflow--;
+ RL_LEVEL (pp) = level;
+ }
+
+ else if (valid_isolate_count > 0)
+ {
+ /* Pop away all LRE,RLE,LRO, RLO levels
+ from the stack, as these are implicitly
+ terminated by the PDI */
+ while (stack_size && !status_stack[stack_size-1].isolate)
+ POP_STATUS;
+ over_pushed = 0; /* The PDI resets the overpushed! */
+ POP_STATUS;
+ isolate_level-- ;
+ valid_isolate_count--;
+ RL_LEVEL (pp) = level;
+ RL_ISOLATE_LEVEL (pp) = isolate_level;
+ }
+ else
+ {
+ /* Ignore isolated PDI's by turning them into ON's */
+ RL_TYPE (pp) = FRIBIDI_TYPE_ON;
+ RL_LEVEL (pp) = level;
+ }
+ }
+ }
+ else if (FRIBIDI_IS_ISOLATE(this_type))
+ {
+ /* TBD support RL_LEN > 1 */
+ new_override = FRIBIDI_TYPE_ON;
+ isolate = 1;
+ if (this_type == FRIBIDI_TYPE_LRI)
+ new_level = level + 2 - (level%2);
+ else if (this_type == FRIBIDI_TYPE_RLI)
+ new_level = level + 1 + (level%2);
+ else if (this_type == FRIBIDI_TYPE_FSI)
+ {
+ /* Search for a local strong character until we
+ meet the corresponding PDI or the end of the
+ paragraph */
+ FriBidiRun *fsi_pp;
+ int isolate_count = 0;
+ int fsi_base_level = 0;
+ for_run_list (fsi_pp, pp)
+ {
+ if (RL_TYPE(fsi_pp) == FRIBIDI_TYPE_PDI)
+ {
+ isolate_count--;
+ if (valid_isolate_count < 0)
+ break;
+ }
+ else if (FRIBIDI_IS_ISOLATE(RL_TYPE(fsi_pp)))
+ isolate_count++;
+ else if (isolate_count==0 && FRIBIDI_IS_LETTER (RL_TYPE (fsi_pp)))
+ {
+ fsi_base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (fsi_pp));
+ break;
+ }
+ }
+
+ /* Same behavior like RLI and LRI above */
+ if (FRIBIDI_LEVEL_IS_RTL (fsi_base_level))
+ new_level = level + 1 + (level%2);
+ else
+ new_level = level + 2 - (level%2);
+ }
+
+ RL_LEVEL (pp) = level;
+ RL_ISOLATE_LEVEL (pp) = isolate_level++;
+ base_level_per_iso_level[isolate_level] = new_level;
+
+ if (!FRIBIDI_IS_NEUTRAL (override))
+ RL_TYPE (pp) = override;
+
+ if (new_level <= FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL)
+ {
+ valid_isolate_count++;
+ PUSH_STATUS;
+ level = new_level;
+ }
+ else
+ isolate_overflow += 1;
+ }
else if (this_type == FRIBIDI_TYPE_BS)
{
/* X8. All explicit directional embeddings and overrides are
@@ -484,6 +796,18 @@ fribidi_get_par_embedding_levels (
}
}
+ /* Build the isolate_level connections */
+ for_run_list (pp, main_run_list)
+ {
+ int isolate_level = RL_ISOLATE_LEVEL (pp);
+ if (run_per_isolate_level[isolate_level])
+ {
+ run_per_isolate_level[isolate_level]->next_isolate = pp;
+ pp->prev_isolate = run_per_isolate_level[isolate_level];
+ }
+ run_per_isolate_level[isolate_level] = pp;
+ }
+
/* Implementing X8. It has no effect on a single paragraph! */
level = base_level;
override = FRIBIDI_TYPE_ON;
@@ -491,6 +815,7 @@ fribidi_get_par_embedding_levels (
over_pushed = 0;
fribidi_free (status_stack);
+ fribidi_free (run_per_isolate_level);
}
/* X10. The remaining rules are applied to each run of characters at the
same level. For each run, determine the start-of-level-run (sor) and
@@ -515,24 +840,45 @@ fribidi_get_par_embedding_levels (
}
# endif /* DEBUG */
- /* 4. Resolving weak types */
+ /* 4. Resolving weak types. Also calculate the maximum isolate level */
+ int max_iso_level = 0;
DBG ("resolving weak types");
{
- FriBidiCharType last_strong, prev_type_orig;
+ int *last_strong_stack;
+ FriBidiCharType prev_type_orig;
fribidi_boolean w4;
- last_strong = base_dir;
+ last_strong_stack = fribidi_malloc (sizeof (int)
+ * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
+ last_strong_stack[0] = base_dir;
for_run_list (pp, main_run_list)
{
register FriBidiCharType prev_type, this_type, next_type;
+ FriBidiRun *ppp_prev, *ppp_next;
+ int iso_level;
+
+ ppp_prev = get_adjacent_run(pp, FALSE, FALSE);
+ ppp_next = get_adjacent_run(pp, TRUE, FALSE);
- prev_type = PREV_TYPE_OR_SOR (pp);
this_type = RL_TYPE (pp);
- next_type = NEXT_TYPE_OR_EOR (pp);
+ iso_level = RL_ISOLATE_LEVEL(pp);
+
+ if (iso_level > max_iso_level)
+ max_iso_level = iso_level;
+
+ if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
+ prev_type = RL_TYPE(ppp_prev);
+ else
+ prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
+
+ if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
+ next_type = RL_TYPE(ppp_next);
+ else
+ next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
if (FRIBIDI_IS_STRONG (prev_type))
- last_strong = prev_type;
+ last_strong_stack[iso_level] = prev_type;
/* W1. NSM
Examine each non-spacing mark (NSM) in the level run, and change the
@@ -544,31 +890,41 @@ fribidi_get_par_embedding_levels (
adjacent ETs are in one FriBidiRun. */
if (this_type == FRIBIDI_TYPE_NSM)
{
- if (RL_LEVEL (pp->prev) == RL_LEVEL (pp))
- pp = merge_with_prev (pp);
+ /* New rule in Unicode 6.3 */
+ if (FRIBIDI_IS_ISOLATE (RL_TYPE (pp->prev)))
+ RL_TYPE(pp) = FRIBIDI_TYPE_ON;
+
+ if (RL_LEVEL (ppp_prev) == RL_LEVEL (pp))
+ {
+ if (ppp_prev == pp->prev)
+ pp = merge_with_prev (pp);
+ }
else
- RL_TYPE (pp) = prev_type;
+ RL_TYPE (pp) = prev_type;
+
if (prev_type == next_type && RL_LEVEL (pp) == RL_LEVEL (pp->next))
{
- pp = merge_with_prev (pp->next);
+ if (ppp_next == pp->next)
+ pp = merge_with_prev (pp->next);
}
continue; /* As we know the next condition cannot be true. */
}
/* W2: European numbers. */
- if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_AL)
+ if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_AL)
{
RL_TYPE (pp) = FRIBIDI_TYPE_AN;
/* Resolving dependency of loops for rules W1 and W2, so we
can merge them in one loop. */
if (next_type == FRIBIDI_TYPE_NSM)
- RL_TYPE (pp->next) = FRIBIDI_TYPE_AN;
+ RL_TYPE (ppp_next) = FRIBIDI_TYPE_AN;
}
}
- last_strong = base_dir;
+ last_strong_stack[0] = base_dir;
+
/* Resolving dependency of loops for rules W4 and W5, W5 may
want to prevent W4 to take effect in the next turn, do this
through "w4". */
@@ -578,17 +934,34 @@ fribidi_get_par_embedding_levels (
so W4 and W5 in next turn can still do their works. */
prev_type_orig = FRIBIDI_TYPE_ON;
+ /* Each isolate level has its own memory of the last strong character */
for_run_list (pp, main_run_list)
{
register FriBidiCharType prev_type, this_type, next_type;
+ int iso_level;
+ FriBidiRun *ppp_prev, *ppp_next;
- prev_type = PREV_TYPE_OR_SOR (pp);
this_type = RL_TYPE (pp);
- next_type = NEXT_TYPE_OR_EOR (pp);
+ iso_level = RL_ISOLATE_LEVEL(pp);
+
+ ppp_prev = get_adjacent_run(pp, FALSE, FALSE);
+ ppp_next = get_adjacent_run(pp, TRUE, FALSE);
+
+ if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
+ prev_type = RL_TYPE(ppp_prev);
+ else
+ prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
+
+ if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
+ next_type = RL_TYPE(ppp_next);
+ else
+ next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
if (FRIBIDI_IS_STRONG (prev_type))
- last_strong = prev_type;
+ last_strong_stack[iso_level] = prev_type;
+ /* W2 ??? */
+
/* W3: Change ALs to R. */
if (this_type == FRIBIDI_TYPE_AL)
{
@@ -629,7 +1002,7 @@ fribidi_get_par_embedding_levels (
RL_TYPE (pp) = FRIBIDI_TYPE_ON;
/* W7. Change european numbers to L. */
- if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_LTR)
+ if (this_type == FRIBIDI_TYPE_EN && last_strong_stack[iso_level] == FRIBIDI_TYPE_LTR)
{
RL_TYPE (pp) = FRIBIDI_TYPE_LTR;
prev_type_orig = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ?
@@ -638,6 +1011,8 @@ fribidi_get_par_embedding_levels (
else
prev_type_orig = PREV_TYPE_OR_SOR (pp->next);
}
+
+ fribidi_free (last_strong_stack);
}
compact_neutrals (main_run_list);
@@ -652,19 +1027,200 @@ fribidi_get_par_embedding_levels (
# endif /* DEBUG */
/* 5. Resolving Neutral Types */
- DBG ("resolving neutral types");
+
+ DBG ("resolving neutral types - N0");
+ {
+ /* BD16 - Build list of all pairs*/
+ int num_iso_levels = max_iso_level + 1;
+ FriBidiPairingNode *pairing_nodes = NULL;
+ FriBidiRun ***bracket_stack = fribidi_malloc(sizeof(bracket_stack[0])
+ * num_iso_levels);
+
+ memset(bracket_stack, 0, sizeof(bracket_stack[0])*num_iso_levels);
+
+ int *bracket_stack_size = fribidi_malloc(sizeof(bracket_stack_size[0])
+ * num_iso_levels);
+ memset(bracket_stack_size, 0, sizeof(bracket_stack_size[0])*num_iso_levels);
+
+ /* Build the bd16 pair stack. */
+ int last_level = RL_LEVEL(main_run_list);
+ int last_iso_level = 0;
+ for_run_list (pp, main_run_list)
+ {
+ int level = RL_LEVEL(pp);
+ int iso_level = RL_ISOLATE_LEVEL(pp);
+
+ /* Interpret the isolating run sequence as such that they
+ end at a change in the level, unless the iso_level has been
+ raised. */
+ if (level != last_level && last_iso_level == iso_level)
+ bracket_stack_size[last_iso_level] = 0;
+
+ if (!bracket_stack[iso_level])
+ bracket_stack[iso_level] = fribidi_malloc (sizeof (bracket_stack[0])
+ * FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS);
+ FriBidiBracketType brack_prop = RL_BRACKET_TYPE(pp);
+ if (FRIBIDI_IS_BRACKET(&brack_prop))
+ {
+ if (brack_prop.is_open)
+ {
+ if (bracket_stack_size[iso_level]==FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS)
+ break;
+
+ /* push onto the pair stack */
+ bracket_stack[iso_level][bracket_stack_size[iso_level]++] = pp;
+ }
+ else
+ {
+ int stack_idx = bracket_stack_size[iso_level] - 1;
+ while (stack_idx >= 0)
+ {
+ FriBidiBracketType se_brack_prop = RL_BRACKET_TYPE(bracket_stack[iso_level][stack_idx]);
+ if (se_brack_prop.bracket_id == brack_prop.bracket_id)
+ {
+ bracket_stack_size[iso_level] = stack_idx;
+
+ pairing_nodes = pairing_nodes_push(pairing_nodes,
+ bracket_stack[iso_level][stack_idx],
+ pp);
+ break;
+ }
+ stack_idx--;
+ }
+ }
+ }
+ last_level = level;
+ last_iso_level = iso_level;
+ }
+
+ /* The list must now be sorted for the next algo to work! */
+ sort_pairing_nodes(&pairing_nodes);
+
+# if DEBUG
+ if UNLIKELY
+ (fribidi_debug_status ())
+ {
+ print_pairing_nodes(pairing_nodes);
+ }
+# endif /* DEBUG */
+
+ /* Start the N0 */
+ {
+ FriBidiPairingNode *ppairs = pairing_nodes;
+ while (ppairs)
+ {
+ int iso_level = ppairs->open->isolate_level;
+ int embedding_level = base_level_per_iso_level[iso_level];
+
+ /* Find matching strong. */
+ fribidi_boolean found = false;
+ FriBidiRun *ppn;
+ for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
+ {
+ FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
+
+ /* Calculate level like in resolve implicit levels below to prevent
+ embedded levels not to match the base_level */
+ int this_level = RL_LEVEL (ppn) +
+ (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
+
+ /* N0b */
+ if (FRIBIDI_IS_STRONG (this_type) && this_level == embedding_level)
+ {
+ RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = this_level%2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
+ found = true;
+ break;
+ }
+ }
+
+ /* N0c */
+ /* Search for any strong type preceding and within the bracket pair */
+ if (!found)
+ {
+ /* Search for a preceding strong */
+ int prec_strong_level = embedding_level; /* TBDov! Extract from Isolate level in effect */
+ int iso_level = RL_ISOLATE_LEVEL(ppairs->open);
+ for (ppn = ppairs->open->prev; ppn->type != FRIBIDI_TYPE_SENTINEL; ppn=ppn->prev)
+ {
+ FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
+ if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
+ {
+ prec_strong_level = RL_LEVEL (ppn) +
+ (FRIBIDI_LEVEL_IS_RTL (RL_LEVEL(ppn)) ^ FRIBIDI_DIR_TO_LEVEL (this_type));
+
+ break;
+ }
+ }
+
+ for (ppn = ppairs->open; ppn!= ppairs->close; ppn = ppn->next)
+ {
+ FriBidiCharType this_type = RL_TYPE_AN_EN_AS_RTL(ppn);
+ if (FRIBIDI_IS_STRONG (this_type) && RL_ISOLATE_LEVEL(ppn) == iso_level)
+ {
+ /* By constraint this is opposite the embedding direction,
+ since we did not match the N0b rule. We must now
+ compare with the preceding strong to establish whether
+ to apply N0c1 (opposite) or N0c2 embedding */
+ RL_TYPE(ppairs->open) = RL_TYPE(ppairs->close) = prec_strong_level % 2 ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR;
+ RL_LEVEL(ppairs->open) = RL_LEVEL(ppairs->close) = prec_strong_level;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ ppairs = ppairs->next;
+ }
+
+ free_pairing_nodes(pairing_nodes);
+ {
+ int i;
+ for (i=0; i<num_iso_levels; i++)
+ fribidi_free(bracket_stack[i]);
+ }
+ fribidi_free(bracket_stack);
+ fribidi_free(bracket_stack_size);
+
+ /* Remove the bracket property and re-compact */
+ const FriBidiBracketType NoBracket = FRIBIDI_NO_BRACKET;
+ for_run_list (pp, main_run_list)
+ pp->bracket_type = NoBracket;
+ compact_list (main_run_list);
+ }
+
+# if DEBUG
+ if UNLIKELY
+ (fribidi_debug_status ())
+ {
+ print_resolved_levels (main_run_list);
+ print_resolved_types (main_run_list);
+ }
+# endif /* DEBUG */
+ }
+
+ DBG ("resolving neutral types - N1+N2");
{
- /* N1. and N2.
- For each neutral, resolve it. */
for_run_list (pp, main_run_list)
{
FriBidiCharType prev_type, this_type, next_type;
+ FriBidiRun *ppp_prev, *ppp_next;
+
+ ppp_prev = get_adjacent_run(pp, FALSE, FALSE);
+ ppp_next = get_adjacent_run(pp, TRUE, FALSE);
/* "European and Arabic numbers are treated as though they were R"
FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */
this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp));
- prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (PREV_TYPE_OR_SOR (pp));
- next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (NEXT_TYPE_OR_EOR (pp));
+
+ if (RL_LEVEL(ppp_prev) == RL_LEVEL(pp))
+ prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_prev));
+ else
+ prev_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_prev), RL_LEVEL(pp)));
+
+ if (RL_LEVEL(ppp_next) == RL_LEVEL(pp))
+ next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE(ppp_next));
+ else
+ next_type = FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(ppp_next), RL_LEVEL(pp)));
if (FRIBIDI_IS_NEUTRAL (this_type))
RL_TYPE (pp) = (prev_type == next_type) ?
@@ -765,7 +1321,9 @@ fribidi_get_par_embedding_levels (
1. segment separators,
2. paragraph separators,
3. any sequence of whitespace characters preceding a segment
- separator or paragraph separator, and
+ separator or paragraph separator, and
+ 4. any sequence of whitespace characters and/or isolate formatting
+ characters at the end of the line.
... (to be continued in fribidi_reorder_line()). */
list = new_run_list ();
if UNLIKELY
@@ -785,8 +1343,9 @@ fribidi_get_par_embedding_levels (
state = 1;
pos = j;
}
- else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS
- (char_type))
+ else if (state &&
+ !(FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS(char_type)
+ || FRIBIDI_IS_ISOLATE(char_type)))
{
state = 0;
p = new_run ();
@@ -838,6 +1397,8 @@ out:
free_run_list (main_run_list);
if UNLIKELY
(explicits_list) free_run_list (explicits_list);
+ if (base_level_per_iso_level)
+ fribidi_free (base_level_per_iso_level);
return status ? max_level + 1 : 0;
}
diff --git a/lib/fribidi-bidi.h b/lib/fribidi-bidi.h
index dd2de67..1a4bbc5 100644
--- a/lib/fribidi-bidi.h
+++ b/lib/fribidi-bidi.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_BIDI_H
#define _FRIBIDI_BIDI_H
@@ -88,6 +88,8 @@ FRIBIDI_ENTRY FriBidiLevel
fribidi_get_par_embedding_levels (
const FriBidiCharType *bidi_types, /* input list of bidi types as returned by
fribidi_get_bidi_types() */
+ const FriBidiBracketType *bracket_types, /* input list of bracket types as returned by
+ fribidi_get_bracket_types() */
const FriBidiStrIndex len, /* input string length of the paragraph */
FriBidiParType *pbase_dir, /* requested and resolved paragraph
* base direction */
diff --git a/lib/fribidi-brackets.c b/lib/fribidi-brackets.c
new file mode 100644
index 0000000..651c9ca
--- /dev/null
+++ b/lib/fribidi-brackets.c
@@ -0,0 +1,106 @@
+/* fribidi-brackets.c - get bracketed character
+ *
+ * Copyright (C) 2004 Sharif FarsiWeb, Inc
+ * Copyright (C) 2001, 2002, 2004 Behdad Esfahbod
+ * Copyright (C) 1999, 2000, 2017 Dov Grobgeld
+ *
+ * This file is part of GNU FriBidi.
+ *
+ * GNU FriBidi is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GNU FriBidi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with GNU FriBidi; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
+ * Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
+ */
+/*
+ * Author(s):
+ * Behdad Esfahbod, 2001, 2002, 2004
+ * Dov Grobgeld, 1999, 2000, 2017
+ */
+
+#include "common.h"
+
+#include <fribidi-brackets.h>
+
+#include "brackets.tab.i"
+#include "brackets-type.tab.i"
+#include <stdio.h>
+
+#define FRIBIDI_TYPE_BRACKET_OPEN 2
+
+FRIBIDI_ENTRY FriBidiBracketType
+fribidi_get_bracket (
+ /* input */
+ FriBidiChar ch
+)
+{
+ FriBidiBracketType bracket_type;
+ register fribidi_uint8 char_type;
+
+ /* The bracket type from the table may be:
+ 0 - Not a bracket
+ 1 - a bracket
+ 2 - closing.
+
+ This will be recodeded into the FriBidiBracketType as having a
+ bracket_id = 0 if the character is not a bracket.
+ */
+ char_type = FRIBIDI_GET_BRACKET_TYPE (ch);
+ fribidi_boolean is_open = 0;
+
+ if (char_type == 0)
+ bracket_type.bracket_id = 0;
+ else
+ {
+ is_open = (char_type & FRIBIDI_TYPE_BRACKET_OPEN) != 0;
+ bracket_type.bracket_id = FRIBIDI_GET_BRACKETS (ch);
+ }
+ bracket_type.is_open = is_open;
+
+ return bracket_type;
+}
+
+FRIBIDI_ENTRY void
+fribidi_get_bracket_types (
+ /* input */
+ const FriBidiChar *str,
+ const FriBidiStrIndex len,
+ const FriBidiType *types,
+ /* output */
+ FriBidiBracketType *btypes
+)
+{
+ register FriBidiStrIndex i = len;
+ for (; i; i--)
+ {
+ /* Optimization that bracket must be of types ON */
+ if (types[i] == FRIBIDI_TYPE_ON)
+ *btypes = NoBracket;
+ else
+ *btypes = fribidi_get_bracket (*str);
+
+ btypes++;
+ str++;
+ }
+}
+
+/* Editor directions:
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * indent-tabs-mode: t
+ * tab-width: 8
+ * End:
+ * vim: textwidth=78: autoindent: cindent: shiftwidth=2: tabstop=8:
+ */
diff --git a/lib/fribidi-brackets.h b/lib/fribidi-brackets.h
new file mode 100644
index 0000000..e66a3f8
--- /dev/null
+++ b/lib/fribidi-brackets.h
@@ -0,0 +1,90 @@
+/* fribidi-brackets.h - get bracket character property
+ *
+ * Copyright (C) 2004 Sharif FarsiWeb, Inc
+ * Copyright (C) 2001, 2002, 2004 Behdad Esfahbod
+ * Copyright (C) 1999, 2000, 2017 Dov Grobgeld
+ *
+ * This file is part of GNU FriBidi.
+ *
+ * GNU FriBidi is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GNU FriBidi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with GNU FriBidi; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
+ * Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
+ */
+/* $Id: fribidi-brackets.h,v 1.10 2004-09-28 07:58:57 behdad Exp $
+ * $Author: behdad $
+ * $Date: 2004-09-28 07:58:57 $
+ * $Revision: 1.10 $
+ * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-brackets.h,v $
+ *
+ * Author(s):
+ * Behdad Esfahbod, 2001, 2002, 2004
+ * Dov Grobgeld, 1999, 2000, 2017
+ */
+#ifndef _FRIBIDI_BRACKETS_H
+#define _FRIBIDI_BRACKETS_H
+
+#include "fribidi-common.h"
+
+#include "fribidi-types.h"
+#include "fribidi-bidi-types.h"
+
+#include "fribidi-begindecls.h"
+
+#define fribidi_get_bracket_char FRIBIDI_NAMESPACE(get_bracket_char)
+/* fribidi_get_bracket_char - get bracketed character
+ *
+ * This function finds the bracketed equivalent of a character as defined in
+ * the file BidiBrackets.txt of the Unicode Character Database available at
+ * http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt.
+ *
+ * If the input character is a declared as a brackets character in the
+ * Unicode standard and has a bracketed equivalent. The matching bracketed
+ * character is put in the output, otherwise the input character itself is
+ * put.
+ *
+ * Returns: The bracket type of the character. Use the
+ * FRIBIDI_IS_BRACKET(FriBidiBracketType) to test if it is a valid
+ * property.
+ */
+FRIBIDI_ENTRY FriBidiBracketType fribidi_get_bracket (
+ FriBidiChar ch /* input character */
+);
+
+FRIBIDI_ENTRY void
+fribidi_get_bracket_types (
+ /* input */
+ const FriBidiChar *str,
+ const FriBidiStrIndex len,
+ const FriBidiType *types,
+ /* output */
+ FriBidiBracketType *btypes
+);
+
+#define FRIBIDI_IS_BRACKET(bt) ((bt)->bracket_id>0)
+#define FRIBIDI_IS_BRACKET_OPEN(bt) ((bt)->is_open>0)
+
+#include "fribidi-enddecls.h"
+
+#endif /* !_FRIBIDI_BRACKETS_H */
+/* Editor directions:
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * indent-tabs-mode: t
+ * tab-width: 8
+ * End:
+ * vim: textwidth=78: autoindent: cindent: shiftwidth=2: tabstop=8:
+ */
diff --git a/lib/fribidi-common.h b/lib/fribidi-common.h
index 6dede39..882e5de 100644
--- a/lib/fribidi-common.h
+++ b/lib/fribidi-common.h
@@ -27,7 +27,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_COMMON_H
#define _FRIBIDI_COMMON_H
diff --git a/lib/fribidi-deprecated.c b/lib/fribidi-deprecated.c
index 6c300a2..b5ce074 100644
--- a/lib/fribidi-deprecated.c
+++ b/lib/fribidi-deprecated.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
@@ -86,13 +86,15 @@ FRIBIDI_ENTRY FriBidiLevel
fribidi_log2vis_get_embedding_levels (
const FriBidiCharType *bidi_types, /* input list of bidi types as returned by
fribidi_get_bidi_types() */
+ const FriBidiBracketType *bracket_types, /* input list of bidi types as returned by
+ fribidi_get_bracket_types() */
const FriBidiStrIndex len, /* input string length of the paragraph */
FriBidiParType *pbase_dir, /* requested and resolved paragraph
* base direction */
FriBidiLevel *embedding_levels /* output list of embedding levels */
)
{
- return fribidi_get_par_embedding_levels (bidi_types, len, pbase_dir, embedding_levels);
+ return fribidi_get_par_embedding_levels (bidi_types, bracket_types, len, pbase_dir, embedding_levels);
}
FRIBIDI_ENTRY FriBidiCharType
@@ -153,6 +155,7 @@ fribidi_remove_bidi_marks (
for (i = 0; i < len; i++)
if (!FRIBIDI_IS_EXPLICIT_OR_BN (fribidi_get_bidi_type (str[i]))
+ && !FRIBIDI_IS_ISOLATE (fribidi_get_bidi_type (str[i]))
&& str[i] != FRIBIDI_CHAR_LRM && str[i] != FRIBIDI_CHAR_RLM)
{
str[j] = str[i];
@@ -205,6 +208,7 @@ fribidi_log2vis (
fribidi_boolean status = false;
FriBidiArabicProp *ar_props = NULL;
FriBidiCharType *bidi_types = NULL;
+ FriBidiBracketType *bracket_types = NULL;
if UNLIKELY
(len == 0)
@@ -222,7 +226,12 @@ fribidi_log2vis (
if (!bidi_types)
goto out;
+ bracket_types = fribidi_malloc (len * sizeof bracket_types[0]);
+ if (!bracket_types)
+ goto out;
+
fribidi_get_bidi_types (str, len, bidi_types);
+ fribidi_get_bracket_types (str, len, bidi_types, bracket_types);
if (!embedding_levels)
{
@@ -232,7 +241,7 @@ fribidi_log2vis (
private_embedding_levels = true;
}
- max_level = fribidi_get_par_embedding_levels (bidi_types, len, pbase_dir,
+ max_level = fribidi_get_par_embedding_levels (bidi_types, bracket_types, len, pbase_dir,
embedding_levels) - 1;
if UNLIKELY
(max_level < 0) goto out;
diff --git a/lib/fribidi-deprecated.h b/lib/fribidi-deprecated.h
index e7dfa36..171e279 100644
--- a/lib/fribidi-deprecated.h
+++ b/lib/fribidi-deprecated.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_DEPRECATED_H
#define _FRIBIDI_DEPRECATED_H
@@ -114,6 +114,8 @@ FRIBIDI_ENTRY FriBidiLevel
fribidi_log2vis_get_embedding_levels (
const FriBidiCharType *bidi_types, /* input list of bidi types as returned by
fribidi_get_bidi_types() */
+ const FriBidiBracketType *bracket_types, /* input list of bidi types as returned by
+ fribidi_get_bracket_types() */
const FriBidiStrIndex len, /* input string length of the paragraph */
FriBidiParType *pbase_dir, /* requested and resolved paragraph
* base direction */
diff --git a/lib/fribidi-flags.h b/lib/fribidi-flags.h
index b264caf..f69b8de 100644
--- a/lib/fribidi-flags.h
+++ b/lib/fribidi-flags.h
@@ -27,7 +27,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_FLAGS_H
#define _FRIBIDI_FLAGS_H
diff --git a/lib/fribidi-joining-types-list.h b/lib/fribidi-joining-types-list.h
index a69020d..3b07eba 100644
--- a/lib/fribidi-joining-types-list.h
+++ b/lib/fribidi-joining-types-list.h
@@ -29,7 +29,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
/* *INDENT-OFF* */
#endif /* !__FRIBIDI_DOC */
diff --git a/lib/fribidi-joining-types.c b/lib/fribidi-joining-types.c
index df53221..6917033 100644
--- a/lib/fribidi-joining-types.c
+++ b/lib/fribidi-joining-types.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
diff --git a/lib/fribidi-joining-types.h b/lib/fribidi-joining-types.h
index bba3f8c..6597d8a 100644
--- a/lib/fribidi-joining-types.h
+++ b/lib/fribidi-joining-types.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_JOINING_TYPES_H
#define _FRIBIDI_JOINING_TYPES_H
diff --git a/lib/fribidi-joining.c b/lib/fribidi-joining.c
index 29d0b67..b05abaa 100644
--- a/lib/fribidi-joining.c
+++ b/lib/fribidi-joining.c
@@ -28,14 +28,13 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
#include <fribidi-joining.h>
-#include "mem.h"
#include "bidi-types.h"
#include "joining-types.h"
diff --git a/lib/fribidi-joining.h b/lib/fribidi-joining.h
index d379816..e98dadf 100644
--- a/lib/fribidi-joining.h
+++ b/lib/fribidi-joining.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_JOINING_H
#define _FRIBIDI_JOINING_H
diff --git a/lib/fribidi-mem.c b/lib/fribidi-mem.c
index e1472cf..5b1e958 100644
--- a/lib/fribidi-mem.c
+++ b/lib/fribidi-mem.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
diff --git a/lib/fribidi-mirroring.c b/lib/fribidi-mirroring.c
index 06acae2..0f9d973 100644
--- a/lib/fribidi-mirroring.c
+++ b/lib/fribidi-mirroring.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2004 Sharif FarsiWeb, Inc
* Copyright (C) 2001, 2002, 2004 Behdad Esfahbod
- * Copyright (C) 1999, 2000 Dov Grobgeld
+ * Copyright (C) 1999, 2000, 2017 Dov Grobgeld
*
* This file is part of GNU FriBidi.
*
@@ -20,7 +20,7 @@
* along with GNU FriBidi; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * For licensing issues, contact <license@farsiweb.info> or write to
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
* Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
*/
/* $Id: fribidi-mirroring.c,v 1.15 2005-11-03 01:39:01 behdad Exp $
diff --git a/lib/fribidi-mirroring.h b/lib/fribidi-mirroring.h
index 8b5bb48..15bdd2e 100644
--- a/lib/fribidi-mirroring.h
+++ b/lib/fribidi-mirroring.h
@@ -2,7 +2,7 @@
*
* Copyright (C) 2004 Sharif FarsiWeb, Inc
* Copyright (C) 2001, 2002, 2004 Behdad Esfahbod
- * Copyright (C) 1999, 2000 Dov Grobgeld
+ * Copyright (C) 1999, 2000, 2017 Dov Grobgeld
*
* This file is part of GNU FriBidi.
*
@@ -20,7 +20,7 @@
* along with GNU FriBidi; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * For licensing issues, contact <license@farsiweb.info> or write to
+ * For licensing issues, contact <fribidi.license@gmail.com> or write to
* Sharif FarsiWeb, Inc., PO Box 13445-389, Tehran, Iran.
*/
/* $Id: fribidi-mirroring.h,v 1.10 2004-09-28 07:58:57 behdad Exp $
diff --git a/lib/fribidi-run.c b/lib/fribidi-run.c
index 9219ff9..f67d9e2 100644
--- a/lib/fribidi-run.c
+++ b/lib/fribidi-run.c
@@ -9,11 +9,11 @@
*
* Authors:
* Behdad Esfahbod, 2001, 2002, 2004
- * Dov Grobgeld, 1999, 2000
+ * Dov Grobgeld, 1999, 2000, 2017
*
* Copyright (C) 2004 Sharif FarsiWeb, Inc
* Copyright (C) 2001,2002 Behdad Esfahbod
- * Copyright (C) 1999,2000 Dov Grobgeld
+ * Copyright (C) 1999,2000,2017 Dov Grobgeld
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
@@ -38,14 +38,8 @@
#include <fribidi-bidi-types.h>
#include "run.h"
-#include "mem.h"
#include "bidi-types.h"
-#if USE_SIMPLE_MALLOC+0
-#else
-static FriBidiRun *free_runs = NULL;
-#endif
-
FriBidiRun *
new_run (
void
@@ -53,54 +47,17 @@ new_run (
{
register FriBidiRun *run;
-#if USE_SIMPLE_MALLOC+0
run = fribidi_malloc (sizeof (FriBidiRun));
-#else /* !USE_SIMPLE_MALLOC */
- if (free_runs)
- {
- run = free_runs;
- free_runs = run->next;
- }
- else
- {
- static FriBidiMemChunk *run_mem_chunk = NULL;
-
- if UNLIKELY
- (!run_mem_chunk)
- run_mem_chunk = fribidi_chunk_new_for_type (FriBidiRun);
-
- if LIKELY
- (run_mem_chunk)
- run = fribidi_chunk_new (FriBidiRun, run_mem_chunk);
- else
- run = NULL;
- }
-#endif /* !USE_SIMPLE_MALLOC */
if LIKELY
(run)
{
- run->len = run->pos = run->level = 0;
- run->next = run->prev = NULL;
+ run->len = run->pos = run->level = run->isolate_level = 0;
+ run->next = run->prev = run->prev_isolate = run->next_isolate = NULL;
}
return run;
}
-void
-free_run (
- /* input */
- FriBidiRun *run
-)
-{
- fribidi_assert (run);
-#if USE_SIMPLE_MALLOC+0
- fribidi_free (run);
-#else /* !USE_SIMPLE_MALLOC */
- run->next = free_runs;
- free_runs = run;
-#endif /* !USE_SIMPLE_MALLOC */
-}
-
FriBidiRun *
new_run_list (
void
@@ -133,7 +90,6 @@ free_run_list (
fribidi_validate_run_list (run_list);
-#if USE_SIMPLE_MALLOC+0
{
register FriBidiRun *pp;
@@ -146,13 +102,9 @@ free_run_list (
p = pp;
pp = pp->next;
- free_run (p);
+ fribidi_free (p);
};
}
-#else /* !USE_SIMPLE_MALLOC */
- run_list->prev->next = free_runs;
- free_runs = run_list;
-#endif /* !USE_SIMPLE_MALLOC */
}
@@ -160,6 +112,7 @@ FriBidiRun *
run_list_encode_bidi_types (
/* input */
const FriBidiCharType *bidi_types,
+ const FriBidiBracketType *bracket_types,
const FriBidiStrIndex len
)
{
@@ -179,7 +132,15 @@ run_list_encode_bidi_types (
for (i = 0; i < len; i++)
{
register FriBidiCharType char_type = bidi_types[i];
- if (char_type != last->type)
+ register FriBidiBracketType bracket_type = FRIBIDI_NO_BRACKET;
+ if (bracket_types)
+ bracket_type = bracket_types[i];
+
+ if (char_type != last->type
+ || bracket_type.bracket_id > 0 /* Always separate bracket into single char runs! */
+ || last->bracket_type.bracket_id > 0
+ || FRIBIDI_IS_ISOLATE(char_type)
+ )
{
run = new_run ();
if UNLIKELY
@@ -189,6 +150,7 @@ run_list_encode_bidi_types (
last->len = run->pos - last->pos;
last->next = run;
run->prev = last;
+ run->bracket_type = bracket_type;
last = run;
}
}
@@ -274,6 +236,7 @@ shadow_run_list (
p->next->prev = r;
r->next = p->next;
r->level = p->level;
+ r->isolate_level = p->isolate_level;
r->type = p->type;
r->len = p->pos + p->len - pos2;
r->pos = pos2;
@@ -292,7 +255,7 @@ shadow_run_list (
{
t = p;
p = p->prev;
- free_run (t);
+ fribidi_free (t);
}
}
}
@@ -324,7 +287,7 @@ shadow_run_list (
{
t = s;
s = s->next;
- free_run (t);
+ fribidi_free (t);
}
}
/* before updating the next and prev runs to point to the inserted q,
diff --git a/lib/fribidi-shape.c b/lib/fribidi-shape.c
index 4d13ecc..dd8927d 100644
--- a/lib/fribidi-shape.c
+++ b/lib/fribidi-shape.c
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
diff --git a/lib/fribidi-shape.h b/lib/fribidi-shape.h
index 6071fa2..a292e46 100644
--- a/lib/fribidi-shape.h
+++ b/lib/fribidi-shape.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_SHAPE_H
#define _FRIBIDI_SHAPE_H
diff --git a/lib/fribidi-types.h b/lib/fribidi-types.h
index 89778df..9b66aea 100644
--- a/lib/fribidi-types.h
+++ b/lib/fribidi-types.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_TYPES_H
#define _FRIBIDI_TYPES_H
@@ -118,7 +118,7 @@
#endif /* FRIBIDI_STR_INDEX */
-typedef FRIBIDI_UINT8 fribidi_int8;
+typedef FRIBIDI_INT8 fribidi_int8;
typedef FRIBIDI_INT16 fribidi_int16;
typedef FRIBIDI_INT32 fribidi_int32;
typedef FRIBIDI_UINT8 fribidi_uint8;
@@ -129,6 +129,16 @@ typedef FRIBIDI_BOOLEAN fribidi_boolean;
typedef FRIBIDI_UNICHAR FriBidiChar;
typedef FRIBIDI_STR_INDEX FriBidiStrIndex;
+struct _FriBracketTypeStruct {
+ FriBidiChar bracket_id;
+ fribidi_boolean is_open;
+};
+
+typedef struct _FriBracketTypeStruct FriBidiBracketType;
+
+/* Use FRIBIDI_NO_BRACKET for assigning to a non-bracket */
+#define FRIBIDI_NO_BRACKET { 0, 0 }
+
#ifndef FRIBIDI_MAX_STRING_LENGTH
# define FRIBIDI_MAX_STRING_LENGTH (sizeof (FriBidiStrIndex) == 2 ? \
diff --git a/lib/fribidi-unicode.h b/lib/fribidi-unicode.h
index 9174fd0..b572afd 100644
--- a/lib/fribidi-unicode.h
+++ b/lib/fribidi-unicode.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_UNICODE_H
#define _FRIBIDI_UNICODE_H
@@ -61,10 +61,13 @@ extern const char *fribidi_unicode_version;
#define FRIBIDI_BIDI_NUM_TYPES 19
/* The maximum embedding level value assigned by explicit marks */
-#define FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL 61
-/* The maximum *number* of different resolved embedding levels: 0-62 */
-#define FRIBIDI_BIDI_MAX_RESOLVED_LEVELS 63
+#define FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL 125
+/* The maximum *number* of different resolved embedding levels: 0-126 */
+#define FRIBIDI_BIDI_MAX_RESOLVED_LEVELS 127
+
+/* The maximum *number* of nested brackets: 0-63 */
+#define FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS 63
/* A few Unicode characters: */
@@ -76,6 +79,10 @@ extern const char *fribidi_unicode_version;
#define FRIBIDI_CHAR_PDF 0x202C
#define FRIBIDI_CHAR_LRO 0x202D
#define FRIBIDI_CHAR_RLO 0x202E
+#define FRIBIDI_CHAR_LRI 0x2066
+#define FRIBIDI_CHAR_RLI 0x2067
+#define FRIBIDI_CHAR_FSI 0x2068
+#define FRIBIDI_CHAR_PDI 0x2069
/* Line and Paragraph Separators */
#define FRIBIDI_CHAR_LS 0x2028
diff --git a/lib/fribidi.c b/lib/fribidi.c
index b09b962..0ce3a1f 100644
--- a/lib/fribidi.c
+++ b/lib/fribidi.c
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#include "common.h"
@@ -78,9 +78,6 @@ const char *fribidi_version_info =
#if DEBUG+0
" --enable-debug"
#endif /* DEBUG */
-#if USE_SIMPLE_MALLOC+0
- " --enable-malloc"
-#endif /* USE_SIMPLE_MALLOC */
#if FRIBIDI_CHARSETS+0
#else
" --disable-charsets"
@@ -93,7 +90,7 @@ const char *fribidi_version_info =
".\n\n"
"Copyright (C) 2004 Sharif FarsiWeb, Inc.\n"
"Copyright (C) 2001, 2002, 2004, 2005 Behdad Esfahbod\n"
- "Copyright (C) 1999, 2000 Dov Grobgeld\n"
+ "Copyright (C) 1999, 2000, 2017 Dov Grobgeld\n"
FRIBIDI_NAME " comes with NO WARRANTY, to the extent permitted by law.\n"
"You may redistribute copies of " FRIBIDI_NAME " under\n"
"the terms of the GNU Lesser General Public License.\n"
diff --git a/lib/fribidi.h b/lib/fribidi.h
index ce0058e..1e10a8e 100644
--- a/lib/fribidi.h
+++ b/lib/fribidi.h
@@ -27,7 +27,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _FRIBIDI_H
#define _FRIBIDI_H
@@ -42,6 +42,7 @@
#include "fribidi-joining-types.h"
#include "fribidi-joining.h"
#include "fribidi-mirroring.h"
+#include "fribidi-brackets.h"
#include "fribidi-arabic.h"
#include "fribidi-shape.h"
diff --git a/lib/joining-types.h b/lib/joining-types.h
index 830ae74..139b7bc 100644
--- a/lib/joining-types.h
+++ b/lib/joining-types.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _JOINING_TYPES_H
#define _JOINING_TYPES_H
diff --git a/lib/mem.h b/lib/mem.h
index ae6d3cd..059c0a2 100644
--- a/lib/mem.h
+++ b/lib/mem.h
@@ -28,7 +28,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _MEM_H
#define _MEM_H
diff --git a/lib/run.h b/lib/run.h
index 6028845..5f881ce 100644
--- a/lib/run.h
+++ b/lib/run.h
@@ -30,7 +30,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
- * For licensing issues, contact <license@farsiweb.info>.
+ * For licensing issues, contact <fribidi.license@gmail.com>.
*/
#ifndef _RUN_H
#define _RUN_H
@@ -54,6 +54,11 @@ struct _FriBidiRunStruct
FriBidiStrIndex pos, len;
FriBidiCharType type;
FriBidiLevel level;
+ FriBidiLevel isolate_level;
+ FriBidiBracketType bracket_type;
+
+ /* Additional links for connecting the isolate tree */
+ FriBidiRun *prev_isolate, *next_isolate;
};
@@ -64,11 +69,6 @@ new_run (
)
FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_MALLOC FRIBIDI_GNUC_WARN_UNUSED;
-#define free_run FRIBIDI_PRIVATESPACE(free_run)
- void free_run (
- FriBidiRun *run
-) FRIBIDI_GNUC_HIDDEN;
-
#define new_run_list FRIBIDI_PRIVATESPACE(new_run_list)
FriBidiRun *new_run_list (
void
@@ -83,6 +83,7 @@ new_run (
#define run_list_encode_bidi_types FRIBIDI_PRIVATESPACE(run_list_encode_bidi_types)
FriBidiRun *run_list_encode_bidi_types (
const FriBidiCharType *bidi_types,
+ const FriBidiBracketType *bracket_types,
const FriBidiStrIndex len
)
FRIBIDI_GNUC_HIDDEN FRIBIDI_GNUC_WARN_UNUSED;
diff --git a/test/test_CapRTL_isolate.input b/test/test_CapRTL_isolate.input
new file mode 100644
index 0000000..3845185
--- /dev/null
+++ b/test/test_CapRTL_isolate.input
@@ -0,0 +1,8 @@
+_yBEAR_I:how is LION?
+_ibear_I:how is LION?
+_fBEAR_I:how is LION?
+_fbear_I:how is LION?
+_yBEAR_I:HOW IS lion?
+_ibear_I:HOW IS lion?
+_fBEAR_I:HOW IS lion?
+_fbear_I:HOW IS lion?
diff --git a/test/test_CapRTL_isolate.reference b/test/test_CapRTL_isolate.reference
new file mode 100644
index 0000000..3571aa5
--- /dev/null
+++ b/test/test_CapRTL_isolate.reference
@@ -0,0 +1,8 @@
+_yBEAR_I:how is LION? => ?NOIL how is:RAEB
+_ibear_I:how is LION? => bear:how is NOIL?
+_fBEAR_I:how is LION? => ?NOIL how is:RAEB
+_fbear_I:how is LION? => bear:how is NOIL?
+_yBEAR_I:HOW IS lion? => ?lion SI WOH:RAEB
+_ibear_I:HOW IS lion? => bear:SI WOH lion?
+_fBEAR_I:HOW IS lion? => ?lion SI WOH:RAEB
+_fbear_I:HOW IS lion? => bear:SI WOH lion?