2 /* Copyright (C) 2002 Mikhael Goikhman */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * FBidi.c - interface to Bidi, we use fribidi implementation here.
20 * See FBidi.h for some comments on this interface.
29 #include "safemalloc.h"
31 #include <fribidi/fribidi.h>
34 Bool
FBidiIsApplicable(const char *charset
)
36 if (fribidi_parse_charset((char *)charset
) ==
37 FRIBIDI_CHAR_SET_NOT_FOUND
)
45 const char *logical_str
, const char *charset
, int str_len
,
46 Bool
*is_rtl
, int *out_len
, superimpose_char_t
*comb_chars
,
50 FriBidiCharSet fribidi_charset
;
51 FriBidiChar
*logical_unicode_str
;
52 FriBidiChar
*visual_unicode_str
;
53 FriBidiCharType pbase_dir
= FRIBIDI_TYPE_ON
;
54 FriBidiStrIndex
*pos_l_to_v
;
57 if (logical_str
== NULL
|| charset
== NULL
)
63 str_len
= strlen(logical_str
);
70 fribidi_charset
= fribidi_parse_charset((char *)charset
);
71 if (fribidi_charset
== FRIBIDI_CHAR_SET_NOT_FOUND
)
76 /* it is possible that we allocate a bit more here, if utf-8 */
78 (FriBidiChar
*)safemalloc((str_len
+ 1) * sizeof(FriBidiChar
));
80 /* convert to unicode first */
81 str_len
= fribidi_charset_to_unicode(
82 fribidi_charset
, (char *)logical_str
, str_len
,
86 (FriBidiChar
*)safemalloc((str_len
+ 1) * sizeof(FriBidiChar
));
88 /* apply bidi algorithm, convert logical string to visual string */
89 /* also keep track of how characters are reordered here, to reorder
90 combing characters accordingly */
92 (FriBidiStrIndex
*)safemalloc((str_len
+ 1) *
93 sizeof(FriBidiStrIndex
));
95 logical_unicode_str
, str_len
, &pbase_dir
,
96 visual_unicode_str
, pos_l_to_v
, NULL
, NULL
);
98 /* remap mapping from logical to visual to "compensate" for BIDI */
99 if (comb_chars
!= NULL
)
102 comb_chars
[i
].c
.byte1
!= 0 ||
103 comb_chars
[i
].c
.byte2
!= 0;
106 /* if input string is zero characters => only
107 combining chars, set position to zero */
108 comb_chars
[i
].position
=
110 pos_l_to_v
[comb_chars
[i
].position
] : 0;
116 /* values in the previuos mapping gives the position of
117 input characters after combining step */
118 /* mapping from BIDI conversion maps from the positions in
119 the output from combining */
122 for (i
= 0; l_to_v
[i
] != -1; i
++)
126 l_to_v_temp
= (int *)safemalloc(orig_len
* sizeof(int));
127 for (i
= 0; i
< orig_len
; i
++)
129 l_to_v_temp
[i
] = pos_l_to_v
[l_to_v
[i
]];
131 for (i
= 0; i
< orig_len
; i
++)
133 l_to_v
[i
] = l_to_v_temp
[i
];
140 /* character shape/join - will get pulled into fribidi with time */
141 str_len
= shape_n_join(visual_unicode_str
, str_len
);
143 visual_str
= (char *)safemalloc((4 * str_len
+ 1) * sizeof(char));
145 /* convert from unicode finally */
146 *out_len
= fribidi_unicode_to_charset(
147 fribidi_charset
, visual_unicode_str
, str_len
, visual_str
);
149 if (is_rtl
!= NULL
&& pbase_dir
== FRIBIDI_TYPE_RTL
)
154 free(logical_unicode_str
);
155 free(visual_unicode_str
);
159 #endif /* HAVE_BIDI */