~ubuntu-branches/ubuntu/karmic/iterm/karmic

« back to all changes in this revision

Viewing changes to lib/src/unix/fribidi_layout/concrete_layout.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Fok
  • Date: 2004-02-27 04:13:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040227041316-q0jn37sia8mt0t9u
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This software is subject to the terms of the Common Public License
 
2
   You must accept the terms of this license to use this software.
 
3
 
 
4
   Copyright (C) 2002, International Business Machines Corporation
 
5
   and others.  All Rights Reserved.
 
6
 
 
7
   Further information about Common Public License Version 0.5 is obtained
 
8
   from url http://oss.software.ibm.com/developer/opensource/license-cpl.html */
 
9
 
 
10
#include <fribidi/fribidi.h>
 
11
#include <wchar.h>
 
12
#include <stdlib.h>
 
13
#include <errno.h>
 
14
 
 
15
#include "iterm/vtlayout.h"
 
16
 
 
17
struct ConcreteVTLayout {
 
18
  int is_LTR;
 
19
  int is_nonimal;
 
20
  int is_shaped;
 
21
};
 
22
 
 
23
 
 
24
static int mbstoFriBidichars(FriBidiChar *fribidi_string,
 
25
                             int *fribidi_length,
 
26
                             const char *string)
 
27
{
 
28
      /* We asume that wchar_t is UCS-4, this sould be somehow removed */
 
29
  wchar_t *wstr = (wchar_t *)fribidi_string;
 
30
  size_t ret = 0;
 
31
  mbstate_t ps;
 
32
  int i;
 
33
 
 
34
  memset(&ps,0,sizeof(ps));
 
35
  errno = 0;
 
36
  ret = mbsrtowcs(wstr, &string, *fribidi_length, &ps);
 
37
  
 
38
  if( ret == (size_t)(-1) )
 
39
  {
 
40
    free(wstr);
 
41
    return 1;
 
42
  }
 
43
      /* on IA64 FriBidiChar is 8 bytes */
 
44
  if(4 < sizeof(FriBidiChar))
 
45
  {
 
46
    for(i=ret-1;0<=i;i--)
 
47
    {
 
48
      fribidi_string[i] = wstr[i];
 
49
    }
 
50
  }
 
51
  fribidi_string[ret] = 0;
 
52
  *fribidi_length = ret;
 
53
 
 
54
  return 0;
 
55
}
 
56
 
 
57
static int FriBidiCharstombs(char *out, size_t *out_len,
 
58
                             FriBidiChar *fribidi_string)
 
59
{
 
60
      /* We asume that wchar_t is UCS-4, this sould be somehow removed */
 
61
  wchar_t *wstr = (wchar_t *)fribidi_string;
 
62
  size_t ret;
 
63
  mbstate_t ps;
 
64
  int i;
 
65
 
 
66
      /* on IA64 FriBidiChar is 8 bytes */
 
67
  if(4 < sizeof(FriBidiChar))
 
68
  {
 
69
    for(i=0;fribidi_string[i];i++)
 
70
    {
 
71
      wstr[i] = fribidi_string[i];
 
72
    }
 
73
  }
 
74
 
 
75
  memset(&ps,0,sizeof(ps));
 
76
  errno = 0;
 
77
  ret = wcsrtombs(out,(const wchar_t **)&wstr,*out_len,&ps);
 
78
 
 
79
  if( ret == (size_t)(-1) || errno )
 
80
    return 1;
 
81
 
 
82
  *out_len = ret;
 
83
  return 0;
 
84
}
 
85
 
 
86
static int VTLayout_transform(VTLayout *vtlayout,
 
87
                              char *logical,
 
88
                              size_t logical_length,
 
89
                              char *visual,
 
90
                              size_t *visual_length,
 
91
                              size_t *logical2visual_index,
 
92
                              size_t *visual2logical_index,
 
93
                              size_t *embedding_level)
 
94
{
 
95
  int array_size;
 
96
  FriBidiChar *fribidi_logical = NULL;
 
97
  int fribidi_logical_length;
 
98
  FriBidiChar *fribidi_visual = NULL;
 
99
  int fribidi_visual_length;
 
100
  FriBidiStrIndex *l2v_index = NULL;
 
101
  FriBidiStrIndex *v2l_index = NULL;
 
102
  FriBidiLevel *embedding_level_list = NULL;
 
103
  FriBidiCharType fribidi_type;
 
104
  int i;
 
105
 
 
106
#define FREE_ALL() \
 
107
do { \
 
108
    if(fribidi_logical) \
 
109
      free(fribidi_logical); \
 
110
  if(fribidi_visual) \
 
111
      free(fribidi_visual); \
 
112
  if(l2v_index) \
 
113
      free(l2v_index); \
 
114
  if(v2l_index) \
 
115
      free(v2l_index); \
 
116
  if(embedding_level_list) \
 
117
      free(embedding_level_list); \
 
118
} while(0)
 
119
  
 
120
  array_size = fribidi_logical_length =
 
121
 fribidi_visual_length = logical_length+1;
 
122
  
 
123
  if( (fribidi_logical = (FriBidiChar *)
 
124
       calloc(array_size,sizeof(FriBidiChar))) == NULL)
 
125
      return 1;
 
126
 
 
127
  if( (fribidi_visual = (FriBidiChar *)
 
128
       calloc(array_size,sizeof(FriBidiChar))) == NULL)
 
129
      goto FAIL;
 
130
 
 
131
  if(logical2visual_index)
 
132
  {
 
133
    if( (l2v_index = (FriBidiStrIndex *)
 
134
         calloc(array_size,sizeof(FriBidiStrIndex))) == NULL)
 
135
        goto FAIL;
 
136
  }
 
137
      
 
138
  if(visual2logical_index)
 
139
  {
 
140
    if( (v2l_index = (FriBidiStrIndex *)
 
141
         calloc(array_size,sizeof(FriBidiStrIndex))) == NULL)
 
142
        goto FAIL;
 
143
  }
 
144
 
 
145
  if(embedding_level)
 
146
  {
 
147
    if( (embedding_level_list = (FriBidiLevel *)
 
148
         calloc(array_size,sizeof(FriBidiLevel))) == NULL)
 
149
        goto FAIL;
 
150
  }
 
151
 
 
152
  logical[logical_length] = '\0';
 
153
  if(mbstoFriBidichars(fribidi_logical,
 
154
                       &fribidi_logical_length,
 
155
                       logical))
 
156
    goto FAIL;
 
157
 
 
158
  if(vtlayout->concrete_layout->is_LTR)
 
159
      fribidi_type = FRIBIDI_TYPE_LTR;
 
160
  else
 
161
      fribidi_type = FRIBIDI_TYPE_RTL;
 
162
  fribidi_log2vis(fribidi_logical,
 
163
                  fribidi_logical_length,
 
164
                  &fribidi_type,
 
165
                  fribidi_visual,
 
166
                  l2v_index,
 
167
                  v2l_index,
 
168
                  embedding_level_list);
 
169
 
 
170
  array_size --;
 
171
  if(l2v_index)
 
172
    for(i=0;i<array_size;i++)
 
173
      logical2visual_index[i] = l2v_index[i];
 
174
 
 
175
 
 
176
  if(v2l_index)
 
177
    for(i=0;i<array_size;i++)
 
178
      visual2logical_index[i] = v2l_index[i];
 
179
 
 
180
  if(embedding_level_list)
 
181
    for(i=0;i<array_size;i++)
 
182
      embedding_level[i] = embedding_level_list[i];
 
183
 
 
184
  if(FriBidiCharstombs(visual,visual_length,fribidi_visual))
 
185
      goto FAIL;
 
186
  
 
187
  FREE_ALL();
 
188
  return 0;
 
189
  FAIL:
 
190
  FREE_ALL();
 
191
  return 1;
 
192
}
 
193
 
 
194
static void VTLayout_set_global_direction(VTLayout *vtlayout,
 
195
                                         int direction)
 
196
{
 
197
  switch(direction)
 
198
  {
 
199
    case VT_RTL:
 
200
        vtlayout->concrete_layout->is_LTR = 0;
 
201
        break;
 
202
    case VT_LTR:
 
203
        vtlayout->concrete_layout->is_LTR = 1;
 
204
        break;
 
205
    default:
 
206
        /* do nothing */;
 
207
  }
 
208
}
 
209
 
 
210
static int VTLayout_is_direction_LTR(VTLayout *vtlayout)
 
211
{
 
212
  return vtlayout->concrete_layout->is_LTR;
 
213
}
 
214
 
 
215
 
 
216
VTLayout *VTLayout_new()
 
217
{
 
218
  VTLayout *vtlayout;
 
219
 
 
220
  if((vtlayout = (VTLayout *)malloc(sizeof(VTLayout))) == NULL)
 
221
      return NULL;
 
222
 
 
223
  if((vtlayout->concrete_layout =
 
224
      (struct ConcreteVTLayout *)malloc(sizeof(struct ConcreteVTLayout)))
 
225
     == NULL)
 
226
  {
 
227
    free(vtlayout);
 
228
    return NULL;
 
229
  }
 
230
 
 
231
  vtlayout->concrete_layout->is_LTR = 1;
 
232
  vtlayout->concrete_layout->is_nonimal = 1;
 
233
  vtlayout->concrete_layout->is_shaped = 1;
 
234
  vtlayout->transform = VTLayout_transform;
 
235
  vtlayout->set_global_direction = VTLayout_set_global_direction;
 
236
  vtlayout->is_direction_LTR = VTLayout_is_direction_LTR;
 
237
  vtlayout->set_numerals = NULL;
 
238
  return vtlayout;
 
239
 
 
240
}
 
241
 
 
242
void VTLayout_destroy(VTLayout *vtlayout)
 
243
{
 
244
  if(vtlayout)
 
245
  {
 
246
    if(vtlayout->concrete_layout)
 
247
      free(vtlayout->concrete_layout);
 
248
    free(vtlayout);
 
249
  }
 
250
}