Merge branch 'upstream' into tizen
[platform/upstream/fribidi.git] / lib / fribidi-deprecated.c
1 /* FriBidi
2  * fribidi-deprecated.c - deprecated interfaces.
3  *
4  * Authors:
5  *   Behdad Esfahbod, 2001, 2002, 2004
6  *   Dov Grobgeld, 1999, 2000
7  *
8  * Copyright (C) 2004 Sharif FarsiWeb, Inc
9  * Copyright (C) 2001,2002 Behdad Esfahbod
10  * Copyright (C) 1999,2000 Dov Grobgeld
11  * 
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * 
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  * 
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this library, in a file named COPYING; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA
26  * 
27  * For licensing issues, contact <fribidi.license@gmail.com>.
28  */
29
30 #include "common.h"
31
32 #undef FRIBIDI_NO_DEPRECATED
33
34 #include <fribidi-deprecated.h>
35 #include <fribidi.h>
36
37 #ifdef FRIBIDI_NO_DEPRECATED
38 #else
39
40 static FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
41
42 FRIBIDI_ENTRY fribidi_boolean
43 fribidi_set_mirroring (
44   /* input */
45   fribidi_boolean state
46 )
47 {
48   return FRIBIDI_ADJUST_AND_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_MIRRORING, state);
49 }
50
51 FRIBIDI_ENTRY fribidi_boolean
52 fribidi_mirroring_status (
53   void
54 )
55 {
56   return FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_SHAPE_MIRRORING);
57 }
58
59 FRIBIDI_ENTRY fribidi_boolean
60 fribidi_set_reorder_nsm (
61   /* input */
62   fribidi_boolean state
63 )
64 {
65   return FRIBIDI_ADJUST_AND_TEST_BITS (flags, FRIBIDI_FLAG_REORDER_NSM, state);
66 }
67
68 fribidi_boolean
69 fribidi_reorder_nsm_status (
70   void
71 )
72 {
73   return FRIBIDI_TEST_BITS (flags, FRIBIDI_FLAG_REORDER_NSM);
74 }
75
76
77
78
79 FRIBIDI_ENTRY FriBidiLevel
80 fribidi_log2vis_get_embedding_levels (
81   const FriBidiCharType *bidi_types,    /* input list of bidi types as returned by
82                                            fribidi_get_bidi_types() */
83   const FriBidiStrIndex len,    /* input string length of the paragraph */
84   FriBidiParType *pbase_dir,    /* requested and resolved paragraph
85                                  * base direction */
86   FriBidiLevel *embedding_levels        /* output list of embedding levels */
87 )
88 {
89   return fribidi_get_par_embedding_levels_ex (bidi_types, NULL, len, pbase_dir, embedding_levels);
90 }
91
92 FRIBIDI_ENTRY FriBidiCharType
93 fribidi_get_type (
94   FriBidiChar ch                /* input character */
95 )
96 {
97   return fribidi_get_bidi_type (ch);
98 }
99
100 FRIBIDI_ENTRY FriBidiCharType
101 fribidi_get_type_internal (
102   FriBidiChar ch                /* input character */
103 )
104 {
105   return fribidi_get_bidi_type (ch);
106 }
107
108
109
110 FRIBIDI_ENTRY FriBidiStrIndex
111 fribidi_remove_bidi_marks (
112   FriBidiChar *str,
113   const FriBidiStrIndex len,
114   FriBidiStrIndex *positions_to_this,
115   FriBidiStrIndex *position_from_this_list,
116   FriBidiLevel *embedding_levels
117 )
118 {
119   register FriBidiStrIndex i, j = 0;
120   fribidi_boolean private_from_this = false;
121   fribidi_boolean status = false;
122
123   if UNLIKELY
124     (len == 0)
125     {
126       status = true;
127       goto out;
128     }
129
130   DBG ("in fribidi_remove_bidi_marks");
131
132   fribidi_assert (str);
133
134   /* If to_this is not NULL, we must have from_this as well. If it is
135      not given by the caller, we have to make a private instance of it. */
136   if (positions_to_this && !position_from_this_list)
137     {
138       position_from_this_list = fribidi_malloc (sizeof
139                                                 (position_from_this_list[0]) *
140                                                 len);
141       if UNLIKELY
142         (!position_from_this_list) goto out;
143       private_from_this = true;
144       for (i = 0; i < len; i++)
145         position_from_this_list[positions_to_this[i]] = i;
146     }
147
148   for (i = 0; i < len; i++)
149     if (!FRIBIDI_IS_EXPLICIT_OR_BN (fribidi_get_bidi_type (str[i]))
150         && !FRIBIDI_IS_ISOLATE (fribidi_get_bidi_type (str[i]))
151         && str[i] != FRIBIDI_CHAR_LRM && str[i] != FRIBIDI_CHAR_RLM)
152       {
153         str[j] = str[i];
154         if (embedding_levels)
155           embedding_levels[j] = embedding_levels[i];
156         if (position_from_this_list)
157           position_from_this_list[j] = position_from_this_list[i];
158         j++;
159       }
160
161   /* Convert the from_this list to to_this */
162   if (positions_to_this)
163     {
164       for (i = 0; i < len; i++)
165         positions_to_this[i] = -1;
166       for (i = 0; i < len; i++)
167         positions_to_this[position_from_this_list[i]] = i;
168     }
169
170   status = true;
171
172 out:
173
174   if (private_from_this)
175     fribidi_free (position_from_this_list);
176
177   return status ? j : -1;
178 }
179
180 /* Local array size, used for stack-based local arrays */
181 #define LOCAL_LIST_SIZE 128
182
183 FRIBIDI_ENTRY FriBidiLevel
184 fribidi_log2vis (
185   /* input */
186   const FriBidiChar *str,
187   FriBidiStrIndex len,
188   /* input and output */
189   FriBidiParType *pbase_dir,
190   /* output */
191   FriBidiChar *visual_str,
192   FriBidiStrIndex *positions_L_to_V,
193   FriBidiStrIndex *positions_V_to_L,
194   FriBidiLevel *embedding_levels
195 )
196 {
197   register FriBidiStrIndex i;
198   FriBidiLevel max_level = 0;
199   fribidi_boolean private_V_to_L = false;
200   fribidi_boolean private_embedding_levels = false;
201   fribidi_boolean status = false;
202   FriBidiArabicProp local_ar_props[LOCAL_LIST_SIZE];
203   FriBidiArabicProp *ar_props = NULL;
204   FriBidiLevel local_embedding_levels[LOCAL_LIST_SIZE];
205   FriBidiCharType local_bidi_types[LOCAL_LIST_SIZE];
206   FriBidiCharType *bidi_types = NULL;
207   FriBidiBracketType local_bracket_types[LOCAL_LIST_SIZE];
208   FriBidiBracketType *bracket_types = NULL;
209   FriBidiStrIndex local_positions_V_to_L[LOCAL_LIST_SIZE];
210
211   if UNLIKELY
212     (len == 0)
213     {
214       status = true;
215       goto out;
216     }
217
218   DBG ("in fribidi_log2vis");
219
220   fribidi_assert (str);
221   fribidi_assert (pbase_dir);
222
223   if (len < LOCAL_LIST_SIZE)
224     bidi_types = local_bidi_types;
225   else
226     bidi_types = fribidi_malloc (len * sizeof bidi_types[0]);
227   if (!bidi_types)
228     goto out;
229
230   fribidi_get_bidi_types (str, len, bidi_types);
231
232   if (len < LOCAL_LIST_SIZE)
233     bracket_types = local_bracket_types;
234   else
235     bracket_types = fribidi_malloc (len * sizeof bracket_types[0]);
236     
237   if (!bracket_types)
238     goto out;
239
240   fribidi_get_bracket_types (str, len, bidi_types,
241                              /* output */
242                              bracket_types);
243   if (!embedding_levels)
244     {
245       if (len < LOCAL_LIST_SIZE)
246         embedding_levels = local_embedding_levels;
247       else
248         embedding_levels = fribidi_malloc (len * sizeof embedding_levels[0]);
249       if (!embedding_levels)
250         goto out;
251       private_embedding_levels = true;
252     }
253
254   max_level = fribidi_get_par_embedding_levels_ex (bidi_types,
255                                                    bracket_types,
256                                                    len,
257                                                    pbase_dir,
258                                                    embedding_levels) - 1;
259   if UNLIKELY
260     (max_level < 0) goto out;
261
262   /* If l2v is to be calculated we must have v2l as well. If it is not
263      given by the caller, we have to make a private instance of it. */
264   if (positions_L_to_V && !positions_V_to_L)
265     {
266       if (len < LOCAL_LIST_SIZE)
267         positions_V_to_L = local_positions_V_to_L;
268       else
269         positions_V_to_L =
270         (FriBidiStrIndex *) fribidi_malloc (sizeof (FriBidiStrIndex) * len);
271       if (!positions_V_to_L)
272         goto out;
273       private_V_to_L = true;
274     }
275
276   /* Set up the ordering array to identity order */
277   if (positions_V_to_L)
278     {
279       for (i = 0; i < len; i++)
280         positions_V_to_L[i] = i;
281     }
282
283
284   if (visual_str)
285     {
286       /* Using memcpy instead
287       for (i = len - 1; i >= 0; i--)
288         visual_str[i] = str[i];
289       */
290       memcpy (visual_str, str, len * sizeof (*visual_str));
291
292       /* Arabic joining */
293       if (len < LOCAL_LIST_SIZE)
294         ar_props = local_ar_props;
295       else
296         ar_props = fribidi_malloc (len * sizeof ar_props[0]);
297       fribidi_get_joining_types (str, len, ar_props);
298       fribidi_join_arabic (bidi_types, len, embedding_levels, ar_props);
299
300       fribidi_shape (flags, embedding_levels, len, ar_props, visual_str);
301     }
302
303   /* line breaking goes here, but we assume one line in this function */
304
305   /* and this should be called once per line, but again, we assume one
306    * line in this deprecated function */
307   status =
308     fribidi_reorder_line (flags, bidi_types, len, 0, *pbase_dir,
309                           embedding_levels, visual_str,
310                           positions_V_to_L);
311
312   /* Convert the v2l list to l2v */
313   if (positions_L_to_V)
314     {
315       for (i = 0; i < len; i++)
316         positions_L_to_V[i] = -1;
317       for (i = 0; i < len; i++)
318         positions_L_to_V[positions_V_to_L[i]] = i;
319     }
320
321 out:
322
323   if (private_V_to_L && positions_V_to_L != local_positions_V_to_L)
324     fribidi_free (positions_V_to_L);
325
326   if (private_embedding_levels && embedding_levels != local_embedding_levels)
327     fribidi_free (embedding_levels);
328
329   if (ar_props && ar_props != local_ar_props)
330     fribidi_free (ar_props);
331
332   if (bidi_types && bidi_types != local_bidi_types)
333     fribidi_free (bidi_types);
334
335   if (bracket_types && bracket_types != local_bracket_types)
336     fribidi_free (bracket_types);
337
338   return status ? max_level + 1 : 0;
339 }
340
341 FRIBIDI_ENTRY FriBidiLevel
342 fribidi_get_par_embedding_levels (
343   /* input */
344   const FriBidiCharType *bidi_types,
345   const FriBidiStrIndex len,
346   /* input and output */
347   FriBidiParType *pbase_dir,
348   /* output */
349   FriBidiLevel *embedding_levels
350 )
351 {
352   return fribidi_get_par_embedding_levels_ex (/* input */
353                                               bidi_types,
354                                               NULL, /* No bracket_types */
355                                               len,
356                                               /* input and output */
357                                               pbase_dir,
358                                               /* output */
359                                               embedding_levels);
360 }
361
362 #endif /* !FRIBIDI_NO_DEPRECATED */
363
364 /* Editor directions:
365  * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent
366  */