1 /*
2 * Copyright 1992, 1993 by TOSHIBA Corp.
3 *
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of TOSHIBA not be used in advertising
9 * or publicity pertaining to distribution of the software without specific,
10 * written prior permission. TOSHIBA make no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
13 *
14 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 * SOFTWARE.
21 *
22 * Author: Katsuhisa Yano TOSHIBA Corp.
23 * mopi@osa.ilab.toshiba.co.jp
24 */
25 /*
26 * Copyright 1995 by FUJITSU LIMITED
27 * This is source code modified by FUJITSU LIMITED under the Joint
28 * Development Agreement for the CDE/Motif PST.
29 *
30 * Modifier: Takanori Tateno FUJITSU LIMITED
31 *
32 */
33 /*
34 * Modifiers: Jeff Walls, Paul Anderson (HEWLETT-PACKARD)
35 */
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40 #include "Xlibint.h"
41 #include "XlcPublic.h"
42 #include "XomGeneric.h"
43 #include <stdio.h>
44
45 /* for VW/UDC start */
46 static Bool
ismatch_scopes(FontData fontdata,unsigned long * value,Bool is_shift)47 ismatch_scopes(
48 FontData fontdata,
49 unsigned long *value,
50 Bool is_shift)
51 {
52 register int scopes_num = fontdata->scopes_num;
53 FontScope scopes = fontdata->scopes;
54 if (!scopes_num)
55 return False;
56
57 if(fontdata->font == NULL)
58 return False;
59
60 for(;scopes_num--;scopes++)
61 if ((scopes->start <= (*value & 0x7f7f)) &&
62 ((scopes->end) >= (*value & 0x7f7f))){
63 if(is_shift == True) {
64 if(scopes->shift){
65 if(scopes->shift_direction == '+'){
66 *value += scopes->shift ;
67 } else if( scopes->shift_direction == '-'){
68 *value -= scopes->shift ;
69 }
70 }
71 }
72 return True;
73 }
74
75 return False;
76 }
77
78 static int
check_vertical_fonttype(char * name)79 check_vertical_fonttype(
80 char *name)
81 {
82 char *ptr;
83 int type = 0;
84
85 if(name == (char *)NULL || (int) strlen(name) <= 0)
86 return False;
87
88 /* Obtains the pointer of CHARSET_ENCODING_FIELD. */
89 if((ptr = strchr(name, '-')) == (char *) NULL)
90 return False;
91 ptr++;
92
93 /* Obtains the pointer of vertical_map font type. */
94 if((ptr = strchr(ptr, '.')) == (char *) NULL)
95 return False;
96 ptr++;
97
98 switch(*ptr) {
99 case '1':
100 type = 1; break;
101 case '2':
102 type = 2; break;
103 case '3':
104 type = 3; break;
105 }
106 return type;
107 }
108
109 /*
110 */
111 #define VMAP 0
112 #define VROTATE 1
113 #define FONTSCOPE 2
114
115 FontData
_XomGetFontDataFromFontSet(FontSet fs,unsigned char * str,int len,int * len_ret,int is2b,int type)116 _XomGetFontDataFromFontSet(
117 FontSet fs,
118 unsigned char *str,
119 int len,
120 int *len_ret,
121 int is2b,
122 int type) /* VMAP , VROTATE , else */
123 {
124 unsigned long value;
125 int num,i,hit,csize;
126 FontData fontdata;
127 unsigned char *c;
128 int vfont_type;
129
130 c = str;
131 hit = -1;
132 if(type == VMAP){
133 fontdata = fs->vmap;
134 num = fs->vmap_num;
135 } else if(type == VROTATE){
136 fontdata = (FontData)fs->vrotate;
137 num = fs->vrotate_num;
138 } else {
139 if(fs->font_data_count <= 0 || fs->font_data == (FontData)NULL) {
140 fontdata = fs->substitute;
141 num = fs->substitute_num;
142 }else {
143 fontdata = fs->font_data;
144 num = fs->font_data_count;
145 }
146 /* CDExc20229 fix */
147 if(fontdata == NULL || num == 0){
148 return(NULL);
149 }
150 }
151
152
153 if(is2b){
154 csize = 2;
155 } else {
156 csize = 1;
157 }
158
159 for(;len;len--){
160 if(is2b){
161 value = (((unsigned long)*c) << 8)|(unsigned long)*(c + 1);
162 } else {
163 value = (unsigned long)*c;
164 }
165
166 /* ### NOTE: This routine DOES NOT WORK!
167 * ### We can work around the problem in the calling routine,
168 * ### but we really need to understand this better. As it
169 * ### stands, the algorithm ALWAYS returns "fontdata[0]"
170 * ### for non-VW text! This is clearly wrong. In fact,
171 * ### given the new parse_font[name|data]() algorithms,
172 * ### we may not even need this routine to do anything
173 * ### for non-VW text (since font_set->font always contains
174 * ### the best font for this fontset). -- jjw/pma (HP)
175 */
176 for (i=0;i<num;i++) {
177 if(type == VROTATE) {
178 if(fontdata[i].font) {
179 /* If the num_cr equal zero, all character is rotated. */
180 if(fontdata[i].scopes_num == 0) {
181 break;
182 } else {
183 /* The vertical rotate glyph is not have code shift. */
184 if (ismatch_scopes(&(fontdata[i]),&value,False)) {
185 break;
186 }
187 }
188 }
189 } else if(type == VMAP) {
190 if(fontdata[i].font) {
191 vfont_type = check_vertical_fonttype(fontdata[i].name);
192 if(vfont_type == 0 || vfont_type == 1) {
193 break;
194 } else if(vfont_type == 2 || vfont_type == 3) {
195 if(fontdata[i].scopes_num <= 0)
196 break;
197
198 if (ismatch_scopes(&(fontdata[i]),&value,True)) {
199 break;
200 }
201 }
202 }
203 } else { /* FONTSCOPE */
204 if(fontdata[i].font) {
205 if(fontdata[i].scopes_num <= 0)
206 break;
207 if (ismatch_scopes(&(fontdata[i]),&value,True)){
208 break;
209 }
210 }
211 }
212 }
213 if((hit != -1) && (i != hit)){
214 break;
215 }
216 if(i == num){
217 if( type == VROTATE || type == VMAP){
218 /* Change 1996.01.23 start */
219 if(fs->font_data_count <= 0 ||
220 fs->font_data == (FontData)NULL)
221 fontdata = fs->substitute;
222 else
223 fontdata = fs->font_data;
224 /* Change 1996.01.23 end */
225 }
226 hit = 0;
227 c += csize;
228 break;
229 }
230 if( hit == -1 ) hit = i;
231 if(is2b){
232 *c = (unsigned char)(value >> 8);
233 *(c + 1) = (unsigned char)(value);
234 } else {
235 *c = (unsigned char)value;
236 }
237 c += csize;
238 }
239 *len_ret = (c - str);
240 return(&(fontdata[hit]));
241 }
242 /* for VW/UDC end */
243
244 static FontSet
_XomGetFontSetFromCharSet(XOC oc,XlcCharSet charset)245 _XomGetFontSetFromCharSet(
246 XOC oc,
247 XlcCharSet charset)
248 {
249 register FontSet font_set = XOC_GENERIC(oc)->font_set;
250 register int num = XOC_GENERIC(oc)->font_set_num;
251 XlcCharSet *charset_list;
252 int charset_count;
253
254 for ( ; num-- > 0; font_set++) {
255 charset_count = font_set->charset_count;
256 charset_list = font_set->charset_list;
257 for ( ; charset_count-- > 0; charset_list++)
258 if (*charset_list == charset)
259 return font_set;
260 }
261
262 return (FontSet) NULL;
263 }
264
265 static void
shift_to_gl(register char * text,register int length)266 shift_to_gl(
267 register char *text,
268 register int length)
269 {
270 while (length-- > 0)
271 *text++ &= 0x7f;
272 }
273
274 static void
shift_to_gr(register char * text,register int length)275 shift_to_gr(
276 register char *text,
277 register int length)
278 {
279 while (length-- > 0)
280 *text++ |= 0x80;
281 }
282
283 static Bool
load_font(XOC oc,FontSet font_set)284 load_font(
285 XOC oc,
286 FontSet font_set)
287 {
288 font_set->font = XLoadQueryFont(oc->core.om->core.display,
289 oc->core.font_info.font_name_list[font_set->id]);
290 if (font_set->font == NULL)
291 return False;
292
293 oc->core.font_info.font_struct_list[font_set->id] = font_set->font;
294 XFreeFontInfo(NULL, font_set->info, 1);
295 font_set->info = NULL;
296
297 if (font_set->font->min_byte1 || font_set->font->max_byte1)
298 font_set->is_xchar2b = True;
299 else
300 font_set->is_xchar2b = False;
301
302 return True;
303 }
304
305 int
_XomConvert(XOC oc,XlcConv conv,XPointer * from,int * from_left,XPointer * to,int * to_left,XPointer * args,int num_args)306 _XomConvert(
307 XOC oc,
308 XlcConv conv,
309 XPointer *from,
310 int *from_left,
311 XPointer *to,
312 int *to_left,
313 XPointer *args,
314 int num_args)
315 {
316 XPointer cs, lc_args[1];
317 XlcCharSet charset;
318 int length, cs_left, ret;
319 FontSet font_set;
320
321 cs = *to;
322 cs_left = *to_left;
323 lc_args[0] = (XPointer) &charset;
324
325 ret = _XlcConvert(conv, from, from_left, &cs, &cs_left, lc_args, 1);
326 if (ret < 0)
327 return -1;
328
329 font_set = _XomGetFontSetFromCharSet(oc, charset);
330 if (font_set == NULL)
331 return -1;
332
333 if (font_set->font == NULL && load_font(oc, font_set) == False)
334 return -1;
335
336 length = *to_left - cs_left;
337
338 if (font_set->side != charset->side) {
339 if (font_set->side == XlcGL)
340 shift_to_gl(*to, length);
341 else if (font_set->side == XlcGR)
342 shift_to_gr(*to, length);
343 }
344
345 if (font_set->is_xchar2b)
346 length >>= 1;
347 *to = cs;
348 *to_left -= length;
349
350 *((XFontStruct **) args[0]) = font_set->font;
351 *((Bool *) args[1]) = font_set->is_xchar2b;
352 if(num_args >= 3){
353 *((FontSet *) args[2]) = font_set;
354 }
355
356 return ret;
357 }
358
359 XlcConv
_XomInitConverter(XOC oc,XOMTextType type)360 _XomInitConverter(
361 XOC oc,
362 XOMTextType type)
363 {
364 XOCGenericPart *gen = XOC_GENERIC(oc);
365 XlcConv *convp;
366 const char *conv_type;
367 XlcConv conv;
368 XLCd lcd;
369
370 switch (type) {
371 case XOMWideChar:
372 convp = &gen->wcs_to_cs;
373 conv_type = XlcNWideChar;
374 break;
375 case XOMMultiByte:
376 convp = &gen->mbs_to_cs;
377 conv_type = XlcNMultiByte;
378 break;
379 case XOMUtf8String:
380 convp = &gen->utf8_to_cs;
381 conv_type = XlcNUtf8String;
382 break;
383 default:
384 return (XlcConv) NULL;
385 }
386
387 conv = *convp;
388 if (conv) {
389 _XlcResetConverter(conv);
390 return conv;
391 }
392
393 lcd = oc->core.om->core.lcd;
394
395 conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNFontCharSet);
396 if (conv == (XlcConv) NULL) {
397 conv = _XlcOpenConverter(lcd, conv_type, lcd, XlcNCharSet);
398 if (conv == (XlcConv) NULL)
399 return (XlcConv) NULL;
400 }
401
402 *convp = conv;
403 return conv;
404 }
405