2 * fribidi-joining.h - Arabic joining algorithm
4 * $Id: fribidi-joining.c,v 1.6 2006-01-31 03:23:13 behdad Exp $
6 * $Date: 2006-01-31 03:23:13 $
8 * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-joining.c,v $
11 * Behdad Esfahbod, 2004
13 * Copyright (C) 2004 Sharif FarsiWeb, Inc
14 * Copyright (C) 2004 Behdad Esfahbod
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public License
27 * along with this library, in a file named COPYING; if not, write to the
28 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 * Boston, MA 02110-1301, USA
31 * For licensing issues, contact <license@farsiweb.info>.
36 #include <fribidi-joining.h>
39 #include "bidi-types.h"
40 #include "joining-types.h"
43 /*======================================================================
44 * For debugging, define some functions for printing joining types and
46 *----------------------------------------------------------------------*/
51 const FriBidiLevel *embedding_levels,
52 const FriBidiStrIndex len,
53 const FriBidiJoiningType *jtypes
56 register FriBidiStrIndex i;
58 fribidi_assert (jtypes);
60 MSG (" Join. types: ");
61 for (i = 0; i < len; i++)
62 MSG2 ("%c", fribidi_char_from_joining_type (jtypes[i],
64 (embedding_levels[i])));
69 #define FRIBIDI_CONSISTENT_LEVEL(i) \
70 (FRIBIDI_IS_EXPLICIT_OR_BN (bidi_types[(i)]) \
72 : embedding_levels[(i)])
74 #define FRIBIDI_LEVELS_MATCH(i, j) \
75 ((i) == (j) || (i) == FRIBIDI_SENTINEL || (j) == FRIBIDI_SENTINEL)
80 const FriBidiCharType *bidi_types,
81 const FriBidiStrIndex len,
82 const FriBidiLevel *embedding_levels,
83 /* input and output */
84 FriBidiArabicProp *ar_props
90 DBG ("in fribidi_join_arabic");
92 fribidi_assert (bidi_types);
93 fribidi_assert (embedding_levels);
94 fribidi_assert (ar_props);
98 (fribidi_debug_status ())
100 print_joining_types (embedding_levels, len, ar_props);
104 /* The joining algorithm turned out very very dirty :(. That's what happens
105 * when you follow the standard which has never been implemented closely
109 /* 8.2 Arabic - Cursive Joining */
110 DBG ("Arabic cursive joining");
112 /* The following do not need to be initialized as long as joins is
113 * initialized to false. We just do to turn off compiler warnings. */
114 register FriBidiStrIndex saved = 0;
115 register FriBidiLevel saved_level = FRIBIDI_SENTINEL;
116 register fribidi_boolean saved_shapes = false;
117 register FriBidiArabicProp saved_joins_following_mask = 0;
119 register fribidi_boolean joins = false;
120 register FriBidiStrIndex i;
122 for (i = 0; i < len; i++)
123 if (!FRIBIDI_IS_JOINING_TYPE_G (ar_props[i]))
125 register fribidi_boolean disjoin = false;
126 register fribidi_boolean shapes = FRIBIDI_ARAB_SHAPES (ar_props[i]);
127 register FriBidiLevel level = FRIBIDI_CONSISTENT_LEVEL (i);
129 if (joins && !FRIBIDI_LEVELS_MATCH (saved_level, level))
135 if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
137 register const FriBidiArabicProp joins_preceding_mask =
138 FRIBIDI_JOINS_PRECEDING_MASK (level);
143 FRIBIDI_UNSET_BITS (ar_props[i], joins_preceding_mask);
145 else if (!FRIBIDI_TEST_BITS (ar_props[i], joins_preceding_mask))
151 register FriBidiStrIndex j;
152 /* This is a FriBidi extension: we set joining properties
153 * for skipped characters in between, so we can put NSMs on tatweel
154 * later if we want. Useful on console for example.
156 for (j = saved + 1; j < i; j++)
157 FRIBIDI_SET_BITS (ar_props[j], joins_preceding_mask | saved_joins_following_mask);
161 if (disjoin && saved_shapes)
162 FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
164 if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
168 saved_shapes = shapes;
169 saved_joins_following_mask =
170 FRIBIDI_JOINS_FOLLOWING_MASK (level);
172 FRIBIDI_TEST_BITS (ar_props[i], saved_joins_following_mask);
175 if ((joins) && saved_shapes)
176 FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
182 (fribidi_debug_status ())
184 print_joining_types (embedding_levels, len, ar_props);
188 DBG ("leaving fribidi_join_arabic");
191 /* Editor directions:
192 * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent